对flask背后运行机制感兴趣,参考网上资料,结合源码分析run函数运行时的机制,主要整理出函数调用栈。以flask0.1分析flask
首先
Flask官方文档经典示例 hello.pyapp
from flask import Flask app = Flask(__name__) @app.route("/") def hello(): return "Hello World!" if __name__ == "__main__": app.run()
如今来分析app.run()启动时发生了什么? # 代码只列出用到的函数,去掉注释等
flask.pysocket
class Flask(object): def run(self, host='localhost', port=5000, **options): from werkzeug import run_simple if 'debug' in options: self.debug = options.pop('debug') options.setdefault('use_reloader', self.debug) options.setdefault('use_debugger', self.debug) return run_simple(host, port, self, **options)
run函数导入from werkzeug import run_simple 运行run_simple(host, port, self, **options)函数
werkzeug/serving.py源码分析
def run_simple(hostname, port, application, use_reloader=False, extra_files=None, threaded=False, processes=1): def inner(): srv = make_server(hostname, port, application, threaded, processes) try: srv.serve_forever() except KeyboardInterrupt: pass inner()
run_simple函数主要运行inner(),inner调用make_server()返回类,而后调用返回类的serve_forever()。先来看看make_server()spa
werkzeug/serving.pydebug
ddef make_server(host, port, app=None, threaded=False, processes=1): if threaded and processes > 1: raise ValueError("cannot have a multithreaded and " "multi process server.") elif threaded: class handler(BaseRequestHandler): multithreaded = True class server(ThreadingMixIn, WSGIServer): pass elif processes > 1: class handler(BaseRequestHandler): multiprocess = True max_children = processes - 1 class server(ForkingMixIn, WSGIServer): pass else: handler = BaseRequestHandler server = WSGIServer srv = server((host, port), handler) srv.set_app(app) return srv
make_server(hostname, port, application, threaded, processes) 传入的都是默认参数,起做用的代码是code
else: handler = BaseRequestHandler server = WSGIServer srv = server((host, port), handler) srv.set_app(app) return srv
能够看出srv = server((host, port), handler) ,其实就是srv = WSGIServer((host, port), BaseRequestHandler),返回类就是WSGIServer ,绑定BaseRequestHandler。先看WSGIServer server
wsgiref/simple_server.py继承
class WSGIServer(HTTPServer): def __init__= 标准库 BaseHTTPServer.py class HTTPServer(SocketServer.TCPServer) : #WSGIServer继承HTTPServer的__init__函数,它本身没有 ,这句是我加的方便理解 ,下同 def set_app(self,application): #这个就是make_server函数中调用的 set_app self.application = application def get_app(self): # return self.application 标准库 BaseHTTPServer.py class HTTPServer(SocketServer.TCPServer) def __init__= 标准库 SocketServer.py class TCPServer(BaseServer): 标准库 SocketServer.py class TCPServer(BaseServer): def __init__(self, server_address, RequestHandlerClass, bind_and_activate=True): BaseServer.__init__(self, server_address, RequestHandlerClass) self.socket = socket.socket(self.address_family, self.socket_type) if bind_and_activate: # 这里调用socket.socket绑定端口 try: self.server_bind() self.server_activate() except: self.server_close() raise class BaseServer: def __init__(self, server_address, RequestHandlerClass): self.server_address = server_address self.RequestHandlerClass = RequestHandlerClass self.__is_shut_down = threading.Event() self.__shutdown_request = False def serve_forever(self, poll_interval=0.5): #这个就是run_simple中调用的serve_forever self.__is_shut_down.clear() try: while not self.__shutdown_request: r, w, e = _eintr_retry(select.select, [self], [], [], poll_interval) if self in r: self._handle_request_noblock() #调用serve_forever时调用_handle_request_noblock finally: self.__shutdown_request = False self.__is_shut_down.set() def _handle_request_noblock(self): try: request, client_address = self.get_request() except socket.error: return if self.verify_request(request, client_address): try: self.process_request(request, client_address) #继续 except: self.handle_error(request, client_address) self.shutdown_request(request) def process_request(self, request, client_address): self.finish_request(request, client_address) #继续 self.shutdown_request(request) def finish_request(self, request, client_address): self.RequestHandlerClass(request, client_address, self) # #继续 并参见 werkzeug/serving.py make_server()
调用serve_forever后到了self.RequestHandlerClass(request, client_address, self) ,根据前面的代码可知RequestHandlerClass 就是werkzeug/serving.py中的BaseRequestHandler,继续
class BaseRequestHandler(WSGIRequestHandler): def __init__= 标准库 wsgiref/simple_server.py class WSGIRequestHandler(BaseHTTPRequestHandler): #这句跟前面同样继承父类 wsgiref/simple_server.py class WSGIRequestHandler(BaseHTTPRequestHandler): def __init__= 标准库 BaseHTTPServer.py class BaseHTTPRequestHandler(SocketServer.StreamRequestHandler): #继续父类 BaseHTTPServer.py class BaseHTTPRequestHandler(SocketServer.StreamRequestHandler): def __init__= 标准库 SocketServer.py class StreamRequestHandler(BaseRequestHandler): #继续父类 SocketServer.py class StreamRequestHandler(BaseRequestHandler): #继续父类 class BaseRequestHandler: def __init__(self, request, client_address, server): self.request = request self.client_address = client_address self.server = server self.setup() try: self.handle() # 运行 参见 werkzeug/serving.py class BaseRequestHandler.handle finally: self.finish()
最后运行了self.handle() 参见 werkzeug/serving.py class BaseRequestHandler.handle
前面有,再贴下看看
class BaseRequestHandler(WSGIRequestHandler): def handle(self): #一、调用的就是这个handle,覆盖了父类的handle self.raw_requestline = self.rfile.readline() if self.parse_request(): self.get_handler().run(self.server.get_app()) #二、调用 get_handler()后,还继续调用 run() ,get_app就是wsgiref/simple_server.py中WSGIServer类定义的函数 def get_handler(self): # 三、看看它返回了什么 handler = self._handler_class if handler is None: class handler(ServerHandler): #四、新建一个类 返回的就是这个类 ,继承ServerHandler ''' 五、直接从其余文件copy出所需代码,也就是handler的父类 wsgiref/simple_server.py class ServerHandler(SimpleHandler): 继续父类 wsgiref/handlers.py class SimpleHandler(BaseHandler): def __init__(self,stdin,stdout,stderr,environ,multithread=True, multiprocess=False ): self.stdin = stdin self.stdout = stdout self.stderr = stderr self.base_env = environ self.wsgi_multithread = multithread self.wsgi_multiprocess = multiprocess class BaseHandler: #六、调用的就是这个类的run函数 def run(self, application): try: self.setup_environ() self.result = application(self.environ, self.start_response) #七、调用app,也就是app=Flask() Flask类的 __call__ self.finish_response() except: try: self.handle_error() except: # If we get an error handling an error, just give up already! self.close() raise # ...and let the actual server figure it out. ''' wsgi_multithread = self.multithreaded wsgi_multiprocess = self.multiprocess self._handler_class = handler rv = handler(self.rfile, self.wfile, self.get_stderr(), self.get_environ()) rv.request_handler = self return rv
能够看出最后调用的是application(self.environ, self.start_response) 这个application就是开始的app = Flask(__name__),调用类就是调用类的__call__ 函数 ,继续贴一下源码
class Flask(object): def __call__(self, environ, start_response): return self.wsgi_app(environ, start_response) def wsgi_app(self, environ, start_response): with self.request_context(environ): rv = self.preprocess_request() if rv is None: rv = self.dispatch_request() response = self.make_response(rv) response = self.process_response(response) return response(environ, start_response)
OK,大功告成,最后调用wsgi_app(self, environ, start_response)函数,这个就是返回响应的主函数了!!
从整个流程中,flask利用WSGIServer类启动监听端口并绑定,BaseRequestHandler类接收、返回相应的信息!彻底符合WSGI要求。剩余的工做就太过于底层,很差深刻分析了。也画了调用流程图,不过太大很差传,若是有须要能够继续交流!