python---wsgiref初探
wsgiref使用
from wsgiref.simple_server import make_serverfrom 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):函数
以上是 python---wsgiref初探 的全部内容, 来源链接: utcz.com/z/388220.html