Flask學習-Flask app啓動過程

由於0.1版本總體代碼大概只有350行,比較簡單。因此本篇文章會以Flask 0.1版本源碼爲基礎進行剖析Flask應用的啓動過程。html

Flask參考資料flask,官網有一個最簡單app:python

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應用的啓動過程:flask

1、初始化App

from flask import Flask    #導入Flask類
app = Flask(__name__)  #一、實例化Flask app

  

flask.py文件:安全

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_']
    )

  

a、request_class變量是一個Request類,Request類繼承自werkzeug的Request類。它調用了werkzeug的Request類的構造函數,RequestBase.__init__(self, environ)。而後又初始化了endpoint和view_args兩個變量。cookie

b、response_class變量是一個Response類。繼承自werkzeug的Reponse類。且本身初始化了變量default_mimetype=‘text/html’。session

c、static_path是靜態文件路徑,默認值爲/static。app

d、secret_key默認值爲None。關於secret_key的做用,用官方的語言來解釋:dom

If a secret key is set, cryptographic components can use this to sign cookies and other things. Set this to a complex random value when you want to use the secure cookie for instance.
若是設置了secret_key,加密組件使用這個key簽名cookies。當你要使用安全cookie,你要把這個key設置成複雜的隨機值。

This attribute can also be configured from the config with the SECRET_KEY configuration key. Defaults to None.
這個屬性能夠經過在配置文件中設置SECRET_KEY來設置。默值爲None。

  

e、session_cookie_name,session的名字爲session。函數

f、jinja_options選項初始化。工具

1.二、初始化構造函數

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路徑、模板相關環境)

 

2、路由處理

@app.route('/hello')
def hello_world():
    return 'Hello World!'

  

flask.py文件

2.1 定義路由裝飾器

功能就是完成url_map和view_functions的初始化,其中Rule是werkzeug提供的工具。

def route(self, rule, **options):   #route裝飾器,裝飾路由的同時,把路由添加進Map,添加視圖函數,確保路由和視圖函數映射起來
        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))

  

3、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已經跑起來了。

相關文章
相關標籤/搜索