python---wsgiref初探


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()
View Code

探究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()
View Code

首先追蹤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
View Code

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):
函數

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM