Flask 框架理解(一)

web 服务器 , web 框架 以及 WSGI

这里说的 web 服务器特指纯粹的 python HTTP 服务器(比如 Gunicorn,而不是 Apache,Nginx这些)

一般来说, web 服务器负责建立并管理监听套接字,并且解析所有收到的 HTTP 请求。Web 框架负责 URL 分发,根据 HTTP 中请求路径生成响应。 而 WSGI(pep 333) 则是 web 服务器调用 web 框架的一个调用惯例。用来解偶 web 服务器和 web 框架。

通过 flask 的源码能比较清晰的看到这三者关系

    def wsgi_app(self, environ, start_response):
ctx = self.request_context(environ)
error = None
try:
try:
ctx.push()
response = self.full_dispatch_request()
except Exception as e:
error = e
response = self.handle_exception(e)
except:
error = sys.exc_info()[1]
raise
return response(environ, start_response)
finally:
if self.should_ignore_error(error):
error = None
ctx.auto_pop(error) def __call__(self, environ, start_response):
"""The WSGI server calls the Flask application object as the
WSGI application. This calls :meth:`wsgi_app` which can be
wrapped to applying middleware."""
return self.wsgi_app(environ, start_response)

从这里可以看出, flask 的 application 是一个 WSGI 可调用对象。如果去看 Flask Appication 的 run 方法, 就能发现最终是启动一个 Werkzeug serving.py 中的一个 基于BaseHTTPServer.HTTPServer 实现的 WSGIServer,也就是 web 服务器。证实 web 服务器通过 WSGI 接口调用 web 框架作出响应。这里也能很清楚的看到 web 框架的基础功能就是分发请求,作出响应。

理解全局变量

在 flask 中有 4 个方便好用的全局变量 current_app, request, session, g。严格意义上来说是线程级别的全局变量(具体可看 Werkzeug 的 LocalStack 源码),也就是只有当前线程能访问。正因为用的多, 更应该花点时间去理解这几个变量的含义以及生命周期。

# context locals
_request_ctx_stack = LocalStack()
_app_ctx_stack = LocalStack()
current_app = LocalProxy(_find_app)
request = LocalProxy(partial(_lookup_req_object, 'request'))
session = LocalProxy(partial(_lookup_req_object, 'session'))
g = LocalProxy(partial(_lookup_app_object, 'g'))

对于请求-响应模式, 响应需要根据具体的请求来做出合理的响应。 这四个全局变量就是用来提供请求的具体信息,即请求上下文。从上面 wsgi_app 函数中也可以看出,有请求过来, 调用 wsig_app 时, 会构建一个当前请求的上下文实例(RequestContext),将 http 请求原始信息存到 request 属性, 并将其 push 到当前线程的全局栈 _request_ctx_stack。接着将当前 flask 实例 push 到 _app_ctx_stack, 存储到上下文实例的 app 属性中。最后解析请求中的 cookie, 构建 Session 实例存到上下文实例的 session 属性中。 这样每个请求的上下文中就携带了, http 请求的原始信息, 当前 flask 实例上下文信息, 以及 cookie 提取的 session 信息。 一个请求所需要的信息基本就全部包含了。至于 g 只是当前 flask 实例上下文对象的一个属性。在响应构造完成后, 会把当前上下文 session 信息存到 cookie,所以裸 flask 框架的 session 全部信息是存在客户端的 cookie 里面。接着弹出当前请求的上下文, 弹出当前请求的 flask 实例上下文。

def push(self):
"""Binds the request context to the current context."""
top = _request_ctx_stack.top
if top is not None and top.preserved:
top.pop(top._preserved_exc) # Before we push the request context we have to ensure that there
# is an application context.
app_ctx = _app_ctx_stack.top
if app_ctx is None or app_ctx.app != self.app:
app_ctx = self.app.app_context()
app_ctx.push()
self._implicit_app_ctx_stack.append(app_ctx)
else:
self._implicit_app_ctx_stack.append(None) if hasattr(sys, 'exc_clear'):
sys.exc_clear() _request_ctx_stack.push(self) if self.session is None:
session_interface = self.app.session_interface
self.session = session_interface.open_session(
self.app, self.request
) if self.session is None:
self.session = session_interface.make_null_session(self.app)

备注:

之前有提到过, web 服务器与 web 框架是分开的,而且 WSGI 也不支持异步服务器。当 web 服务器是异步服务器时,因为 flask 存在线程级全局变量, 且是基于 Werkzeug 中基于 greenlet 的 LocalStack 上实现,所以当异步服务器不是基于 greenlet 时,会存在一定问题。

Flask 框架理解(一)的更多相关文章

  1. Flask框架基础--第一篇

    1.flask框架和其他几种框架的优缺点对比 Django : 优点 - 大而全所有组件都是有组织内部开发高度定制化 教科书级别的框架 缺点 - 大到浪费资源,请求的时候需要的资源较高 Flask : ...

  2. Python Flask框架

    Python有很多Web框架,可谓是百家争鸣,我这里列出几个比较叼的几个框架 Django      市场占有率最高,官方文档几近完美,但是适合比较大的项目,小项目会显得累赘. Tornado    ...

  3. flask框架1

    说flask框架之前,必须得提一下web框架,他的作用是为了利用互联网交流工作文档,我们为什么要使用框架,因为框架的稳定性和可扩展性强并且可以降低开发难度,提高开发效率.总的来说就是避免做无用功,重复 ...

  4. 真正搞明白Python中Django和Flask框架的区别

    在谈Python中Django框架和Flask框架的区别之前,我们需要先探讨如下几个问题. 一.为什么要使用框架? 为了更好地阐述这个问题,我们把开发一个应用的过程进行类比,往往开发一个应用(web应 ...

  5. 一线Python运维开发带你秒懂Flask框架

    相信曾经纠结过这个问题:怎样才能彻底掌握flask? Flask是一个使用 Python 编写的轻量级 Web 应用框架.其 WSGI 工具箱采用 Werkzeug ,模板引擎则使用 Jinja2 . ...

  6. Flask框架踩坑之ajax跨域请求

    业务场景: 前后端分离需要对接数据接口. 接口测试是在postman做的,今天才开始和前端对接,由于这是我第一次做后端接口开发(第一次嘛,问题比较多)所以在此记录分享我的踩坑之旅,以便能更好的理解,应 ...

  7. 测试开发中Django和Flask框架

    Python测试开发中Django和Flask框架 为了更好地阐述这个问题,我们把开发一个应用的过程进行类比,往往开发一个应用(web应用.系统应用)跟建造房子的过程一样,需要先打地基,搭好骨架,然后 ...

  8. Flask框架(2)--编写简单的用户注册--登录场景

    为了更好的理解web前后端的工作业务逻辑:本笔记记录用flask框架编写的一个最初级的代码实现简单的用户注册,登录场景: 初次进入首页,提示--游客,欢迎参观,有登录和注册选项, 登录成功后的用户,会 ...

  9. 基于Flask框架搭建视频网站的学习日志(二)

    基于Flask框架搭建视频网站的学习日志(二)2020/02/02 一.初始化 所有的Flask程序都必须创建一个程序实例,程序实例是Flask类的对象 from flask import Flask ...

随机推荐

  1. 阿里 RPC 框架 DUBBO 初体验

    最近研究了一下阿里开源的分布式RPC框架dubbo,楼主写了一个 demo,体验了一下dubbo的功能. 快速开始 实际上,dubbo的官方文档已经提供了如何使用这个RPC框架example代码,基于 ...

  2. kubernetes 1.3管中窥豹- RS(Replica Sets):the next-generation Replication Controller

    前言 kubernates 1.3出了几个新的概念,其中包括deployments,Replica Sets,并且官网称之为是the next-generation Replication Contr ...

  3. vs2015+opencv3.3.1 实现 c++ 彩色高斯滤波器(Gaussian Smoothing, Gaussian Blur, Gaussian Filter)

    //高斯滤波器 https://github.com/scutlzk#include <opencv2\highgui\highgui.hpp> #include <iostream ...

  4. 主流C语言编译器介绍

  5. windows10 docker 使用以及虚拟机下fastDFS 的使用教程

    我们 先来了解下 什么是docker?   Docker的思想来自于集装箱,集装箱解决了什么问题?在一艘大船上,可以把货物规整的摆放起来.并且各种各样的货物被集装箱标准化了,集装箱和集装箱之间不会互相 ...

  6. CBV请求流程源码分析

    一.CBV流程解析 urls.py urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^book/', views.BookView.as ...

  7. javascript中构造器(函数)的__proto__与prototype初探

    背景:最近没什么需求,快要闲出屁了,所以重温了一下js的原型,结果大有收获,且偶然看到Snandy大神的<JavaScript中__proto__与prototype的关系> 这篇文章,感 ...

  8. [I/O]一览图

  9. 【python跨目录调用】结合自己遇到的问题到解决问题,作个记录

    写PO的时候,想把page和case 文件分开存不同的文件夹,但是在调用模块的时候就出现了问题.后来终于解决了,记录下 ---------------------------------------- ...

  10. Android 连接服务器,并进行相关操作

    1.连接服务器 (1)直接使用WINDOWS自带的远程桌面连接 win+R调出DOS操作窗口,输入mstsc.exe 点击确定,进入如下界面: 点击连接,输入用户名和密码登录,电脑会进入服务器界面.