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

python---wsgiref初探的更多相关文章

  1. 进击的Python【第一章】:Python背景初探与Python基础(一)

    Python背景初探 一.Python起源 Python的创始人为Guido van Rossum.1989年圣诞节期间,在阿姆斯特丹,Guido为了打发圣诞节的无趣,决心开发一个新的脚本解释程序,做 ...

  2. Python 3 初探,第 2 部分: 高级主题

    Python 3 是 Guido van Rossum 功能强大的通用编程语言的最新版本.它虽然打破了与 2.x 版本的向后兼容性,但却清理了某些语法方面的问题.本文是这个由两部分组成的系列文章中的第 ...

  3. python SimpleHTTPRequestHandler初探

    1,转自 https://blog.gtwang.org/web-development/python-simplehttpserver-web-server/ 如果你急需一个简单的Web Serve ...

  4. python脚本初探---新手如何直接编写一个hello world模块即可执行的.py文件

    废话不多说,就讲一下这个背景吧: 事情是这个样子的~ 本着好学的精神,咱就买了本书,学习python结果呢,发现python的教程都是一个样子滴,上来的第一个hello world 都是通过IDLE来 ...

  5. Python对象初探

    数据结构 PyObject_HEAD //对象公共头部   Py_ssize_t ob_refcnt; //对象引用数 PyTypeObject *ob_type; //对象类型 PyObject_V ...

  6. Python随笔------初探

    今年的双十一刚刚才过去,大多数人主要就是抢购商品,可能他们现在已经收到了他们夜以继日抢购的商品.然而对于我们做技术的,特别是做互联网技术的,我相信肯定都被双十一那天的许多技术震撼到了吧.云计算.分压式 ...

  7. python dash 初探 --- k 线国内版

    python dash 的应用首页,是用一个 k 线图来做 damo 的,奈何数据源用的 Google,上不去.当然,可以换 yahoo,但是毕竟国内的还是更亲切些. 官方的 demo 用的 pand ...

  8. Python爬虫初探 - selenium+beautifulsoup4+chromedriver爬取需要登录的网页信息

    目标 之前的自动答复机器人需要从一个内部网页上获取的消息用于回复一些问题,但是没有对应的查询api,于是想到了用脚本模拟浏览器访问网站爬取内容返回给用户.详细介绍了第一次探索python爬虫的坑. 准 ...

  9. Python 3 初探,第 1 部分: Python 3 的新特性

    Python 3 是 Guido van Rossum 功能强大的通用编程语言的最新版本.它虽然打破了与 2.x 版本的向后兼容性,但却清理了某些语法方面的问题.本文是系列文章中的第一篇,介绍了影响该 ...

  10. python类初探

    class human: is_alive=True is_man=True def __init__(self,age): print('this is __init__() method, whi ...

随机推荐

  1. Daily Scrum - 12/15-21

    Meeting Minutes 没有什么实质性进展: 添加/完成了一个新feature,即使用非线性的函数作为速度条的设定: 等待与travis开会,讨论下一步的feature = =: 阅读code ...

  2. python中的文件读写(open()函数、with open('file_directory','r') as f:、read()函数等)

    python中也有文件读写,通过调用内置的读写函数.可以完成文件的打开/关闭.读.写入.追加等功能. open()函数 open()函数为python中的打开文件函数,使用方式为: f = open( ...

  3. 牛客OI周赛7-提高组

    https://ac.nowcoder.com/acm/contest/371#question A.小睿睿的等式 #include <bits/stdc++.h> using names ...

  4. Effective C++(第三版)笔记 ---- 第一部分让自己习惯C++

    内容从侯捷译版的<Effective C++>(第三版)摘录 条款一 C++作为一个多种范式融合的语言,可以看成是语言的联邦,它包含了一下四种主要的次语言: C.C++以C为基础,很多时候 ...

  5. Linux中gcc与g++编译器的区别

    一.对于C文件 对于C文件gcc和g++所做的事情确实是一样的,g++在编译C文件时调用了gcc. 二.对于C++文件 1.预处理 预处理gcc与g++做了相同的事. 2.编译 gcc无法自动和c++ ...

  6. Linux文件权限属性后面有个点

    坑啊,新上的机器,监控怎么都不好使,各种报错说:没有权限 什么情况? 仔细查看,发现文件权限属性后面怎么多了个点,类似如下: 这是什么? 原来: 开启了SELinux功能的Linux系统就会有这个点. ...

  7. hashCode和equal

    转自:https://www.cnblogs.com/dolphin0520/p/3681042.html hashCode方法在Object类中: public native int hashCod ...

  8. Ubuntu 16.04安装Maven

    此篇为http://www.cnblogs.com/EasonJim/p/7139275.html的分支页. 前提:必须正确安装JDK. 一.通过二进制包(tar.gz)安装 下载: 进入下载列表:h ...

  9. Spring的编程式事务和声明式事务

    事务管理对于企业应用来说是至关重要的,当出现异常情况时,它也可以保证数据的一致性. Spring事务管理的两种方式 spring支持编程式事务管理和声明式事务管理两种方式. 编程式事务使用Transa ...

  10. Java微信公众号安全模式消息解密

    这篇文章主要为大家详细介绍了Java微信公众号安全模式消息解密,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 1.微信公众平台下载解密工具,导入项目中,根据demo解密消息 public stat ...