wsgiref
- WSGI 工具和参考实现¶
源代码: Lib/wsgiref
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。
wsgiref.util
- WSGI 环境工具¶
此模块提供了各种用于处理 WSGI 环境的实用程序函数。WSGI 环境是一个字典,其中包含 PEP 3333 中所述的 HTTP 请求变量。所有接受 environ 参数的函数都希望提供符合 WSGI 的字典;有关详细规范,请参阅 PEP 3333,有关可在类型注释中使用的类型别名,请参阅 WSGIEnvironment
。
- wsgiref.util.guess_scheme(environ)¶
通过检查 environ 字典中的
HTTPS
环境变量,返回对wsgi.url_scheme
应该是“http”还是“https”的猜测。返回值是一个字符串。此函数在创建包装 CGI 或类似 CGI 的协议(如 FastCGI)的网关时非常有用。通常,提供此类协议的服务器在通过 SSL 收到请求时,将在
HTTPS
变量中包含值“1”、“yes”或“on”。因此,如果找到此类值,则此函数返回“https”,否则返回“http”。
- wsgiref.util.request_uri(environ, include_query=True)¶
使用 PEP 3333 的“URL 重建”部分中的算法,返回完整的请求 URI,可以选择包含查询字符串。如果 include_query 为 false,则结果 URI 中不包含查询字符串。
- wsgiref.util.application_uri(environ)¶
与
request_uri()
类似,但忽略PATH_INFO
和QUERY_STRING
变量。结果是由请求寻址的应用程序对象的基 URI。
- wsgiref.util.shift_path_info(environ)¶
将单个名称从
PATH_INFO
转移到SCRIPT_NAME
并返回该名称。environ 字典是就地修改的;如果您需要保持原始的PATH_INFO
或SCRIPT_NAME
不变,请使用副本。如果
PATH_INFO
中没有剩余的路径段,则返回None
。通常,此例程用于处理请求 URI 路径的每个部分,例如将路径视为一系列字典键。此例程修改传入的环境,使其适合于调用位于目标 URI 的另一个 WSGI 应用程序。例如,如果在
/foo
处有一个 WSGI 应用程序,并且请求 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/
结尾的 URI。
- wsgiref.util.setup_testing_defaults(environ)¶
使用简单的默认值更新 environ 以进行测试。
此例程添加了 WSGI 所需的各种参数,包括
HTTP_HOST
、SERVER_NAME
、SERVER_PORT
、REQUEST_METHOD
、SCRIPT_NAME
、PATH_INFO
以及所有 PEP 3333 定义的wsgi.*
变量。它只提供默认值,不会替换这些变量的任何现有设置。此例程旨在使 WSGI 服务器和应用程序的单元测试更容易设置虚拟环境。实际的 WSGI 服务器或应用程序不应使用它,因为数据是假的!
用法示例
from wsgiref.util import setup_testing_defaults from 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_defaults def 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 ret with make_server('', 8000, simple_app) as httpd: print("Serving on port 8000...") httpd.serve_forever()
除了上述环境函数之外,wsgiref.util
模块还提供以下杂项实用程序
- class wsgiref.util.FileWrapper(filelike, blksize=8192)¶
用于将类文件对象转换为 迭代器 的
wsgiref.types.FileWrapper
协议的具体实现。生成的对象是 可迭代 的。在迭代对象时,可选的 blksize 参数将被重复传递给 filelike 对象的read()
方法以获取要生成的字节串。当read()
返回一个空的字节串时,迭代结束并且不可恢复。如果 filelike 有一个
close()
方法,则返回的对象也将有一个close()
方法,并且它将在调用时调用 filelike 对象的close()
方法。用法示例
from io import StringIO from wsgiref.util import FileWrapper # We're using a StringIO-buffer for as the file-like object filelike = StringIO("This is an example file-like object"*10) wrapper = FileWrapper(filelike, blksize=5) for chunk in wrapper: print(chunk)
在 3.11 版更改: 已移除对
__getitem__()
方法的支持。
wsgiref.headers
– WSGI 响应标头工具¶
此模块提供了一个类 Headers
,可以使用类似映射的接口方便地操作 WSGI 响应标头。
- class wsgiref.headers.Headers([headers])¶
创建一个类似映射的对象,包装 headers,它必须是 PEP 3333 中描述的标头名称/值元组列表。headers 的默认值是一个空列表。
Headers
对象支持典型的映射操作,包括__getitem__()
、get()
、__setitem__()
、setdefault()
、__delitem__()
和__contains__()
。对于这些方法中的每一个,键都是标头名称(不区分大小写),值是与该标头名称关联的第一个值。设置标头会删除该标头的任何现有值,然后在包装的标头列表的末尾添加一个新值。通常会保留标头的现有顺序,并将新标头添加到包装列表的末尾。与字典不同,当您尝试获取或删除包装标头列表中不存在的键时,
Headers
对象不会引发错误。获取不存在的标头只会返回None
,而删除不存在的标头则什么也不做。Headers
对象还支持keys()
、values()
和items()
方法。如果存在多值标头,则keys()
和items()
返回的列表可以多次包含同一个键。Headers
对象的len()
与其items()
的长度相同,后者又与包装的标头列表的长度相同。实际上,items()
方法只是返回包装的标头列表的副本。对
Headers
对象调用bytes()
会返回一个格式化的字节串,适合作为 HTTP 响应标头进行传输。每个标头都放在一行上,其值用冒号和空格分隔。每行都以回车符和换行符终止,并且字节串以空行终止。除了它们的映射接口和格式化功能之外,
Headers
对象还具有以下方法,用于查询和添加多值标头,以及添加带有 MIME 参数的标头- get_all(name)¶
返回命名标头的所有值的列表。
返回的列表将按照它们在原始标头列表中出现的顺序或添加到此实例中的顺序进行排序,并且可能包含重复项。任何已删除并重新插入的字段始终附加到标头列表中。如果给定名称不存在任何字段,则返回一个空列表。
- 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 应用程序提供服务。如果要在单个主机和端口上为多个应用程序提供服务,则应创建一个 WSGI 应用程序,该应用程序解析 PATH_INFO
以选择为每个请求调用哪个应用程序。(例如,使用 wsgiref.util
中的 shift_path_info()
函数。)
- wsgiref.simple_server.make_server(host, port, app, server_class=WSGIServer, handler_class=WSGIRequestHandler)¶
创建一个新的 WSGI 服务器,监听 host 和 port,接受 app 的连接。返回值是提供的 server_class 的实例,并将使用指定的 handler_class 处理请求。app 必须是一个 WSGI 应用程序对象,如 PEP 3333 中所定义。
用法示例
from wsgiref.simple_server import make_server, demo_app with 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)
元组,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(即套接字)、client_address(
(host,port)
元组)和 server(WSGIServer
实例)创建一个 HTTP 处理程序。您不需要直接创建此类的实例;
WSGIServer
对象会根据需要自动创建它们。但是,您可以将此类子类化,并将其作为 handler_class 提供给make_server()
函数。子类中可能需要重写的一些方法- get_environ()¶
返回请求的
WSGIEnvironment
字典。默认实现复制WSGIServer
对象的base_environ
字典属性的内容,然后添加从 HTTP 请求派生的各种标头。每次调用此方法都应返回一个新字典,其中包含 PEP 3333 中指定的所有相关 CGI 环境变量。
- get_stderr()¶
返回应该用作
wsgi.errors
流的对象。默认实现只返回sys.stderr
。
- handle()¶
处理 HTTP 请求。默认实现使用
wsgiref.handlers
类创建一个处理程序实例,以实现实际的 WSGI 应用程序接口。
wsgiref.validate
— WSGI 一致性检查器¶
在创建新的 WSGI 应用对象、框架、服务器或中间件时,使用 wsgiref.validate
验证新代码的一致性非常有用。此模块提供了一个函数,用于创建 WSGI 应用对象,这些对象验证 WSGI 服务器或网关与 WSGI 应用对象之间的通信,以检查双方是否符合协议。
请注意,此实用程序不保证完全符合 PEP 3333;此模块没有错误并不一定意味着不存在错误。但是,如果此模块确实产生错误,则几乎可以肯定服务器或应用程序并非 100% 兼容。
此模块基于 Ian Bicking 的“Python Paste”库中的 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
(不是wsgi.errors
,除非它们碰巧是同一个对象)。用法示例
from wsgiref.validate import validator from wsgiref.simple_server import make_server # Our callable object which is intentionally not compliant to the # standard, so the validator is going to break def 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 validator validator_app = validator(simple_app) with make_server('', 8000, validator_app) as httpd: print("Listening on port 8000....") httpd.serve_forever()
wsgiref.handlers
– 服务器/网关基类¶
此模块提供了用于实现 WSGI 服务器和网关的基本处理程序类。只要为这些基类提供类似 CGI 的环境以及输入、输出和错误流,它们就可以处理与 WSGI 应用程序通信的大部分工作。
- class wsgiref.handlers.CGIHandler¶
通过
sys.stdin
、sys.stdout
、sys.stderr
和os.environ
进行基于 CGI 的调用。当您有一个 WSGI 应用程序并希望将其作为 CGI 脚本运行时,这很有用。只需调用CGIHandler().run(app)
,其中app
是您希望调用的 WSGI 应用程序对象。此类是
BaseCGIHandler
的子类,它将wsgi.run_once
设置为 true,将wsgi.multithread
设置为 false,将wsgi.multiprocess
设置为 true,并且始终使用sys
和os
来获取必要的 CGI 流和环境。
- class wsgiref.handlers.IISCGIHandler¶
CGIHandler
的一种特殊替代方案,用于在 Microsoft 的 IIS Web 服务器上部署时,而无需设置 config allowPathInfo 选项 (IIS>=7) 或 metabase allowPathInfoForScriptMappings (IIS<7)。默认情况下,IIS 提供的
PATH_INFO
在前面复制了SCRIPT_NAME
,这会导致希望实现路由的 WSGI 应用程序出现问题。此处理程序会删除任何此类重复的路径。可以将 IIS 配置为传递正确的
PATH_INFO
,但这会导致另一个错误,即PATH_TRANSLATED
错误。幸运的是,这个变量很少使用,并且 WSGI 不保证它。但是,在 IIS<7 上,该设置只能在虚拟主机级别进行,影响所有其他脚本映射,其中许多在暴露于PATH_TRANSLATED
错误时会中断。因此,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
模块,而是显式指定 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
属性中。stdout 的
write()
方法应该像io.BufferedIOBase
一样完整地写入每个块。
- class wsgiref.handlers.BaseHandler¶
这是一个用于运行 WSGI 应用程序的抽象基类。每个实例将处理一个 HTTP 请求,尽管原则上您可以创建一个可用于多个请求的可重用子类。
BaseHandler
实例只有一个供外部使用的方法- run(app)¶
运行指定的 WSGI 应用程序 app。
所有其他
BaseHandler
方法都在运行应用程序的过程中由此方法调用,因此存在的主要目的是允许自定义该过程。以下方法必须在子类中重写
- _write(data)¶
缓冲字节 data 以便传输到客户端。如果此方法实际上传输了数据,则可以;
BaseHandler
只是将写入和刷新操作分开,以便在底层系统实际上有这种区别时提高效率。
- get_stdin()¶
返回与
InputStream
兼容的对象,适合用作当前正在处理的请求的wsgi.input
。
- get_stderr()¶
返回与
ErrorStream
兼容的对象,适合用作当前正在处理的请求的wsgi.errors
。
- add_cgi_vars()¶
将当前请求的 CGI 变量插入到
environ
属性中。
以下是一些您可能希望重写的其他方法和属性。但是,此列表只是一个摘要,并不包括可以重写的每个方法。在尝试创建自定义的
BaseHandler
子类之前,您应该查阅文档字符串和源代码以获取更多信息。用于自定义 WSGI 环境的属性和方法
- wsgi_multithread¶
用于
wsgi.multithread
环境变量的值。它在BaseHandler
中默认为 true,但在其他子类中可能具有不同的默认值(或由构造函数设置)。
- wsgi_multiprocess¶
用于
wsgi.multiprocess
环境变量的值。它在BaseHandler
中默认为 true,但在其他子类中可能具有不同的默认值(或由构造函数设置)。
- wsgi_run_once¶
用于
wsgi.run_once
环境变量的值。它在BaseHandler
中默认为 false,但CGIHandler
默认将其设置为 true。
- os_environ¶
要包含在每个请求的 WSGI 环境中的默认环境变量。默认情况下,这是导入
wsgiref.handlers
时os.environ
的副本,但子类可以在类或实例级别创建自己的副本。请注意,该字典应被视为只读的,因为默认值在多个类和实例之间共享。
- server_software¶
如果设置了
origin_server
属性,则此属性的值将用于设置默认的SERVER_SOFTWARE
WSGI 环境变量,以及设置 HTTP 响应中的默认Server:
标头。对于不是 HTTP 源服务器的处理程序(例如BaseCGIHandler
和CGIHandler
),将忽略此属性。在 3.3 版更改: 术语“Python”替换为特定于实现的术语,例如“CPython”、“Jython”等。
- get_scheme()¶
返回当前请求使用的 URL 方案。默认实现使用
wsgiref.util
中的guess_scheme()
函数,根据当前请求的environ
变量猜测方案应该是“http”还是“https”。
- setup_environ()¶
将
environ
属性设置为完全填充的 WSGI 环境。默认实现使用上述所有方法和属性,以及get_stdin()
、get_stderr()
和add_cgi_vars()
方法以及wsgi_file_wrapper
属性。只要origin_server
属性为真值且设置了server_software
属性,它还会插入一个SERVER_SOFTWARE
键(如果不存在)。
用于自定义异常处理的方法和属性
- 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.exception()
访问当前错误,并在调用 start_response 时应将该信息传递给它(如 PEP 3333 的“错误处理”部分所述)。默认实现仅使用
error_status
、error_headers
和error_body
属性来生成输出页面。子类可以覆盖此方法以生成更动态的错误输出。但是请注意,从安全的角度来看,不建议向任何旧用户吐出诊断信息;理想情况下,您应该做一些特殊的事情来启用诊断输出,这就是默认实现不包含任何诊断输出的原因。
- error_headers¶
用于错误响应的 HTTP 标头。这应该是 WSGI 响应标头的列表(
(name, value)
元组),如 PEP 3333 中所述。默认列表仅将内容类型设置为text/plain
。
- error_body¶
错误响应正文。这应该是 HTTP 响应正文字节字符串。它默认为纯文本“发生服务器错误。请联系管理员。”
用于 PEP 3333 的“可选平台特定文件处理”功能的方法和属性
- wsgi_file_wrapper¶
与
wsgiref.types.FileWrapper
兼容的wsgi.file_wrapper
工厂,或None
。此属性的默认值为wsgiref.util.FileWrapper
类。
- sendfile()¶
覆盖以实现特定于平台的文件传输。仅当应用程序的返回值是
wsgi_file_wrapper
属性指定的类的实例时,才会调用此方法。如果它能够成功传输文件,则它应该返回真值,以便不会执行默认的传输代码。此方法的默认实现仅返回假值。
其他方法和属性
- origin_server¶
如果处理程序的
_write()
和_flush()
用于直接与客户端通信,而不是通过希望在特殊Status:
标头中包含 HTTP 状态的类似 CGI 的网关协议进行通信,则应将此属性设置为真值。此属性在
BaseHandler
中的默认值为 true,但在BaseCGIHandler
和CGIHandler
中为 false。
- http_version¶
如果
origin_server
为 true,则此字符串属性用于设置发送给客户端的响应的 HTTP 版本。默认为"1.0"
。
- wsgiref.handlers.read_environ()¶
将 CGI 变量从
os.environ
转码为 PEP 3333 “Unicode 中的字节”字符串,返回一个新的字典。此函数由CGIHandler
和IISCGIHandler
使用,而不是直接使用os.environ
,后者在使用 Python 3 的所有平台和 Web 服务器上不一定符合 WSGI 标准——特别是那些操作系统实际环境为 Unicode 的平台(例如 Windows),或者那些环境为字节但 Python 用于解码的系统编码不是 ISO-8859-1 的平台(例如使用 UTF-8 的 Unix 系统)。如果您正在实现自己的基于 CGI 的处理程序,您可能希望使用此例程,而不是直接从
os.environ
中复制值。3.2 版新增。
wsgiref.types
– 用于静态类型检查的 WSGI 类型¶
此模块提供用于静态类型检查的各种类型,如 PEP 3333 中所述。
3.11 版新增。
- class wsgiref.types.StartResponse¶
描述 start_response() 可调用对象的
typing.Protocol
(PEP 3333)。
- wsgiref.types.WSGIEnvironment¶
描述 WSGI 环境字典的类型别名。
- wsgiref.types.WSGIApplication¶
描述 WSGI 应用程序可调用对象的类型别名。
- class wsgiref.types.InputStream¶
描述 WSGI 输入流 的
typing.Protocol
。
- class wsgiref.types.ErrorStream¶
描述 WSGI 错误流 的
typing.Protocol
。
- class wsgiref.types.FileWrapper¶
描述 文件包装器 的
typing.Protocol
。有关此协议的具体实现,请参阅wsgiref.util.FileWrapper
。
示例¶
这是一个有效的“Hello World”WSGI 应用程序
"""
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.
"""
from wsgiref.simple_server import make_server
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()
WSGI 应用程序示例,用于提供当前目录,接受命令行上的可选目录和端口号(默认值:8000)
"""
Small wsgiref based web server. Takes a path to serve from and an
optional port number (defaults to 8000), then tries to serve files.
MIME types are guessed from the file names, 404 errors are raised
if the file is not found.
"""
import mimetypes
import os
import sys
from wsgiref import simple_server, util
def app(environ, respond):
# Get the file name and MIME type
fn = os.path.join(path, environ["PATH_INFO"][1:])
if "." not in fn.split(os.path.sep)[-1]:
fn = os.path.join(fn, "index.html")
mime_type = mimetypes.guess_type(fn)[0]
# Return 200 OK if file exists, otherwise 404 Not Found
if os.path.exists(fn):
respond("200 OK", [("Content-Type", mime_type)])
return util.FileWrapper(open(fn, "rb"))
else:
respond("404 Not Found", [("Content-Type", "text/plain")])
return [b"not found"]
if __name__ == "__main__":
# Get the path and port from command-line arguments
path = sys.argv[1] if len(sys.argv) > 1 else os.getcwd()
port = int(sys.argv[2]) if len(sys.argv) > 2 else 8000
# Make and start the server until control-c
httpd = simple_server.make_server("", port, app)
print(f"Serving {path} on port {port}, control-C to stop")
try:
httpd.serve_forever()
except KeyboardInterrupt:
print("Shutting down.")
httpd.server_close()