Flask是一个非常流行的Python开源Web框架,Flask主要依赖2个库

  • Jinja2
  • Werkzeug, 使用python内置的BaseHTTPServer来实现wisgi,为Flask.run()默认的启动方式,但是不推荐生产环境使用

程序基本结构

  1. from flask import Flask
  2. from flask import request
  3. app = Flask(__name__) # 以环境变量__name__作为程序根目录,方便后续定位静态资源
  4. @app.route('/', methods=['GET', 'POST']) # Flask使用装饰器来定义路由
  5. def home():
  6. return '<h1>Home</h1>'
  7. @app.route('/signin', methods=['GET'])
  8. def signin_form():
  9. return '''<form action="/signin" method="post">
  10. <p><input name="username"></p>
  11. <p><input name="password" type="password"></p>
  12. <p><button type="submit">Sign In</button></p>
  13. </form>'''
  14. @app.route('/signin', methods=['POST'])
  15. def signin():
  16. # 需要从request对象读取表单内容:
  17. if request.form['username']=='admin' and request.form['password']=='password':
  18. return '<h3>Hello, admin!</h3>'
  19. return '<h3>Bad username or password.</h3>'
  20. if __name__ == '__main__':
  21. app.run() # 使用Werkzeug来启动web服务,不适合生产环境

上下文(Context)

Flask上下文保存在globals文件中,为全局共享。看下面这个例子,我们在请求之前就引用了request这个模块,那么这个请求的信息是如何被request获取的?在多线程中,是何如做不发生冲突的?
image.png
Flask会在wsgi接口中构造上下文对象,上下文分为应用上下文与请求上下文,分别保存当前app信心与当前的请求信息。
上下文信息在线程安全的对象(werkzeug.local,相当于java中的ThreadLocal)中,FLask手动创建与释放这些对象,当一次请求到来FLask-wsgi程序按照以下顺序创建上下文:

  1. RequestContext(self, environ),以当前app对象(FLask实例)与请求信息(http字段构成的字典)创建一个请求上下文对象
  2. RequestContext.push(), 以当前app实例为参数构建AppContext(self)并放入_request_ctx_stack对象中,然后在_request_ctx_stack中放入当前请求上下文对象。

    请求调度

    请求调度也就是我们常说的路由,Flask会在程序的ur映射中查找请求的函数.Flask使用app.route装饰器或者非装饰器形式的app.add_url_rule()生成映射,可以获取app.url_map来查看所有url分配的规则。

    请求钩子

    一般用来处理请求之前或者之后执行函数。比如,每次请求都之前都要发起认证请求的用户,有以下几种方式:
  • before_first_request:注册一个函数,在处理第一个请求之前运行。
  • before_request:注册一个函数,在每次请求之前运行
  • after_request:注册一个函数,如果没有未处理的异常抛出,在每次请求之后运行
  • teardown_request:注册一个函数,即使有未处理的异常抛出,也在每次请求之后运行

    数据库

    会话

    TODO
    自动将session获取与加密

https://blog.csdn.net/xiaoxinshuaiga/article/details/80766369

Q&A

1.一个http request,Flask如何处理,需要经过哪些流程?

  1. 构造Flask实例app,该Flask实例其实就是可执行的WSGI程序,其中call为程序入口
  2. 执行app.run(),校验启动参数,然后执行werkzeug.serving.run_simple()
  3. werkzeug中的服务继承自python内置库中的HTTPServer,HTTPServer传入会根据参数的不同来启动单进程,多线程或者多进程服务
  4. HTTPServer继承自内置库中的Socket_server,使用select系统调用来不停地轮序是否有新的连接
  5. 每当有flask捕获新的的请求会调用FLask实例app中的wsgi接口来处理请求,一个典型的wsgi为wsgi_app(environ, start_response),其中environ参数为请求的http信息
  6. 当一个http request到达wsgi程序的时候,flask首先应用上下文,然后构造程序上下文。同时解析请求url中并根据路由信息找到视图函数

2.signal 如何使用,什么业务场景下用?同步还是异步的?属于哪种设计模式?

参考文档:
Flask上下文: https://www.cnblogs.com/zhaopanpan/articles/9457343.html
FLask-Signal:https://www.jianshu.com/p/756ed0267f53
wsgi规范: https://www.jianshu.com/p/3fc801878e72