首页 > 代码库 > flask快速入门笔记三_上下文对象:Flask核心机制

flask快速入门笔记三_上下文对象:Flask核心机制

首先声明:内容大部分来自huizhiwang,只是单纯记笔记。

1 请求 :WSGI

WSGI,全称 Web Server Gateway Interface,或者 Python Web Server Gateway Interface ,是为 Python 语言定义的Web服务器Web应用程序之间的一种简单而通用的接口。

技术分享

WSGI将Web服务分成两个部分:服务器和应用程序。WGSI服务器只负责与网络相关的两件事:接收浏览器的 HTTP请求、向浏览器发送HTTP应答;而对HTTP请求的具体处理逻辑,则通过调用WSGI应用程序进行。

实现一个WSGI应用,只需要满足3个要求:

  1. 是可调用的,比如是一个函数,或者是一个可调用类(具有__call__方法)的实例
  2. WSGI应用应当返回一个可迭代(iterable)的值,比如字符串列表
  3. WSGI应用在返回之前,应当调用WSGI服务器传入的start_response函数发送状态码和HTTP报文头

最小WSGI应用

一种最简单的满足WSGI规约的应用程序需要实现一个指定形式的函数:

from wsgiref.simple_server import make_server
 
def wsgi_app(environ,start_response):
    start_response(200 OK,[(Context-Type,text/plain)])
    return such a tiny wsgi app!
 
httpd = make_server(0.0.0.0,80,wsgi_app)    
httpd.serve_forever()   

environ是一个包含全部HTTP请求信息的字典/Dict,由WSGI服务器解包HTTP请求生成。

 

使用类实现WSGI应用

也可以使用类来实现WSGI应用,一个可调用的类的实例可以像函数一样调用,因此, 只要把实例对象传给make_server()就可以了。

这种基于类的实现方法是绝大多数框架的选择,因为这样易于扩展各种各样的处理逻辑。

下面的示例以Python类的形式建立了一个最小化的WSGI应用:

class WSGI_APP:
    def __call__(self,environ,start_response):
        start_response(200 OK,[(Context-Type,text/plain)])
        return such a tiny wsgi app!
 
app = WSGI_APP()  

由于WSGI的存在,不同的Web服务器和不同的Web应用之间可以随意搭配,只要它们都遵循WSGI规范。

Flask框架用于开发上图中的App部分,在开发环境我们可以简单的使用Flask内置的开发用Web服务器, 而在生产环境中使用性能更好的专业Web服务器,比如Apache、Gunicorn等。

 

2 Flask处理流程

Flask类就是Flask框架中WSGI应用规范的实现。每当WSGI服务器收到一个HTTP请求, 都将调用Flask类的实例对象进行处理,其逻辑如下:

技术分享

  1. 创建上下文对象,这包括表征当前HTTP请求信息的RequestContext对象和 表征当前应用的AppContext对象。

    RequestContext对象内主要包含两个和请求信息相关的对象:Request对象 基本是基于WSGI服务器传入的环境变量environ的封装,它表征了来自客户端的全部信息; Session对象则是根据请求中的cookie,重新载入该访问者相关的会话信息。

    AppContext对象主要提供给用户提供一次请求周期内有效的存储空间。比如:g

  2. 入栈。将两个上下文对象分别推入两个全局堆栈:_request_ctx_stack_app_ctx_stack

  3. 请求分发。调用dispatch_request()函数处理_request_ctx_stack栈顶的对象,即 我们刚刚推入的RequestContext对象。dispatch_request()所做的主要工作就是 根据HTTP请求的URL信息,通过路由表找到并调用视图函数进行处理。

    值得注意的是,dispatch_request()并不直接被传入前序环节生成的Request对象, 而是需要使用_request_ctx_stack栈顶的ReqestContext的Request对象。这意味着 dispatch_request()内所有与请求相关的处理(包括我们定义的视图函数), 都必须依赖于_request_ctx_stack所提供的数据情境 —— 所以称之为上下文/Context

    我们使用的全局对象request事实上就指向这个栈顶对象,因此,在一个请求应答的 声明周期之外试图访问request是无效的。

    dispatch_request()返回的是一个Response对象。

  4. 栈。将两个上下文对象出栈

  5. 响应WSGI。调用Response对象,向WSGI服务器返回其结果作为HTTP正文。Response对象是一个 可调用对象,当调用发生时,将首先执行WSGI服务器传入的start_response()函数 发送状态码和HTTP报文头。

flask快速入门笔记三_上下文对象:Flask核心机制