因为 0.1 版本整体代码大概只有 350 行, 比较简单. 所以本篇文章会以 Flask 0.1 版本源码为基础进行剖析 Flask 应用的启动过程.
Flask 参考资料 http://docs.jinkan.org/docs/flask/index.html , 官网有一个最简单 app:
- from flask import Flask
- app = Flask(__name__)
- @app.route('/hello')
- def hello_world():
- return 'Hello World!'
- if __name__ == '__main__':
- app.run(host='0.0.0.0', port=8080,debug=True)
下面就以上面这个最简单的 Flask app 为起点, 以 v0.1 版本源码为核心进行说明整个 Flask 应用的启动过程:
一, 初始化 App
- from flask import Flask #导入 Flask 类
- app = Flask(__name__) #1, 实例化 Flask app
flask.py 文件:
1.1, 定义类变量
- class Flask(object):
- '''全局变量'''
- request_class = Request
- response_class = Response
- static_path = '/static'
- secret_key = None
- session_cookie_name = 'session'
- jinja_options = dict(
- autoescape=True,
- extensions=['jinja2.ext.autoescape', 'jinja2.ext.with_']
- )
1.2, 初始化构造函数
- def __init__(self, package_name):
- self.debug = False #debug 变量为 False
- self.package_name = package_name #一般为__name__, 如果以本模块运行, 则为__main__; 如果是被调用, 则为 app 文件名.
- self.root_path = _get_package_path(self.package_name) #获取 app 的绝对路径
- self.view_functions = {} #视图函数
- self.error_handlers = {} #错误处理
- self.before_request_funcs = [] #HTTP 请求之前需要执行的函数
- self.after_request_funcs = [] #HTTP 请求结束之后, 需要执行的函数
- self.template_context_processors = [_default_template_ctx_processor] #上下文模板变量: session,g,request
- self.url_map = Map() #url 集合
- if self.static_path is not None: #self.static_path 默认值为'/static', 所以默认会把它加入到 url_map 集合中. Map([<Rule '/static/<filename>' -> static>])
- self.url_map.add(Rule(self.static_path + '/<filename>',
- build_only=True, endpoint='static'))
- if pkg_resources is not None:
- target = (self.package_name, 'static')
- else:
- target = os.path.join(self.root_path, 'static')
- self.wsgi_app = SharedDataMiddleware(self.wsgi_app, {
- self.static_path: target
- })
- self.jinja_env = Environment(loader=self.create_jinja_loader(),
- **self.jinja_options)
- self.jinja_env.globals.update(
- url_for=url_for,
- get_flashed_messages=get_flashed_messages
- )
在构造函数中, 主要定义了一些变量 (debug, 包名, 包路径, 视图函数, 上下文相关, 路由, static 路径, 模板相关环境)
二, 路由处理
- @app.route('/hello')
- def hello_world():
- return 'Hello World!'
flask.py 文件
2.1 定义路由装饰器
功能就是完成 url_map 和 view_functions 的初始化, 其中 Rule 是 werkzeug 提供的工具.
- def route(self, rule, **options):
- def decorator(f):
- self.add_url_rule(rule, f.__name__, **options) #Map([<Rule '/hello'(HEAD,GET) -> hello_world>])
- self.view_functions[f.__name__] = f #view_functions = {'hello_world':hello_world}
- return f
- return decorator
- def add_url_rule(self, rule, endpoint, **options):
- options['endpoint'] = endpoint
- options.setdefault('methods', ('GET',))
- self.url_map.add(Rule(rule, **options))
三, app.run()
前面两个步骤, 都是初始化操作, 为后续启动做准备. 包括初始化环境变量和路由添加.
- if __name__ == '__main__':
- app.run(host='0.0.0.0', port=8080,debug=True)
app 正式启动了. 过程如下:
- flask.run()
- --> werkzeug.run_simple()
- --> werkzeug.inner()
- --> werkzeug.serving.make_server()
- -->serve_forever()
- -->SocketServer.BaseServer.HTTPServer.serve_forever() #While True:****
至此, 一个 flask 的 app 已经跑起来了.
来源: http://www.bubuko.com/infodetail-2648789.html