博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python---wsgiref初探
阅读量:5311 次
发布时间:2019-06-14

本文共 7027 字,大约阅读时间需要 23 分钟。

wsgiref使用

from wsgiref.simple_server import  make_serverfrom urls import URLSdef RunServer(environ, start_respone):    start_respone('200 OK',[('Content-Type','text/html')]);    url = environ['PATH_INFO'] #用户访问路径    ret = "

404

" return retdef 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 '

Hello World

' 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):函数

 

转载于:https://www.cnblogs.com/ssyfj/p/8509404.html

你可能感兴趣的文章
ActiveX控件是什么?
查看>>
php ob_start()、ob_end_flush和ob_end_clean()多级缓冲
查看>>
Servlet生命周期、工作模式以及reloadable
查看>>
zookeeper介绍及集群的搭建(利用虚拟机)
查看>>
(转)英语写作的好习惯
查看>>
(转)如何在链表中找回路
查看>>
puppet集群
查看>>
第一章例1-1
查看>>
网络基础-1
查看>>
深入了解Angularjs指令中的ngModel
查看>>
【python深入】单例模式
查看>>
(九)Hive分析窗口函数(一) SUM,AVG,MIN,MAX
查看>>
python之路day1
查看>>
[浪风分享] -- 系列百度云管家 V2.1.0 单文件版-分享必用的神器
查看>>
031.[转] 从类状态看Java多线程安全并发
查看>>
关于截取字符串substr和substring两者的区别
查看>>
伪JS
查看>>
java开发目前技术选型
查看>>
51nod 1179 最大的最大公约数
查看>>
Kafka如何保证消息不丢失不重复
查看>>