Flask请求流程超清大图
补充一下
request是在哪里产生的:
class RequestContext(object):
# app就是flask对象
self.app = app
if request is None:
request = app.request_class(environ) # Request(environ) 处理request
self.request = request # 就是这里没错了
self.url_adapter = app.create_url_adapter(self.request)
self.flashes = None
self.session = None
请求流程

session的存取过程
session的取值过程位于上图的此部分

Flask实例的open_session方法首先是取了session_interface的值--一个类(SecureCookieSessionInterface)的对象,调用了他的open_session方法,将取出来的值赋予了ctx.session,存储到了Local实例中
session的存值过程
则是调用了session_interface代表的类实例的save_session方法但是这里存在一个问题:
class SecureCookieSessionInterface(SessionInterface):
session_class = SecureCookieSession
def open_session(self, app, request):
return self.session_class() # ctx的session就是这个类的实例
# 父类中的此方法,我给直接写到这里了,如果此函数返回False,save_session不会设置cookie
def should_set_cookie(self, app, session):
if session.modified:
# 如果session.modified为True就说明session修改过了,为什么说修改过了,看下面
return True
save_each = app.config['SESSION_REFRESH_EACH_REQUEST']
# session.permanent在SessionMixin类中
return save_each and session.permanent def save_session(self, app, session, response):
# 保存session时会根据session的modified来判断将不将session写进cookie中,下面简写
if not self.should_set_cookie(app, session):
return # session的类
class SecureCookieSession(CallbackDict, SessionMixin):
def __init__(self, initial=None):
def on_update(self):
self.modified = True
CallbackDict.__init__(self, initial, on_update)
self.modified = False # 默认是False class CallbackDict(UpdateDictMixin, dict):
def __init__(self, initial=None, on_update=None):
dict.__init__(self, initial or ())
self.on_update = on_update # 这个就是上面init定义的方法 class UpdateDictMixin(object):
# 这个类中定义了__setitem__和__delitem__ 会去执行self.on_update,修改self.modified的值
# 问题就出在这里,session["x"]=""才会去执行self.on_update,
# 但是如果session["x"]对应的是个数据结构,修改这个数据结构中的元素并不会去执行elf.on_update,
# session.modified就还是False,修不修改session就要看save_each and session.permanent了
# 如果他们之间有一个false就不会去修改,可以直接看到save_each存在与配置中
# ,而session.permanent在SessionMixin类中
on_update = None
def calls_update(name):
def oncall(self, *args, **kw):
rv = getattr(super(UpdateDictMixin, self), name)(*args, **kw)
if self.on_update is not None:
self.on_update(self)
return rv
oncall.__name__ = name
return oncall def setdefault(self, key, default=None):
modified = key not in self
rv = super(UpdateDictMixin, self).setdefault(key, default)
if modified and self.on_update is not None:
self.on_update(self)
return rv def pop(self, key, default=_missing):
modified = key in self
if default is _missing:
rv = super(UpdateDictMixin, self).pop(key)
else:
rv = super(UpdateDictMixin, self).pop(key, default)
if modified and self.on_update is not None:
self.on_update(self)
return rv __setitem__ = calls_update('__setitem__')
__delitem__ = calls_update('__delitem__')
clear = calls_update('clear')
popitem = calls_update('popitem')
update = calls_update('update')
del calls_update # session.permanent相关的
class SessionMixin(object):
# 取值时走这个方法
def _get_permanent(self):
return self.get('_permanent', False)
# 通过.设置值是走这个方法
def _set_permanent(self, value):
self['_permanent'] = bool(value)
# 这里不明白,为他设置值的时候会去调用on_update修改modified = True,如果设置了他
# SessionInterface中的should_set_cookie就会直接return True
# 而如果没设置就直接return session.permanent就好了,为什么还要and save_each
permanent = property(_get_permanent, _set_permanent)
del _get_permanent, _set_permanent new = False modified = True
将session存在其他地方
要将session存在其他地方,主要是和Flask中的session_interface属性对应的类实例有关系的.这些类要提供save_session和open_session方法
Flask的flask_session组件就提供了这些类
安装
pip install flask_session
用法
# 配置类,具体的配置是根据数据库类型设置的
class Config(object):
SECRET_KEY = "umsuldfsdflskjdf" # 加密用
PERMANENT_SESSION_LIFETIME = timedelta(minutes=20)
SESSION_TYPE = "redis"
SESSION_REDIS = Redis(host='192.168.0.94', port='6379') # 数据库连接,可以用连接池 from flask import Flask,session
from flask_session import Session
app = Flask(__name__)
app.config.from_object('Config')
Session(app)
Session干了什么
class Session(object):
def __init__(self, app=None):
self.app = app
if app is not None:
self.init_app(app) def init_app(self, app):
# 为flase实例赋了新的实例
app.session_interface = self._get_interface(app) def _get_interface(self, app):
# 根据配置来匹配不同的类
config = app.config.copy()
config.setdefault('SESSION_TYPE', 'null')
config.setdefault('SESSION_PERMANENT', True)
config.setdefault('SESSION_USE_SIGNER', False)
config.setdefault('SESSION_KEY_PREFIX', 'session:')
config.setdefault('SESSION_REDIS', None)
config.setdefault('SESSION_MEMCACHED', None)
config.setdefault('SESSION_FILE_DIR',
os.path.join(os.getcwd(), 'flask_session'))
config.setdefault('SESSION_FILE_THRESHOLD', 500)
config.setdefault('SESSION_FILE_MODE', 384)
config.setdefault('SESSION_MONGODB', None)
config.setdefault('SESSION_MONGODB_DB', 'flask_session')
config.setdefault('SESSION_MONGODB_COLLECT', 'sessions')
config.setdefault('SESSION_SQLALCHEMY', None)
config.setdefault('SESSION_SQLALCHEMY_TABLE', 'sessions') if config['SESSION_TYPE'] == 'redis':
session_interface = RedisSessionInterface(
config['SESSION_REDIS'], config['SESSION_KEY_PREFIX'],
config['SESSION_USE_SIGNER'], config['SESSION_PERMANENT'])
elif config['SESSION_TYPE'] == 'memcached':
session_interface = MemcachedSessionInterface(
config['SESSION_MEMCACHED'], config['SESSION_KEY_PREFIX'],
config['SESSION_USE_SIGNER'], config['SESSION_PERMANENT'])
elif config['SESSION_TYPE'] == 'filesystem':
session_interface = FileSystemSessionInterface(
config['SESSION_FILE_DIR'], config['SESSION_FILE_THRESHOLD'],
config['SESSION_FILE_MODE'], config['SESSION_KEY_PREFIX'],
config['SESSION_USE_SIGNER'], config['SESSION_PERMANENT'])
elif config['SESSION_TYPE'] == 'mongodb':
session_interface = MongoDBSessionInterface(
config['SESSION_MONGODB'], config['SESSION_MONGODB_DB'],
config['SESSION_MONGODB_COLLECT'],
config['SESSION_KEY_PREFIX'], config['SESSION_USE_SIGNER'],
config['SESSION_PERMANENT'])
elif config['SESSION_TYPE'] == 'sqlalchemy':
session_interface = SqlAlchemySessionInterface(
app, config['SESSION_SQLALCHEMY'],
config['SESSION_SQLALCHEMY_TABLE'],
config['SESSION_KEY_PREFIX'], config['SESSION_USE_SIGNER'],
config['SESSION_PERMANENT'])
else:
session_interface = NullSessionInterface() return session_interface
Flask请求流程超清大图的更多相关文章
- flask请求流程详解
先看一个流程图: 1.当一个请求进入的时候,Flask框架首先会实例化一个Request Context,封装了请求信息,保存在Request中.生成请求上下文后,Flask框架会将请求上下文推入到_ ...
- flask请求流程
- flask源码剖析--请求流程
想了解这篇里面的内容,请先去了解我另外一篇博客Flask上下文 在了解flask之前,我们需要了解两个小知识点 偏函数 import functools def func(a1,a2): print( ...
- python妹子图爬虫5千张高清大图突破防盗链福利5千张福利高清大图
meizitu-spider python通用爬虫-绕过防盗链爬取妹子图 这是一只小巧方便,强大的爬虫,由python编写 所需的库有 requests BeautifulSoup os lxml 伪 ...
- 爬取5K分辨率超清唯美壁纸
目录 爬取5K分辨率超清唯美壁纸 简介 编写思路 使用教程 演示图片 完整源代码 @ 爬取5K分辨率超清唯美壁纸 简介 壁纸的选择其实很大程度上能看出电脑主人的内心世界,有的人喜欢风景,有的人喜欢星空 ...
- flask请求钩子、HTTP响应、响应报文、重定向、手动返回错误码、修改MIME类型、jsonify()方法
请求钩子: 当我们需要对请求进行预处理和后处理时,就可以用Flask提供的回调函数(钩子),他们可用来注册在请求处理的不同阶段执行的处理函数.这些请求钩子使用装饰器实现,通过程序实例app调用,以 b ...
- flask请求和应用上下文
关于WSGI WSGI(全称Web Server Gateway Interface),是为 Python 语言定义的Web服务器和Web应用程序之间的一种简单而通用的接口,它封装了接受HTTP请求. ...
- DRF之REST规范介绍及View请求流程分析
编程是数据结构和算法的结合,而在Web类型的App中,我们对于数据的操作请求是通过url来承载的,本文详细介绍了REST规范和CBV请求流程. 编程是数据结构和算法的结合,小程序如简单的计算器,我们输 ...
- 如何实现1080P延迟低于500ms的实时超清直播传输技术<转>
转载地址:http://www.yunweipai.com/archives/9037.html 最近由于公司业务关系,需要一个在公网上能实时互动超清视频的架构和技术方案.众所周知,视频直播用 CDN ...
随机推荐
- 14、JDBC-DbUtils-API
DbUtils /** * DbUtils :提供如关闭连接.装载 JDBC 驱动等操作的工具类,里面方法都是静态的. * * public static void close(…) throws j ...
- netty的对象传输
pom <!-- https://mvnrepository.com/artifact/io.netty/netty-all --> <dependency> <grou ...
- netty的HelloWorld演示
pom <dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artif ...
- python 面向对象(四)反射
####################总结########## 1. isinstance: 判断xxx是否是xxx类型的(向上判断) type: 返回xx对象的数据类型 issubclass: 判 ...
- Nginx记录-nginx 负载均衡5种配置方式(转载)
nginx 负载均衡5种配置方式 1.轮询(默认) 每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除. 2.weight 指定轮询几率,weight和访问比率成 ...
- 微信小程序,错误{"errMsg":"request:fail 小程序要求的 TLS 版本必须大于等于 1.2"}
解决方法一: 开发环境,项目--->勾选不校验即可 解决办法二: 在 PowerShell中运行以下内容, 然后重启服务器 # Enables TLS R2 and Windows # Thes ...
- 028、限制容器对CPU的使用(2019-01-23 周三)
参考https://www.cnblogs.com/CloudMan6/p/7003199.html 默认情况下,所有容器都可以平等的使用host cpu资源,没有限制 docker 可以通过 ...
- C#一例绘制字体不清晰的解决办法
public static Bitmap GetPieWithText(String text, Color color, Color fontColor,Font font) { ; Bitmap ...
- NFine框架全选checkBox列错位
在jqgrid.css里找到 .ui-jqgrid .cbox{margin-left: -1px;position: initial;vertical-align: text-bottom;}.ui ...
- Java实现猜数字,附带提示功能。
很简单的一段代码: package com.changeyd.demo; import java.util.Random;import java.util.Scanner;public class M ...