浅谈flask基本工作流程

上传人:第*** 文档编号:31782720 上传时间:2018-02-09 格式:DOC 页数:8 大小:64KB
返回 下载 相关 举报
浅谈flask基本工作流程_第1页
第1页 / 共8页
浅谈flask基本工作流程_第2页
第2页 / 共8页
浅谈flask基本工作流程_第3页
第3页 / 共8页
浅谈flask基本工作流程_第4页
第4页 / 共8页
浅谈flask基本工作流程_第5页
第5页 / 共8页
点击查看更多>>
资源描述

《浅谈flask基本工作流程》由会员分享,可在线阅读,更多相关《浅谈flask基本工作流程(8页珍藏版)》请在金锄头文库上搜索。

1、浅谈 Flask 基本工作流程前置技能 - WSGI在具体读源码之前,这里先需要说一个概念,什么是 WSGI。WSGI,全称 Web Server Gateway Interface,或者 Python Web Server Gateway Interface ,是为 Python 语言定义的 Web 服务器和 Web 应用程序或框架之间的一种简单而通用的接口。自从 WSGI 被开发出来以后,许多其它语言中也出现了类似接口。WSGI 的官方定义是,the Python Web Server Gateway Interface。从名字就可以看出来,这东西是一个 Gateway,也就是网关。网关的

2、作用就是在协议之间进行转换。WSGI 是作为 Web 服务器与 Web 应用程序或应用框架之间的一种低级别的接口,以提升可移植 Web 应用开发的共同点。WSGI 是基于现存的 CGI 标准而设计的。很多框架都自带了 WSGI server ,比如 Flask,webpy,Django、CherryPy 等等。当然性能都不好,自带的 web server 更多的是测试用途,发布时则使用生产环境的 WSGI server 或者是联合 nginx 做 uwsgi 。在网上搜过 WSGI 的人应该会看到一个图,左边是 Server,右边是 APP,中间有一个连接纽带是 WSGI。不过,我看了源码以后

3、的理解和这个有些不同,我个人觉得,实际上不应该单独写一个 APP,因为,这个 WSGI 的使用方法实际上也是包含在 APP 里面的,最右端的 app 实际上应该指的是逻辑功能,包括 URL 和 view function 的对应关系。所以我个人的理解如下自己画的图WSGI 其实是作为一个接口,来接受 Server 传递过来的信息, 然后通过这个接口调用后台 app 里的 view function 进行响应。WSGI 具体的功能上面讲到了 WSGI 可以起到一个接口的功能,前面对接服务器,后面对接 app 的具体功能我们先来看看最简单的一个 wsgi_app 的实现python view pl

4、ain copy 在 CODE 上查看代码片派生到我的代码片def application(environ, start_response): #一个符合 wsgi 协议的应用程序写法应该接受 2 个参数 start_response(200 OK, (Content-Type, text/html) #environ 为 http 的相关信息,如请求头等 start_response 则是响应信息 return bHello, web! #return 出来是响应内容 但是,作为 app 本身,你就算启动了程序,你也没办法给 application 传递参数?所以,实际上,调用 applic

5、ation 和传递 2 个参数的动作,是服务器来进行的,比如 Gunicorn.而这个叫做 application 的东西,在 Flask 框架内部的名字,叫做 wsgi_app,请看下面章节的源码。Flask 和 WSGI生成 Flask 实例我们再来看下生成 flask 应用的操作写法,用过的人肯定都非常熟悉。python view plain copy 在 CODE 上查看代码片派生到我的代码片from flask import Flask app = Flask(_name_) #生成 app 实例 app.route(/) def index(): return Hello Worl

6、d 这样,一个 flask app 就生成了但是这里有一个概念必须要搞清楚,就是当你的 gunicorn 收到 http 请求,去调用 app 的时候,他实际上是用了 Flask 的 _call_方法,这点非常重要!因为_call_方法怎么写,决定了你整个流程从哪里开始。那我们来看下 Flask 类的_call_方法的源码python view plain copy 在 CODE 上查看代码片派生到我的代码片class Flask(_PackageBoundObject): #Flask 类 #中间省略一些代码 def _call_(self, environ, start_response)

7、: #Flask 实例的_call_方法 Shortcut for :attr:wsgi_app. return self.wsgi_app(environ, start_response) #注意他的 return,他返回的时候,实际上是调用了 wsgi_app 这个功能 如此一来,我们便知道,当 http 请求从 server 发送过来的时候,他会启动_call_功能,最终实际是调用了 wsgi_app 功能并传入 environ 和 start_responseFlask 的 wsgi_app 定义python view plain copy 在 CODE 上查看代码片派生到我的代码片c

8、lass Flask(_PackageBoundObject): #中间省略一些代码 #请注意函数的说明,说得非常准确,这个 wsgi_app 是一个真正的 WSGI 应用 def wsgi_app(self, environ, start_response): #他扮演的是一个中间角色 The actual WSGI application. This is not implemented in _call_ so that middlewares can be applied without losing a reference to the class. So instead of do

9、ing this: app = MyMiddleware(app) Its a better idea to do this instead: app.wsgi_app = MyMiddleware(app.wsgi_app) Then you still have the original application object around and can continue to call methods on it. :param environ: a WSGI environment :param start_response: a callable accepting a status

10、 code, a list of headers and an optional exception context to start the response ctx = self.request_context(environ) ctx.push() error = None try: try: response = self.full_dispatch_request() #full_dispatch_request 起到了预处理和错误处理以及分发请求的作用 except Exception as e: error = e response = self.make_response(se

11、lf.handle_exception(e) #如果有错误发生,则生成错误响应 return response(environ, start_response) #如果没有错误发生,则正常响应请求,返回响应内容 finally: if self.should_ignore_error(error): error = None ctx.auto_pop(error) Ok, 这个 wsgi_app 的函数定义,基本上包含了整个流程的功能WSGI_APP 的内部流程第一步:生成 request 请求对象和请求上下文环境首先,你会看到 ctx = self.request_context(envir

12、on)的语句,这个涉及到 Flask 使用了请求上下文和应用上下文的概念,结构为栈结构,这部分比较难,后面第二篇会单独写。这里只需要理解为,上面语句产生的所用是生成了一个 request 请求对象以及包含请求信息在内的 request context第二部:请求进入预处理,错误处理及请求转发到响应的过程进入 wsgi_app 的函数内部,生成了 request 对象和上下文环境之后,进入到 trypython view plain copy 在 CODE 上查看代码片派生到我的代码片response = self.full_dispatch_request() 我们看到,响应被赋值成了 ful

13、l_dispatch_request()方法的返回内容,所以我们来看一下 full_dispatch_request 方法python view plain copy 在 CODE 上查看代码片派生到我的代码片class Flask(_PackageBoundObject): #此处省略一些代码 def full_dispatch_request(self): Dispatches the request and on top of that performs request pre and postprocessing as well as HTTP exception catching a

14、nd error handling. . versionadded: 0.7 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

15、 = 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 的话就代表了程序开始处理请求了.来看看 try_trigger_before_first_request_function()的代码,他的目的是,最后将_got_first_request 属性置为 True.python view plain copy 在 CODE 上查看代码片派生到我的代码片class Flask(_PackageBoundObject): #省略一些代码 def try_trigger_before_first_request_functions(self): Called before ea

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 行业资料 > 工业设计

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号