– WSGI实用程序和参考实现 – Internet协议和支持(Python教程)(参考资料)
wsgiref
– WSGI实用程序和参考实现
Web服务器网关接口(WSGI)是Web服务器软件和用Python编写的Web应用程序之间的标准接口。使用标准接口可以很容易地使用支持WSGI的应用程序和许多不同的Web服务器.
只有Web服务器和编程框架的作者需要了解WSGI设计的每个细分案例。您不需要了解WSGI的每个细节只是为了安装WSGI应用程序或使用现有框架编写Web应用程序.
wsgiref
是WSGI规范的参考实现,可用于向Web添加WSGI支持服务器或框架。它提供了用于操作WSGI环境变量和响应头的实用程序,用于实现WSGI服务器的基类,为WSGI应用程序提供服务的演示HTTP服务器,以及用于检查WSGI服务器和应用程序是否符合WSGI规范的验证工具( PEP 3333).
有关WSGI的更多信息,请参阅wsgi.readthedocs.io,以及linksto教程和其他资源.
wsgiref.util
– WSGI环境实用程序
此模块提供了多种实用程序用于处理WSGIenvironments的函数。WSGI环境是包含HTTP请求变量的字典,如 PEP 3333 中所述。所有采用environ参数的函数都需要提供符合WSGI的字典;请看 PEP 3333 详细说明.
wsgiref.util.
guess_scheme
(environ)-
回想一下是否
wsgi.url_scheme
应该是“http”或“https”,通过检查HTTPS
字典中的environ环境变量。其中的值是一个字符串.这个函数在创建包装CGI或类似CGI的协议(如FastCGI)的网关时很有用。通常,提供此类协议的服务器将包含
HTTPS
变量值为“1”“是”,或者当通过SSL接收请求时为“on”。所以,如果找到这样的值,这个函数返回“https”,否则返回“http”
wsgiref.util.
request_uri
// (environ, include_query=True)-
使用在 PEP 3333 的“URL Reconstruction”部分中找到的算法,返回完整的请求URI,可选地包括查询字符串。如果include_query如果是,则查询字符串不包含在生成的URI中.
wsgiref.util.
application_uri
(environ)-
与
request_uri()
类似,除了PATH_INFO
和QUERY_STRING
变量被忽略。结果是请求所解决的应用程序对象的基URI .
wsgiref.util.
shift_path_info
(environ)-
从转换单个名称
PATH_INFO
至SCRIPT_NAME
并返回名称.environ字典是modified就地;如果你需要保留原件PATH_INFO
或SCRIPT_NAME
完整地使用副本如果
PATH_INFO
,None
中没有剩余的路径段则返回通常,此例程用于处理请求URI路径的每个部分,例如将路径视为一系列字典键。此例程修改传入的环境,使其适合调用位于目标URI的另一个WSGI应用程序。例如,如果
/foo
,请求URI路径为/foo/bar/baz
,而/foo
的WSGI应用程序调用shift_path_info()
,它将收到字符串“bar”,并且环境将被更新为适合传递到/foo/bar
的WSGI应用程序。也就是说,SCRIPT_NAME
将从/foo
改为/foo/bar
和PATH_INFO
将从/bar/baz
更改为/baz
.当
PATH_INFO
只是一个“/”时,此例程返回一个空字符串并向SCRIPT_NAME
发送一个尾部斜杠,即使空路径段通常被忽略,并且SCRIPT_NAME
通常不会以斜线结尾。这是有意的行为,以确保应用程序能够区分以/x
结尾的URI与以/x/
使用此程序进行对象遍历时
wsgiref.util.
setup_testing_defaults
(environ)-
更新environ用于测试目的的普通默认值.
此例程添加了WSGI所需的各种参数,包括
HTTP_HOST
,SERVER_NAME
,SERVER_PORT
,REQUEST_METHOD
,SCRIPT_NAME
,PATH_INFO
,以及所有 PEP 3333 – 定义wsgi.*
变量。Itonly提供默认值,并不替换这些变量的任何现有设置.此例程旨在使WSGI服务器和应用程序的单元测试更容易设置虚拟环境。实际的WSGIservers或应用程序不应该使用它,因为数据是假的!
用法示例:
from wsgiref.util import setup_testing_defaultsfrom wsgiref.simple_server import make_server# A relatively simple WSGI application. It"s going to print out the# environment dictionary after being updated by setup_testing_defaultsdef simple_app(environ, start_response): setup_testing_defaults(environ) status = "200 OK" headers = [("Content-type", "text/plain; charset=utf-8")] start_response(status, headers) ret = [("%s: %s\n" % (key, value)).encode("utf-8") for key, value in environ.items()] return retwith make_server("", 8000, simple_app) as httpd: print("Serving on port 8000...") httpd.serve_forever()
除了上面的环境函数之外,wsgiref.util
module还提供了这些杂项实用程序:
wsgiref.util.
is_hop_by_hop
(header_name)-
如果’header_name’是HTTP / 1.1“Hop-by-Hop”标题,则返回true,如RFC 2616 .
- class
wsgiref.util.
FileWrapper
(filelike, blksize=8192) -
一个将类文件对象转换为迭代器。生成的对象支持
__getitem__()
和__iter__()
迭代样式,与Python 2.1和Jython兼容。当对象被迭代时,可选的blksize参数将被重复传递给filelike对象的read()
方法以获得产生的字节串。当read()
返回一个空的字节串时,迭代结束并且不可恢复.如果filelike有一个
close()
方法,返回的对象也将有一个close()
方法,它会在调用时调用filelike对象的close()
方法.示例用法:
from io import StringIOfrom wsgiref.util import FileWrapper# We"re using a StringIO-buffer for as the file-like objectfilelike = StringIO("This is an example file-like object"*10)wrapper = FileWrapper(filelike, blksize=5)for chunk in wrapper: print(chunk)
wsgiref.headers
– WSGI响应头工具
这个模块提供了一个单独的类Headers
,用于使用类似映射的界面方便地操作WSGI响应头.
- class
wsgiref.headers.
Headers
( [headers] ) -
创建一个包含headers的映射式对象,它必须是中描述的headername / value元组列表PEP 3333 。headers的默认值是空列表.
Headers
对象支持典型的映射操作,包括__getitem__()
,get()
,__setitem__()
,setdefault()
,__delitem__()
和__contains__()
。对于每个方法,键是标题名称(不区分大小写),value是与该标题名称关联的第一个值。设置标题会删除该标题的任何现有值,然后在包装标题列表的末尾添加一个新值。通常会维护标头的现有顺序,并将新标头添加到包装列表的末尾.与字典不同,
Headers
当您尝试获取或删除密钥时,对象不会引发错误不在包装的标题列表中。获取一个不存在的头只返回None
,删除一个不存在的头没有任何东西.Headers
对象也支持keys()
,values()
和items()
方法。如果存在多值标头,则keys()
和items()
返回的列表可以多次包含相同的密钥。len()
对象的Headers
与items()
的长度相同,这与包装头列表的长度相同。事实上,items()
方法只返回包装标题列表的副本.调用
bytes()
在Headers
对象上返回一个格式化的字节串,以便作为HTTP响应头传输。每个标题都放在aline上,其值由冒号和空格分隔。每一行都由一个回车符和换行符终止,而bytestring以ablank行终止.除了它们的映射接口和格式化功能外,
Headers
对象还有以下查询方法并添加多值头,并添加带有MIME参数的头:get_all
(name)-
返回指定头的所有值的列表.
返回的列表将按照它们在原始标题列表中出现的顺序排序,或者已添加到此实例中,并且可能包含重复项。删除并重新插入的任何字段始终附加到标题列表中。如果存在具有给定名称的nofield,则返回一个空列表.
add_header
(name, value, **_params)-
添加一个(可能是多值的)标头,并通过关键字参数指定可选的MIME参数.
name是要添加的标头字段。关键字参数可用于为标题字段设置MIME参数。每个参数必须是一个字符串或
None
。参数名称中的下划线转换为破折号,因为破折号在Python标识符中是非法的,但许多MIME参数名称包括破折号。如果参数值是一个字符串,它将被添加到表格name="value"
中的标题值参数中。如果是None
,则只添加参数名称。(这用于没有值的MIME参数。)示例用法:h.add_header("content-disposition", "attachment", filename="bud.gif")
以上将添加如下所示的标题:
Content-Disposition: attachment; filename="bud.gif"
版本3.5更改:headers参数是可选的.
wsgiref.simple_server
– 一个简单的WSGI HTTP服务器
这个模块实现了一个简单的HTTP服务器(基于http.server
)提供WSGI应用程序。每个服务器实例在给定主机和端口上提供单个WSGI应用程序。如果要在单个主机和端口上提供多个应用程序,则应创建一个解析PATH_INFO
以选择为每个请求调用哪个应用程序。(例如,使用shift_path_info()
功能wsgiref.util
。)
wsgiref.simple_server.
make_server
(host, port, app, server_class=WSGIServer, handler_class=WSGIRequestHandler)-
创建一个新的WSGI服务器,监听host和port,接受app的连接。返回值是提供的server_class的一个实例,并使用指定的handler_class. app必须是一个WSGIapplication对象,由PEP 3333 .
用法示例:
from wsgiref.simple_server import make_server, demo_appwith make_server("", 8000, demo_app) as httpd: print("Serving HTTP on port 8000...") # Respond to requests until process is killed httpd.serve_forever() # Alternative: serve one request, then exit httpd.handle_request()
wsgiref.simple_server.
demo_app
(environ, start_response)-
这个函数是一个小而完整的WSGI应用程序,它返回一个包含消息“Hello world!”的文本页面以及environ参数。它对于验证WSGI服务器很有用(例如
wsgiref.simple_server
)能够正确运行一个简单的WSGI应用程序
- class
wsgiref.simple_server.
WSGIServer
(server_address, RequestHandlerClass) -
创建一个
WSGIServer
实例。server_address应该是(host,port)
tuple和RequestHandlerClass应该是http.server.BaseHTTPRequestHandler
的子类,将用于处理请求.你通常不需要调用这个构造函数,如
make_server()
函数可以为你处理所有细节.WSGIServer
是http.server.HTTPServer
的子类,所以它的所有方法(例如serve_forever()
和handle_request()
)都是可用的。WSGIServer
还提供了这些特定于WSGI的方法:set_app
(application)-
将可调用的application设置为将接收请求的WSGI应用程序.
get_app
()-
返回当前设置的应用程序可调用
但是,通常情况下,您不需要使用这些额外的方法,如
set_app()
通常由make_server()
调用,而get_app()
主要是为了请求处理程序实例的存在而存在.
- class
wsgiref.simple_server.
WSGIRequestHandler
(request, client_address, server) -
为给定的request创建一个HTTP处理程序(即套接字),client_address(
(host,port)
元组)和server(WSGIServer
instance).您不需要直接创建此类的实例;它们根据需要自动创建
WSGIServer
对象。但是,您可以将此类子类化并将其作为handler_class提供给make_server()
函数。一些可能相关的覆盖小班的方法:get_environ
()-
返回包含请求的WSGI环境的字典。defaultimplementation复制
WSGIServer
对象的内容base_environ
字典属性,然后添加从HTTP请求派生的各种标头。每次调用此方法都应返回一个新的字典,其中包含PEP 3333 .
get_stderr
()-
返回应该用作
wsgi.errors
流的对象。defaultimplementation只返回sys.stderr
.
handle
()-
处理HTTP请求。默认实现使用
wsgiref.handlers
类创建一个处理程序实例来实现实际的WSGI应用程序接口.
wsgiref.validate
– WSGI一致性检查器
在创建新的WSGI应用程序对象,框架,服务器或中间件时,使用wsgiref.validate
。此模块提供了一个函数,用于创建WSGIapplication对象,以验证WSGI服务器或网关与WSGI应用程序对象之间的通信,以检查双方的协议兼容性.
请注意,此实用程序不保证完整 PEP 3333 合规性;此模块中的错误并不一定意味着错误确实存在。但是,如果此模块确实产生错误,那么实际上确定服务器或应用程序不是100%兼容的.
这个模块基于Ian Bicking的“PythonPaste”库中的paste.lint
模块.
wsgiref.validate.
validator
(application)-
包裹application并返回一个新的WSGI应用程序对象。返回的应用程序会将所有请求转发到原来的application,并检查application并且调用它的服务器符合WSGI规范和 RFC 2616 .
任何检测到的不符合都会导致
AssertionError
被提出;但请注意,这些错误的处理方式取决于服务器。例如,wsgiref.simple_server
和基于wsgiref.handlers
(不会将错误处理方法覆盖到其他地方)只会输出一条错误发生的消息,并将回溯转发到sys.stderr
或其他一些错误流.这个包装器也可以使用
warnings
模块来表示有问题但可能实际上不被禁止的行为PEP 3333 。除非使用Python命令行选项或warnings
API来抑制它们,否则任何此类警告都将写入sys.stderr
(notwsgi.errors
,除非它们恰好是同一对象).用法示例:
from wsgiref.validate import validatorfrom wsgiref.simple_server import make_server# Our callable object which is intentionally not compliant to the# standard, so the validator is going to breakdef simple_app(environ, start_response): status = "200 OK" # HTTP Status headers = [("Content-type", "text/plain")] # HTTP Headers start_response(status, headers) # This is going to break because we need to return a list, and # the validator is going to inform us return b"Hello World"# This is the application wrapped in a validatorvalidator_app = validator(simple_app)with make_server("", 8000, validator_app) as httpd: print("Listening on port 8000....") httpd.serve_forever()
wsgiref.handlers
– 服务器/网关基类
此模块提供用于实现WSGI服务器和网关的基本处理程序类。这些基类处理与aWSGI应用程序通信的大部分工作,只要它们在内部输出,输出和错误流中被赋予类似CGI的环境.
- class
wsgiref.handlers.
CGIHandler
-
基于CGI的调用
sys.stdin
,sys.stdout
,sys.stderr
和os.environ
。当您拥有WSGI应用程序并希望作为CGI脚本运行时,这非常有用。只需调用CGIHandler().run(app)
,其中app
是你想要调用的WSGI应用程序对象.这个类是
BaseCGIHandler
设置wsgi.run_once
为真,wsgi.multithread
假,和wsgi.multiprocess
为真,总是使用sys
和os
获得必要的CGI流和环境
- class
wsgiref.handlers.
IISCGIHandler
-
是
CGIHandler
,在部署onMicrosoft的IIS Web服务器时使用,而没有设置配置allowPathInfooption(IIS> = 7)或配置数据库allowPathInfoForScriptMappings(IIS< 7).默认情况下,IIS给出
PATH_INFO
在前面重复SCRIPT_NAME
,导致希望实现路由的WSGI应用程序出现问题。这个处理程序剥离任何这样的重复路径.IIS可以配置为传递正确的
PATH_INFO
,但这会导致另一个错误,其中PATH_TRANSLATED
是错的。幸运的是,这个变量被使用,WSGI无法保证。但是在IIS< 7上,这些只能在vhost级别上进行,影响所有其他脚本映射,其中许多在暴露于PATH_TRANSLATED
bug时会中断。因此,IIS< 7几乎从未部署过固定。(即使IIS7也使用它,因为它仍然没有UI。)CGI代码无法判断选项是否已设置,因此提供了一个单独的处理程序类。它的使用方式与
CGIHandler
相同,即调用IISCGIHandler().run(app)
,其中app
是你想调用的WSGI应用程序对象.新版本3.2.
- class
wsgiref.handlers.
BaseCGIHandler
(stdin, stdout, stderr, environ, multithread=True, multiprocess=False) -
与
CGIHandler
类似,但不是使用sys
和os
modules,CGI环境和I / O流是明确指定的.multithread和multiprocess值用于设置wsgi.multithread
和wsgi.multiprocess
标志处理程序实例运行的任何应用程序这个类是
SimpleHandler
打算用于HTTP“原始服务器”以外的软件。如果您正在编写一个使用Status:
标头发送HTTP状态的网关协议实现(例如CGI,FastCGI,SCGI等),您可能希望将其子类化为SimpleHandler
.
- class
wsgiref.handlers.
SimpleHandler
(stdin, stdout, stderr, environ, multithread=True, multiprocess=False) -
与
BaseCGIHandler
类似,但设计用于HTTP原始服务器。如果您正在编写HTTP服务器实现,您可能希望将其子类化而不是BaseCGIHandler
.此类是
BaseHandler
的子类。它会覆盖__init__()
,get_stdin()
,get_stderr()
,add_cgi_vars()
,_write()
和_flush()
方法,以支持通过构造函数显式设置环境和流。提供的环境和流存储在stdin
,stdout
,stderr
和environ
属性write()
stdout的方法应该写完全,就像io.BufferedIOBase
.
- class
wsgiref.handlers.
BaseHandler
-
这是一个用于运行WSGI应用程序的抽象基类。每个实例都会处理一个HTTP请求,虽然原则上你可以创建可以为多个请求重用的asubclass .
BaseHandler
实例只有一个外部使用的方法:run
(app)-
运行指定的WSGI应用程序,app.
所有其他
BaseHandler
方法在运行应用程序的过程中由此方法调用,因此主要用于允许自定义进程.必须在子类中重写以下方法:
_write
(data)-
缓冲字节data以传输到客户端。如果这种方法实际传输数据也没关系;
BaseHandler
当底层系统实际上有这样的区别时,只需将写入和刷新操作分开以获得更高的效率.
_flush
( )-
强制缓冲数据传输到客户端。如果这种方法是无操作的话也没关系(即如果
_write()
实际发送数据).
get_stdin
()-
返回一个输入流对象,适合用作当前正在处理的请求的
wsgi.input
.
get_stderr
()-
返回一个适合使用的输出流对象作为
wsgi.errors
当前正在处理的请求.
add_cgi_vars
()-
将当前请求的CGI变量插入到
environ
属性中
以下是您可能希望覆盖的一些其他方法和属性。但是,此列表只是一个摘要,并不包括可以覆盖的每个方法。在尝试创建自定义的
BaseHandler
subclass.用于自定义WSGI环境的属性和方法:
wsgi_multithread
-
用于
wsgi.multithread
环境变量。它在中默认为真BaseHandler
,但在其他子类中可能有不同的默认值(orbe由构造函数设置).
wsgi_multiprocess
-
用于
wsgi.multiprocess
环境变量。它在中默认为真BaseHandler
,但在其他子类中可能有不同的默认值(orbe由构造函数设置).
wsgi_run_once
-
用于
wsgi.run_once
环境变量的值。在BaseHandler
中它是假的,但CGIHandler
默认情况下设置它.
os_environ
-
每个请求的WSGI环境中包含的默认环境变量。默认情况下,这是导入
os.environ
时wsgiref.handlers
的副本,但是子类可以在类或实例级别创建自己的副本。请注意,字典应该被认为是只读的,因为默认值是在多个类和实例之间共享的.
server_software
-
如果设置了
origin_server
属性,则使用此属性的值来设置默认值SERVER_SOFTWARE
WSGI环境变量,还可以在HTTP响应中设置adefaultServer:
标头。对于不是HTTP原始服务器的处理程序(例如BaseCGIHandler
和CGIHandler
),它被忽略.在版本3.3中更改:术语“Python”是替换为实现特定术语,如“CPython”,“Jython”等.
get_scheme
()-
返回用于当前请求的URL方案。defaultimplementation使用来自
guess_scheme()
的wsgiref.util
函数来猜测该方案应该是“http”还是“https”,基于当前请求的environ
变量
setup_environ
// ()-
将
environ
属性设置为完全填充的WSGI环境。默认实现使用上述所有方法和属性,以及get_stdin()
,get_stderr()
和add_cgi_vars()
方法以及wsgi_file_wrapper
属性。它还插入一个SERVER_SOFTWARE
keyif不存在,只要origin_server
属性是一个真值并设置server_software
属性.
Methods和attributes for自定义异常处理:
log_exception
(exc_info)-
在服务器日志中记录exc_info元组。exc_info是
(type, value,traceback)
元组。默认实现只是将回溯写入请求的wsgi.errors
流并刷新它。子类可以覆盖此方法来更改格式或重新定位输出,将回溯邮件发送给管理员,或者其他任何可能被认为合适的操作.
traceback_limit
-
默认情况下输出的回溯中包含的最大帧数
log_exception()
方法。如果None
,包括所有框架.
error_output
(environ, start_response)-
此方法是一个WSGI应用程序,用于为用户生成错误页面。如果在将标头发送到客户端之前发生错误,则仅调用它.
此方法可以使用
sys.exc_info()
,并将该信息传递给start_response在调用它时(如PEP 3333 ).默认实现只使用
error_status
,error_headers
和error_body
属性来生成输出页面。子类可以覆盖它以产生更多动态错误输出.但请注意,从安全角度来看,不建议将outdiagnostics吐出到任何旧用户;理想情况下,你应该做一些特殊的toenable诊断输出,这就是为什么默认实现不包括任何.
error_status
-
用于错误响应的HTTP状态。这应该是PEP 3333 ;它默认为500个代码和消息.
error_headers
-
用于错误响应的HTTP标头。这应该是一个WSGIresponse标题列表(
(name, value)
元组),如 PEP 3333 中所述。默认列表只是将内容类型设置为text/plain
.
error_body
-
错误响应正文。这应该是HTTP响应主体字节串。它默认为纯文本,“发生了服务器错误。请联系管理员。“
PEP 3333 的“可选平台专用FileHandling”功能:
wsgi_file_wrapper
-
一个
wsgi.file_wrapper
工厂,或None
。thisattribute的默认值是wsgiref.util.FileWrapper
类。
sendfile
()-
覆盖以实现特定于平台的文件传输。仅当应用程序的返回值是
wsgi_file_wrapper
属性。如果它能够成功传输文件,它应返回truevalue,以便不执行defaulttransmission代码。thismethod的默认实现只返回false值.
其他方法和属性:
origin_server
-
如果使用处理程序的
_write()
和_flush()
直接与客户端通信,而不是通过CGI,则应将此属性设置为true值想要在一个特殊的Status:
header.这个属性的默认值在
BaseHandler
中为true,但在BaseCGIHandler
中为false,这样的网关协议CGIHandler
.
http_version
-
如果
origin_server
为true,则此字符串属性用于设置客户端响应集的HTTPversion。它默认为"1.0"
.
wsgiref.handlers.
read_environ
()-
将CGI变量从
os.environ
转换为PEP 3333“字节在unicode”字符串中,返回一个新字典。CGIHandler
和IISCGIHandler
使用此功能代替直接使用os.environ
在使用Python 3的所有平台和Web服务器上都不一定符合WSGI标准 – 特别是OS的实际环境是Unicode(即Windows),或者环境是字节的那些,但是Python用来解码它的系统编码是ISO-8859-1以外的任何东西(例如使用UTF-8的Unix系统).如果你正在实现自己的基于CGI的处理程序,你可能想要使用这个例程而不是仅仅复制
os.environ
directly的值//新版本3.2.
例子
这是一个有效的“Hello World”WSGI应用程序:
from wsgiref.simple_server import make_server# Every WSGI application must have an application object - a callable# object that accepts two arguments. For that purpose, we"re going to# use a function (note that you"re not limited to a function, you can# use a class for example). The first argument passed to the function# is a dictionary containing CGI-style environment variables and the# second variable is the callable object (see PEP 333).def hello_world_app(environ, start_response): status = "200 OK" # HTTP Status headers = [("Content-type", "text/plain; charset=utf-8")] # HTTP Headers start_response(status, headers) # The returned object is going to be printed return [b"Hello World"]with make_server("", 8000, hello_world_app) as httpd: print("Serving on port 8000...") # Serve until process is killed httpd.serve_forever()
评论被关闭。