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 应用程序。例如,如果 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/
结尾的 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 服务器或应用程序不应使用它,因为数据是假的!
用法示例(另请参阅
demo_app()
以获取另一个示例)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()
方法以获取要生成(yield)的字节串。当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,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 应用程序非常有用。可调用对象 start_response 应该遵循
StartResponse
协议。
- 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 (即 socket)、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 服务器和网关的基本处理程序类。这些基本类处理与 WSGI 应用程序通信的大部分工作,只要它们给定一个类似 CGI 的环境,以及输入、输出和错误流。
- 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
,该PATH_INFO
会在前面重复SCRIPT_NAME
,从而导致希望实现路由的 WSGI 应用程序出现问题。此处理程序会剥离任何此类重复路径。IIS 可以配置为传递正确的
PATH_INFO
,但这会导致另一个错误,即PATH_TRANSLATED
不正确。幸运的是,这个变量很少使用,并且 WSGI 并不保证。然而,在 IIS<7 上,设置只能在虚拟主机级别进行,影响所有其他脚本映射,其中许多在暴露于PATH_TRANSLATED
错误时会中断。因此,IIS<7 几乎从不部署此修复(即使 IIS7 也很少使用它,因为仍然没有用户界面)。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
属性。它还会插入一个SERVER_SOFTWARE
键(如果不存在),只要origin_server
属性为真且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 的“错误处理”部分所述)。特别是,可调用对象 start_response 应遵循StartResponse
协议。默认实现仅使用
error_status
、error_headers
和error_body
属性生成输出页面。子类可以重写此方法以生成更动态的错误输出。但是请注意,从安全角度来看,不建议将诊断信息直接显示给任何普通用户;理想情况下,您应该采取特殊措施来启用诊断输出,这就是默认实现不包含任何诊断信息的原因。
- error_headers¶
用于错误响应的 HTTP 头。这应该是一个 WSGI 响应头列表(
(name, value)
元组),如 PEP 3333 中所述。默认列表只将内容类型设置为text/plain
。
- error_body¶
错误响应主体。这应该是一个 HTTP 响应主体字节串。它默认为纯文本“A server error occurred. Please contact the administrator.”
用于 PEP 3333 的“可选平台特定文件处理”功能的方法和属性
- wsgi_file_wrapper¶
一个
wsgi.file_wrapper
工厂,与wsgiref.types.FileWrapper
兼容,或None
。此属性的默认值是wsgiref.util.FileWrapper
类。
- sendfile()¶
重写以实现特定于平台的文件传输。此方法仅在应用程序的返回值是
wsgi_file_wrapper
属性指定的类的实例时调用。如果它能够成功传输文件,则应返回一个真值,以便不会执行默认的传输代码。此方法的默认实现只返回一个假值。
杂项方法和属性
- origin_server¶
如果处理程序的
_write()
和_flush()
正用于直接与客户端通信,而不是通过需要特殊Status:
头中的 HTTP 状态的类 CGI 网关协议进行通信,则此属性应设置为 true。此属性在
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 服务器上,os.environ
不一定符合 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¶
一个
typing.Protocol
,描述 start_response() 可调用对象(PEP 3333)。
- wsgiref.types.WSGIEnvironment¶
描述 WSGI 环境字典的类型别名。
- wsgiref.types.WSGIApplication¶
描述 WSGI 应用程序可调用对象的类型别名。
- class wsgiref.types.InputStream¶
一个
typing.Protocol
,描述一个 WSGI 输入流。
- class wsgiref.types.ErrorStream¶
一个
typing.Protocol
,描述一个 WSGI 错误流。
- class wsgiref.types.FileWrapper¶
一个
typing.Protocol
,描述一个 文件包装器。有关此协议的具体实现,请参阅wsgiref.util.FileWrapper
。
示例¶
这是一个可工作的“Hello World”WSGI 应用程序,其中 start_response 可调用对象应遵循 StartResponse
协议
"""
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_file_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()