为了账号安全,请及时绑定邮箱和手机立即绑定

用gunicorn部署flask报错

用gunicorn部署flask报错

侃侃尔雅 2019-04-27 22:14:42
问题描述学习flask时候做了一个网站用flaskrun可以正常运行想用gunicorn部署一直启动不起来而且网上大部分部署都是用flask1.0以前的版本相关的资料很少想问一下应该如何正确启动相关代码root@iZuf6cbarncpdr9s9j5ktcZ:/WebForTrans#exportFLASK_APP=Yippeeroot@iZuf6cbarncpdr9s9j5ktcZ:/WebForTrans#flaskrun--host=0.0.0.0*ServingFlaskapp"Yippee"*Environment:productionWARNING:Donotusethedevelopmentserverinaproductionenvironment.UseaproductionWSGIserverinstead.*Debugmode:off*Runningonhttp://0.0.0.0:5000/(PressCTRL+Ctoquit)├──instance├──reload├──setup.py├──tests└──Yippee├──db.py├──front.py├──__init__.py├──reload├──schema.sql├──static├──templates└──upload.py__init__.pyfromflaskimportFlaskimportosdefcreate_app(test_config=None):#createandconfiguretheappapp=Flask(__name__,instance_relative_config=True)app.config.from_mapping(SECRET_KEY='dev',DATABASE=os.path.join(app.instance_path,'WebForTrans.sqlite'),)iftest_configisNone:#loadtheinstanceconfig,ifitexists,whennottestingapp.config.from_pyfile('config.py',silent=True)else:#loadthetestconfigifpassedinapp.config.from_mapping(test_config)#ensuretheinstancefolderexiststry:os.makedirs(app.instance_path)exceptOSError:passfromYippeeimportdbdb.init_app(app)fromYippeeimportupload,frontapp.register_blueprint(upload.bp)app.register_blueprint(front.bp)app.add_url_rule('/',endpoint='index')returnapp
查看完整描述

2 回答

?
慕尼黑5688855

TA贡献1848条经验 获得超2个赞

根据gunicorn官网的demo:
$pipinstallgunicorn
$catmyapp.py
defapp(environ,start_response):
data=b"Hello,World!\n"
start_response("200OK",[
("Content-Type","text/plain"),
("Content-Length",str(len(data)))
])
returniter([data])
$gunicorn-w4myapp:app
这个方法app是一个基于WSGI协议实现的一个方法,具体可以看PEP333--PythonWebServerGatewayInterface.
简单说就是输入了命令之后,gunicorn会去找上面定义的app,然后运行app(),这个app的参数必须是environ和start_response,别问为什么,协议就是这么规定的,否则无法运行。
你的代码create_app这个方法并不是协议的一种实现,所以gunicorn无法运行。
为什么要create_app()呢?因为要实例化一个Flask对象。现在再来看看Flask内部做了什么操作,可以看看Flask框架最早版本的代码。
Flask类中有这么两个方法:
def__call__(self,environ,start_response):
"""Shortcutfor:attr:`wsgi_app`"""
returnself.wsgi_app(environ,start_response)
defwsgi_app(self,environ,start_response):
"""TheactualWSGIapplication.Thisisnotimplementedin
`__call__`sothatmiddlewarescanbeapplied:
app.wsgi_app=MyMiddleware(app.wsgi_app)
:paramenviron:aWSGIenvironment
:paramstart_response:acallableacceptingastatuscode,
alistofheadersandanoptional
exceptioncontexttostarttheresponse
"""
withself.request_context(environ):
rv=self.preprocess_request()
ifrvisNone:
rv=self.dispatch_request()
response=self.make_response(rv)
response=self.process_response(response)
returnresponse(environ,start_response)
__call__魔术方法是让一个对象能够变成可调用的,比如:
In[1]:classFoo(object):
...:def__call__(self):
...:return'helloworld'
In[2]:f=Foo()
In[3]:f()
Out[3]:'helloworld'
当你运行gunicorn-w4Yippee:create_app()的时候,gunicorn找到了你的create_app(),这个返回的是一个Flask对象,然后gunicorn再去运行这个对象create_app()()调用的就是__call__方法,这个方法就是一个WSGI协议的实现。
所以就运行起来了。
                            
查看完整回答
反对 回复 2019-04-27
?
炎炎设计

TA贡献1808条经验 获得超4个赞

问题已解决把部署命令改一下gunicorn"Yippee:create_app()"
有没有人能解释一下这里为什么实例名create_app后要加上括号
                            
查看完整回答
反对 回复 2019-04-27
  • 2 回答
  • 0 关注
  • 940 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信