使用Python App Engine设置多个处理程序

时间:2015-07-09 13:43:01

标签: python google-app-engine

我似乎无法让多个处理程序工作。我正在使用Google App Engine和Python。基本URL按预期返回" Hello world!"但是当我尝试访问" / girl"时,我一直收到404错误。

据我所知,我完全按照文档中的规定行事:

https://cloud.google.com/appengine/docs/python/config/appconfig

在这个类似的问题中:

YAML file url and script in GAE python

然后尝试在这些模型上我能想到的所有变体都无法解决我的404问题。我是初学者,并且不太了解app.yaml文件的工作原理,因此我非常确定我没有正确指定处理程序。但我不知道如何解决它。

的app.yaml

application: multiapp
version: 1
runtime: python27
api_version: 1
threadsafe: yes

handlers:

- url: ./girl/.*
  script: girl.app

- url: .*
  script: main.app

libraries:
- name: webapp2
  version: "2.5.2"

main.py

import webapp2

class MainHandler(webapp2.RequestHandler):
    def get(self):
        self.response.write('Hello world!')

app = webapp2.WSGIApplication([
    ('/', MainHandler)
], debug=True)

girl.py

import webapp2

class MainHandler(webapp2.RequestHandler):
        def get(self):
            self.response.write('Hey girl!')

app = webapp2.WSGIApplication([
    ('/',MainHandler),
    ('/girl/', MainHandler)
], debug=True)

已添加:项目的不同组织绝对可以避免解决此问题,但我也想知道为什么设置这些多个处理程序并不适合开始。

4 个答案:

答案 0 :(得分:2)

我知道这是一个老线程,你得到了答案,但我想更好地解释发生的事情,因为我刚刚找到了你的基本问题的答案: 如何将处理程序拆分为不同的文件?

关键问题是,当您声明 WSGIApplication

时,您正在使用正则表达式
app = webapp2.WSGIApplication([
    ('/', MainHandler),
    ('/girl/', GirlHandler)
], debug=True)

并在 yaml 文件中

handlers:

- url: ./girl/.*
  script: girl.app

- url: .*
  script: main.app

您的yaml url: regex中的路径必须是您的webapp域的完整路径。因此,如果您的域名为localhost:8080,那么在您的yaml文件中,您应该从 localhost:8080 开始添加网址。如果您输入url: /girl/.* 您要求浏览器匹配域+正则表达式localhost:8080/girl/.*

这意味着:

  1. 完全匹配此部分:localhost:8080 / girl /
  2. 匹配第一部分后面的任何字符(因为' s"。*" 在正则表达式中表示
  3. 以下是yaml声明:

    handlers:
    
    - url: /girl/.*
      script: girl.app
    

    表示对于 domain / girl / 任何内容(或任何内容)形式的任何网址,都使用 app变量< / strong>在 girl.py 文件app = webapp2.WSGIApplication(...)

    第一个含义是,为girl.py永远不会处理的url编写处理程序没有任何意义,例如编码时:

    girl.py

    import webapp2
    
    class MainHandler(webapp2.RequestHandler):
            def get(self):
                self.response.write('Hey girl!')
    
    app = webapp2.WSGIApplication([
        ('/',MainHandler),
    ], debug=True)
    

    你永远不会使用这个主处理程序,因为它只会激活&#39;当你浏览域/ 时,你在你的yaml文件中说你只想要girl.py来处理域/ girl / something 形式的网址。这是一个矛盾

    这意味着,为了使您的设置正常工作,在girl.py中,您应该只为与您的yaml中的正则表达式匹配的网址编写处理程序。在这种情况下,/girl/.*也接受的任何正则表达式。

    作为旁注,如果你想让你的girlHandler在域/女孩域/ girl / 上工作,你应该在你的yaml文件中使用这个正则表达式:

    handlers:
    
    - url: ./girl(?:/.*)?
      script: girl.app
    
    - url: .*
      script: main.app
    

    因为这会使/.*部分成为可选

    希望这可以帮助任何人达成这个问题,作为一个洞察webapp2如何调用每个处理程序取决于给定的URL

答案 1 :(得分:1)

您应该将所有路由捆绑在一个文件中,并为不同的路由使用不同的处理程序。

main.py

import webapp2

class MainHandler(webapp2.RequestHandler):
    def get(self):
        self.response.write('Hello world!')

class GirlHandler(webapp2.RequestHandler):
    def get(self):
        self.response.write('Hey Girl!')

app = webapp2.WSGIApplication([
    ('/', MainHandler),
    ('/girl/', GirlHandler)
], debug=True)

然后在您的app.yaml中,您只需要链接到main.app

application: multiapp
version: 1
runtime: python27
api_version: 1
threadsafe: yes

handlers:
- url: .*
  script: main.app

libraries:
- name: webapp2
  version: "2.5.2"

您不需要多个webapp2.WSGIApplication个实例。

答案 2 :(得分:1)

可以拥有中央路由,同时将处理程序保存在单独的文件中,并在main.py中包含这些内容:

app = webapp2.WSGIApplication([
    ('/girl/.*', "girl.MainHandler")
    ('/.*', MainHandler),
], debug=True)

运行很大程度上独立的应用程序的另一种可能性&#34;虽然仍然能够在它们之间共享一些信息(如身份验证),但要使它们成为modules of the main app。虽然从长远来看提供了更大的灵活性,但它们确实具有不可忽视的学习曲线(并且文档并不总是为它们提供更新)

答案 3 :(得分:0)

除了组织问题,之所以不起作用的原因是我没有包含尾随斜杠。

“/ girl”(没有斜线)返回404; “/ girl /”(使用斜杠)呈现页面。

app.yaml中的行也应该是:

handlers:
- url: /girl/.*
  script: girl.app