• 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):
    函数
  • 相关阅读:
    NOIp2014 Day2T3 解方程 秦九韶算法
    Luogu P1082 同余方程 拓展欧几里得
    Luogu P1351 联合权值 前缀和
    [USACO06JAN]冗余路径Redundant Paths 无向图tarjan缩点
    P1073 最优贸易 dp
    LOJ #6279. 数列分块入门 3
    LOJ #6278. 数列分块入门 2
    分块
    字典树Trie
    KMP
  • 原文地址:https://www.cnblogs.com/ssyfj/p/8509404.html
Copyright © 2020-2023  润新知