如何在GAE(Google App Engine)中使用Python main()函数?

我想在我的GAE代码中使用main()函数(注意:下面的代码只是一个更大程序的最小演示,因此需要main()).

如果我使用以下代码,它将按预期执行:

import webapp2

class GetHandler(webapp2.RequestHandler):
    def get(self):
        self.response.headers['Content-Type'] = 'text/plain'
        self.response.write('in GET')

class SetHandler(webapp2.RequestHandler):
    def get(self):
        self.response.headers['Content-Type'] = 'text/plain'
        self.response.write('in SET')

app = webapp2.WSGIApplication([
    ('/get',    GetHandler),
    ('/set',    SetHandler),
], debug=True)

我的app.yaml在哪里:

runtime: python27
api_version: 1
threadsafe: true

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

但是,我无法弄清楚如何实现main()函数,并且仍然具有顶部代码中的应用程序行为.即,以下内容:

# with main()
import webapp2

class GetHandler(webapp2.RequestHandler):
    def get(self):
        self.response.headers['Content-Type'] = 'text/plain'
        self.response.write('in GET')

class SetHandler(webapp2.RequestHandler):
    def get(self):
        self.response.headers['Content-Type'] = 'text/plain'
        self.response.write('in SET')

def main():
    app = webapp2.WSGIApplication([
        ('/get',    GetHandler),
        ('/set',    SetHandler),
    ], debug=True)

if __name__ == '__main__':
    main()

对于http:// localhost:8080 / get给出以下错误:

$dev_appserver.py .
INFO     2016-10-17 11:29:30,962 devappserver2.py:769] Skipping SDK update check.
INFO     2016-10-17 11:29:31,059 api_server.py:205] Starting API server at: http://localhost:45865
INFO     2016-10-17 11:29:31,069 dispatcher.py:197] Starting module "default" running at: http://localhost:8080
INFO     2016-10-17 11:29:31,073 admin_server.py:116] Starting admin server at: http://localhost:8000
ERROR    2016-10-17 11:29:37,461 wsgi.py:263] 
Traceback (most recent call last):
  File "/home/.../sdk/platform/google_appengine/google/appengine/runtime/wsgi.py", line 240, in Handle
    handler = _config_handle.add_wsgi_middleware(self._LoadHandler())
  File "/home/.../sdk/platform/google_appengine/google/appengine/runtime/wsgi.py", line 302, in _LoadHandler
    raise err
ImportError: <module 'main' from '/home/.../main.pyc'> has no attribute app
INFO     2016-10-17 11:29:37,496 module.py:788] default: "GET /get HTTP/1.1" 500 -

编辑1

试:

# with main()
import webapp2

app = webapp2.RequestHandler()

class GetHandler(webapp2.RequestHandler):
    def get(self):
        self.response.headers['Content-Type'] = 'text/plain'
        self.response.write('in GET')

class SetHandler(webapp2.RequestHandler):
    def get(self):
        self.response.headers['Content-Type'] = 'text/plain'
        self.response.write('in SET')

def main():
    global app
    app = webapp2.WSGIApplication([
        ('/get',    GetHandler),
        ('/set',    SetHandler),
    ], debug=True)
    return app

if __name__ == '__main__':
    app = main()

结果是:

INFO     2016-10-17 12:30:34,751 module.py:402] [default] Detected file changes:
  /home/openstack/googleAppEngine/fastsimon/task2/task2_with_main/main.py
ERROR    2016-10-17 12:30:42,328 wsgi.py:279] 
Traceback (most recent call last):
  File "/home/openstack/googleAppEngine/google-cloud-sdk/platform/google_appengine/google/appengine/runtime/wsgi.py", line 267, in Handle
    result = handler(dict(self._environ), self._StartResponse)
TypeError: 'RequestHandler' object is not callable
INFO     2016-10-17 12:30:42,335 module.py:788] default: "GET /get HTTP/1.1" 500 -

解决方法:

GAE应用程序并非设计为独立的应用程序,main()函数对它们没有多大意义.

基本上,GAE应用程序实际上只是处理程序代码和规则/配置的集合,旨在扩展和自定义通用GAE红外线/沙盒代码的行为,以便其表现您的应用程序.您可以从回溯中看到-其他代码正在调用您的处理程序代码(到达代码之前的堆栈可能要深得多).

在您的特定情况下,app变量必须在main.py中是全局变量,以匹配脚本:app.yaml配置文件中的main.app config行.这就是追溯的目的.

至于组织大型应用程序的代码,还有其他方法可以实现:

>将应用分成多个modules/services,每个都有自己的app.yaml配置文件.例如:Can a default service/module in a Google App Engine app be a sibling of a non-default one in terms of folder structure?
>将服务/模块分成多个“脚本”-类似于main.py文件的app.yaml文件中的主要入口点,每个入口点都有自己的app config`-实际上,它们只是路由和处理程序之间的映射器.例如:App Engine throws 404 Not Found for any path but root
>使用webapp2的延迟加载处理程序技术将一个应用程序映射程序的处理程序拆分为多个文件.例子:

> App Engine: Few big scripts or many small ones?
> What determines start up time of dynamic instance and can it vary between weeks if code is same

在极端情况下,main.py文件可能只包含app变量-这实际上是唯一的要求.

上一篇:PYthon / Django的WSGI怪异:提供交替的旧版本和新版本的应用程序


下一篇:Django + Uwsgi + Nginx 的概念