资讯专栏INFORMATION COLUMN

Flask基本工作流程

IT那活儿 / 1470人阅读
Flask基本工作流程

点击上方“IT那活儿”,关注后了解更多精彩内容!!

什么是WSGI

这里先需要说一个概念,什么是WSGI。
WSGI 的官方定义是,the Python Web Server Gateway Interface。从名字就可以看出来,这东西是一个Gateway,也就是网关。网关的作用就是在协议之间进行转换。
WSGI 是作为 Web 服务器与 Web 应用程序或应用框架之间的一种低级别的接口,以提升可移植 Web 应用开发的共同点。WSGI 是基于现存的 CGI 标准而设计的。
很多框架都自带了 WSGI server ,比如 Flask,webpy,Django、CherryPy等等。当然性能都不好,自带的 web server 更多的是测试用途,发布时则使用生产环境的 WSGI server或者是联合 nginx 做 uwsgi 。

 WSGI具体的功能

上面讲到了WSGI可以起到一个接口的功能,前面对接服务器,后面对接app的具体功能。
我们先来看看最简单的一个wsgi_app的实现:
def application(environ, start_response):
#一个符合wsgi协议的应用程序应该接受2个参数  :
start_response(200 OK, [(Content-Type, text/html)])
#environ为http的相关信息;
 return [b

Hello, world!

]
#return出来是响应内容。
但是,作为app本身,你就算启动了程序,你也没办法给application传递参数。
所以,实际上,调用application和传递2个参数的动作,是服务器来进行的,比如Gunicorn。
而这个叫做application的东西,在Flask框架内部的名字,叫做wsgi_app。

Flask和WSGI

我们再来看下生成flask应用的操作写法:
from flask import Flask 
app = Flask(__name__) #生成app实例

@app.route(/index)

def index():  
return Hello World
这样,一个flask app就生成了。
当你的gunicorn收到http请求,去调用app的时候,他实际上是用了Flask 的 __call__方法。因此__call__方法怎么写,决定了你整个流程从哪里开始。
那我们来看下Flask类的__call__方法的源码:
class Flask(_PackageBoundObject): #Flask类 

   ...

 def __call__(self, environ, start_response): #Flask实例的__call__方法

return self.wsgi_app(environ, start_response) #
注意他的return,他返回的时候,实际上是调用了wsgi_app这个函数。
我们便知道,当http请求从server发送过来的时候,他会启动__call__功能,最终实际是调用了wsgi_app功能并传入environ和start_response。

WSGI_APP的内部流程

第一步:生成request请求对象和请求上下文环境:
首先,你会看到ctx = self.request_context(environ)的语句,这个涉及到Flask使用了请求上下文和应用上下文的概念,结构为栈结构。
第二步:请求进入预处理,错误处理及请求转发到响应的过程:
进入wsgi_app的函数内部,生成了request对象和上下文环境之后,进入到try...except。
response = self.full_dispatch_request()
我们看到,响应被赋值成了full_dispatch_request()方法的返回内容,所以我们来看一下full_dispatch_request方法。
class Flask(_PackageBoundObject): 

 def full_dispatch_request(self):
   self.try_trigger_before_first_request_functions() #进行发生真实请求前的处理

   try:  

     request_started.send(self) #socket部分的操作

     rv = self.preprocess_request() #进行请求的预处理

     if rv is None:  

       rv = self.dispatch_request()

   except Exception as e:  

     rv = self.handle_user_exception(e)

   response = self.make_response(rv)

   response = self.process_response(response)

   request_finished.send(self, response=response)

   return response
他首先会触发 try_trigger_before_first_request_function()方法, 在方法内部 会触发 _got_first_request 属性,这个属性的返回值是True或者False,True的话就代表了程序开始处理请求了。
第三步:返回到wsgi_app内部
流程走回到了wsgi_app的内部。
下面这段是wsgi_app内部的代码:
try: 

 try:

   response = self.full_dispatch_request()

 except Exception as e:

   error = e

   response = self.make_response(self.handle_exception(e))

 return response(environ, start_response)

finally:

 if self.should_ignore_error(error):

   error = None

 ctx.auto_pop(error)
当response从刚刚的full_dispatch_request功能返回之后,函数会对这个response加上environ, start_response的参数并返回给Gunicorn。
至此,一个HTTP从请求到响应的流程就完毕了。

本 文 原 创 来 源:IT那活儿微信公众号(上海新炬王翦团队)


文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/129703.html

相关文章

  • Flask Web Development —— 基本应用程序结构(下)

    摘要:有两类应用级和请求级。一个响应中非常重要的部分是状态码,默认设置来指示请求已经成功处理。重定向通常由响应状态码注明并且重定向的由头部的给出。因为这些变化,应用程序获得一组基本的命令行选项。运行显示可用信息在应用程序上下文的内部运行一个。 5、请求-响应循环 现在你已经玩过一个基本的Flask应用程序,你也许想要知道更多关于Flask如何施展魔力。下面章节描述了一些框架设计方面的特点。...

    caohaoyu 评论0 收藏0
  • flask源码走读

    摘要:另外,如果你对模板渲染部分的内容感兴趣,也可以考虑阅读文档文档文档源码阅读,可以参考下面的函数打断点,再测试一个请求,理清过程。 Flask-Origin 源码版本 一直想好好理一下flask的实现,这个项目有Flask 0.1版本源码并加了注解,挺清晰明了的,我在其基础上完成了对Werkzeug的理解部分,大家如果想深入学习的话,可以参考werkzeug_flow.md. 阅读前 为...

    Coly 评论0 收藏0
  • python大佬养成计划----Flask蓝图

    摘要:使用蓝图的概念来制作应用程序组件和支持应用程序内部或跨应用程序的通用模式。蓝图可以大大简化大型应用程序的工作方式,并为扩展提供了在应用程序上注册操作的中心手段。相反,它是如何构造或扩展应用程序的蓝图。 蓝图 之前我们已经通过代码了解了一些Flask基本的用法,现在出现一个问题,我们要做的功能越来越多,路由是不是都要放在run文件中呢?例如我们在不同的文件都定义了一些路由,如果想要访问他...

    tianyu 评论0 收藏0
  • 使用Visual Studio Code编写调试Python Flask程序

    摘要:最近由于工作关系,开始写程序,同事有用的,有用的。第一种适合及以上版本,因为在版本起,出现了文件,配置可以写成用文件启动程序,实测可以触发断点。 最近由于工作关系,开始写flask web程序,同事有用Vim的,有用PyCharm的。在调研了一通python的编辑器,IDE之后,发现Visual Studio Code相对比较适合我。 VSC有相对较全的功能,比较好看舒服的主题,良好的...

    gotham 评论0 收藏0

发表评论

0条评论

IT那活儿

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<