wsgiref使用

from wsgiref.simple_server import make_server from urls import URLS def RunServer(environ, start_respone): start_respone('200 OK',[('Content-Type','text/html')]); url = environ['PATH_INFO'] #用戶訪問路徑 ret = "<h1 style='color:red;'>404</h1>" return ret def run(): httpd=make_server('',8080,RunServer) httpd.serve_forever()
探究make_server以及serve_forever和自定義處理函數RunServer之間的關系

def RunServer(environ, start_respone): start_respone('200 OK',[('Content-Type','text/html')]); return '<h1>Hello World</h1>' if __name__ == "__main__": httpd=make_server('',8080,RunServer) httpd.serve_forever()
首先追蹤make_server:發現返回WSGIServer對象,其中WSGIServer與WSGIRequestHandler存在聯系(一個用於客戶端連接,一個用於調用自定義函數處理數據),那他們是如何關聯和調用自定義函數是今天所需要探討的

def make_server( host, port, app, server_class=WSGIServer, handler_class=WSGIRequestHandler ): server = server_class((host, port), handler_class) server.set_app(app) return server
1.開始追蹤WSGIServer類
server = server_class((host, port), handler_class) #因為server_class=WSGIServer所有開始向上查找構造函數 class WSGIServer(HTTPServer): class HTTPServer(socketserver.TCPServer): class TCPServer(BaseServer): def __init__(self, server_address, RequestHandlerClass, bind_and_activate=True): //上面handler_class BaseServer.__init__(self, server_address, RequestHandlerClass)
在父類TCPServer中找到構造函數,也發現了與WSGIRequestHandler的聯系,繼續查找父類BaseServer
class BaseServer: def __init__(self, server_address, RequestHandlerClass): def serve_forever(self, poll_interval=0.5): if ready: self._handle_request_noblock() def _handle_request_noblock(self): try: self.process_request(request, client_address) except: def process_request(self, request, client_address): self.finish_request(request, client_address) def finish_request(self, request, client_address): 注 self.RequestHandlerClass(request, client_address, self)
最終我們會調用這里面的serve_forever函數,而這里我們調用到(注)處的處理類,並且進行了構造
2.可以開始追蹤handler_class=WSGIRequestHandler類,看是如何處理數據,對於上面(注)處調用初始化開始
此處對應上面的注處 class BaseHTTPRequestHandler(socketserver.StreamRequestHandler)://中含有構造函數 def __init__(self, request, client_address, server): self.request = request self.client_address = client_address self.server = server self.setup() try: self.handle() finally: self.finish()
發現需要找到handle函數,而我們在WSGIServer對象中進行使用的類是其子類,
handler_class=WSGIRequestHandler
所有向先尋找handle函數,最后一次在子類中出現位置是在WSGIRequestHandler中
class WSGIRequestHandler(BaseHTTPRequestHandler): def handle(self): handler = ServerHandler( self.rfile, stdout, self.get_stderr(), self.get_environ() ) handler.run(self.server.get_app())
他又構造了ServerHandler對象,並且向其中傳入了自己的數據進行構造,運行了ServerHandler對象中的run方法
先向上查找構造方法
class ServerHandler(SimpleHandler): #在父類中找到 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
開始查找run方法,發現在父類BaseHandler中
class BaseHandler: def run(self, application): self.setup_environ() self.result = application(self.environ, self.start_response) def setup_environ(self) env = self.environ = self.os_environ.copy() self.add_cgi_vars() env['wsgi.input'] = self.get_stdin() env['wsgi.errors'] = self.get_stderr() env['wsgi.version'] = self.wsgi_version env['wsgi.run_once'] = self.wsgi_run_once env['wsgi.url_scheme'] = self.get_scheme() env['wsgi.multithread'] = self.wsgi_multithread env['wsgi.multiprocess'] = self.wsgi_multiprocess if self.wsgi_file_wrapper is not None: env['wsgi.file_wrapper'] = self.wsgi_file_wrapper if self.origin_server and self.server_software: env.setdefault('SERVER_SOFTWARE',self.server_software) def start_response(self, status, headers,exc_info=None): """'start_response()' callable as specified by PEP 3333""" if exc_info: try: if self.headers_sent: # Re-raise original exception if headers sent raise exc_info[0](exc_info[1]).with_traceback(exc_info[2]) finally: exc_info = None # avoid dangling circular ref elif self.headers is not None: raise AssertionError("Headers already set!") self.status = status self.headers = self.headers_class(headers) status = self._convert_string_type(status, "Status") assert len(status)>=4,"Status must be at least 4 characters" assert status[:3].isdigit(), "Status message must begin w/3-digit code" assert status[3]==" ", "Status message must have a space after code" if __debug__: for name, val in headers: name = self._convert_string_type(name, "Header name") val = self._convert_string_type(val, "Header value") assert not is_hop_by_hop(name),"Hop-by-hop headers not allowed" return self.write
最終運行了函數application,而application則是我們傳入的自定義函數RunServer
def make_server( host, port, app, server_class=WSGIServer, handler_class=WSGIRequestHandler ): """Create a new WSGI server listening on `host` and `port` for `app`""" server = server_class((host, port), handler_class) server.set_app(app) return server #app為傳入函數
class WSGIServer(HTTPServer): def set_app(self,application): self.application = application
而WSGServer則是server_class=WSGIServer中的父類
所以最終數據都傳入到了
server = server_class((host, port), handler_class)
server對象中返回給用戶調用
而且由上面
self.result = application(self.environ, self.start_response)
我們可以知道自定義函數RunServer(environ,start_response)中的兩個參數必須加上,其各自代表了
env['wsgi.input'] = self.get_stdin() env['wsgi.errors'] = self.get_stderr() env['wsgi.version'] = self.wsgi_version ...... 信息列表
以及
def start_response(self, status, headers,exc_info=None): 函數