wsgiref --- WSGI 工具和引用的實現?


Web 服務器網關接口(WSGI)是 Web 服務器軟件和用 Python 編寫的 Web 應用程序之間的標準接口。 具有標準接口能夠讓支持 WSGI 的應用程序與多種不同的 Web 服務器配合使用。

只有 Web 服務器和編程框架的開發者才需要了解 WSGI 設計的每個細節和邊界情況。 你不需要了解 WSGI 的每個細節而只需要安裝一個 WSGI 應用程序或編寫使用現有框架的 Web 應用程序。

wsgiref 是一個 WSGI 規范的參考實現,可被用于將 WSGI 支持添加到 Web 服務器或框架中。 它提供了操作 WSGI 環境變量和響應標頭的工具,實現 WSGI 服務器的基類,一個可部署 WSGI 應用程序的演示性 HTTP 服務器,以及一個用于檢查 WSGI 服務器和應用程序是否符合 WSGI 規范的驗證工具 (PEP 3333)。

參看 wsgi.readthedocs.io 獲取有關 WSGI 的更多信息,以及教程和其他資源的鏈接。

wsgiref.util -- WSGI 環境工具?

本模塊提供了多種工具配合 WSGI 環境使用。 WSGI 環境就是一個包含 PEP 3333 所描述的 HTTP 請求變量的目錄。 所有接受 environ 形參的函數都會預期被得到一個符合 WSGI 規范的目錄;請參閱 PEP 3333 來了解相關規范的細節。

wsgiref.util.guess_scheme(environ)?

返回對于 wsgi.url_scheme 應為 "http" 還是 "https" 的猜測,具體方式是在 environ 中檢查 HTTPS 環境變量。 返回值是一個字符串。

This function is useful when creating a gateway that wraps CGI or a CGI-like protocol such as FastCGI. Typically, servers providing such protocols will include a HTTPS variable with a value of "1" "yes", or "on" when a request is received via SSL. So, this function returns "https" if such a value is found, and "http" otherwise.

wsgiref.util.request_uri(environ, include_query=True)?

使用 PEP 3333 的 "URL Reconstruction" 一節中的算法返回完整的請求 URL,可能包括查詢字符串。 如果 include_query 為假值,則結果 URI 中將不包括查詢字符串。

wsgiref.util.application_uri(environ)?

類似于 request_uri(),區別在于 PATH_INFOQUERY_STRING 變量會被忽略。 結果為請求所指定的應用程序對象的基準 URI。

wsgiref.util.shift_path_info(environ)?

將單個名稱從 PATH_INFO 變換為 SCRIPT_NAME 并返回該名稱。 environ 目錄將被原地 修改;如果你需要保留原始 PATH_INFOSCRIPT_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 結束的和以 /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 模塊還提供了以下輔助工具:

wsgiref.util.is_hop_by_hop(header_name)?

如果 'header_name' 是 RFC 2616 所定義的 HTTP/1.1 "Hop-by-Hop" 標頭則返回 True

class wsgiref.util.FileWrapper(filelike, blksize=8192)?

一個將文件類對象轉換為 iterator 的包裝器。 結果對象同時支持 __getitem__()__iter__() 迭代形式,以便兼容 Python 2.1 和 Jython。 當對象被迭代時,可選的 blksize 形參將被反復地傳給 文件類對象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)

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 應用程序。 如果你想在一個主機名和端口號上發布多個應用程序,你應當創建一個通過解析 PATH_INFO 來選擇每個請求要發起調用哪個應用程序的 WSGI 應用程序。 (例如,使用 wsgiref.util 中的 shift_path_info() 函數。)

wsgiref.simple_server.make_server(host, port, app, server_class=WSGIServer, handler_class=WSGIRequestHandler)?

創建一個新的 WSGI 服務器并在 hostport 上進行監聽,接受對 app 的連接。 返回值是所提供的 server_class 的實例,并將使用指定的 handler_class 來處理請求。 app 必須是一個如 PEP 3333 所定義的 WSGI 應用程序對象。

用法示例:

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() 函數能為你處理所有的細節。

WSGIServerhttp.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 實例)。

你不需要直接創建該類的實例;它們會根據 WSGIServer 對象的需要自動創建。 但是,你可以子類化該類并將其作為 handler_class 提供給 make_server() 函數。 一些可能在子類中重載的相關方法:

get_environ()?

返回包含針對一個請求的 WSGI 環境的字典。 默認實現會拷貝 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.stderros.environ 發起基于 CGI 的調用。 這在當你有一個 WSGI 應用程序并想將其作為 CGI 腳本運行時很有用處。 只需發起調用 CGIHandler().run(app),其中 app 是你想要發起調用的 WSGI 應用程序。

該類是 BaseCGIHandler 的子類,它將設置 wsgi.run_once 為真值,wsgi.multithread 為假值,wsgi.multiprocess 為真值,并總是使用 sysos 來獲取所需的 CGI 流和環境。

class wsgiref.handlers.IISCGIHandler?

CGIHandler 的一個專門化替代,用于在 Microsoft 的 IIS Web 服務器上部署,無需設置 config allowPathInfo 選項 (IIS>=7) 或 metabase allowPathInfoForScriptMappings (IIS<7)。

默認情況下,IIS 給出的 PATH_INFO 會與前面的 SCRIPT_NAME 重復,導致想要實現路由的 WSGI 應用程序出現問題。 這個處理句柄會去除任何這樣的重復路徑。

IIS can be configured to pass the correct PATH_INFO, but this causes another bug where PATH_TRANSLATED is wrong. Luckily this variable is rarely used and is not guaranteed by WSGI. On IIS<7, though, the setting can only be made on a vhost level, affecting all other script mappings, many of which break when exposed to the PATH_TRANSLATED bug. For this reason IIS<7 is almost never deployed with the fix. (Even IIS7 rarely uses it because there is still no UI for it.)

CGI 代碼沒有辦法確定該選項是否已設置,因此提供了一個單獨的處理句柄類。 它的用法與 CGIHandler 相同,即通過調用 IISCGIHandler().run(app),其中 app 是你想要發起調用的 WSGI 應用程序。

3.2 新版功能.

class wsgiref.handlers.BaseCGIHandler(stdin, stdout, stderr, environ, multithread=True, multiprocess=False)?

類似于 CGIHandler,但是改用 sysos 模塊,CGI 環境和 I/O 流會被顯式地指定。 multithreadmultiprocess 值被用來為處理句柄實例所運行的任何應用程序設置 wsgi.multithreadwsgi.multiprocess 旗標。

該類是 SimpleHandler 的子類,旨在用于 HTTP "origin servers" 以外的軟件。 如果你在編寫一個網關協議實現(例如 CGI, FastCGI, SCGI 等等),它使用 Status: 標頭來發布 HTTP 狀態,你可能會想要子類化該類而不是 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, stderrenviron 屬性中。

stdoutwrite() 方法應該完整寫入每個數據塊,與 io.BufferedIOBase 一樣。

class wsgiref.handlers.BaseHandler?

這是適用于運行 WSGI 應用程序的抽象基類。 每個實例將處理一個單獨的 HTTP 請求,不過在原則上你也可以創建一個可針對多個請求重用的子類。

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 子類之前參閱文檔字符串和源代碼來了解更多信息。

用于自定義 WSGI 環境的屬性和方法:

wsgi_multithread?

用于 wsgi.multithread 環境變量的值。 它在 BaseHandler 中默認為真值,但在其他子類中可能有不同的默認值(或是由構造器來設置)。

wsgi_multiprocess?

用于 wsgi.multiprocess 環境變量的值。 它在 BaseHandler 中默認為真值,但在其他子類中可能有不同的默認值(或是由構造器來設置)。

wsgi_run_once?

用于 wsgi.run_once 環境變量的值。 它在 BaseHandler 中默認為假值,但在 CGIHandler 中默認為真值。

os_environ?

要包括在每個請求的 WSGI 環境中的默認環境變量。 在默認情況下,這是當 wsgiref.handlers 被導入時的 os.environ 的一個副本,但也可以在類或實例層級上創建它們自己的子類。 請注意該字典應當被當作是只讀的,因為默認值會在多個類和實際之間共享。

server_software?

如果設置了 origin_server 屬性,該屬性的值會被用來設置默認的 SERVER_SOFTWARE WSGI 環境變量,并且還會被用來設置 HTTP 響應中默認的 Server: 標頭。 它會被不是 It is ignored for handlers (such as BaseCGIHandler and CGIHandler) that are not HTTP origin servers.

在 3.3 版更改: 名稱 "Python" 會被替換為實現專屬的名稱如 "CPython", "Jython" 等等。

get_scheme()?

返回當前請求所使用的 URL 方案。 默認的實現會使用來自 wsgiref.utilguess_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.exc_info() 來訪問當前錯誤信息,并應當在調用 start_response 時將該信息傳遞給它(如 PEP 3333 的 "Error Handling" 部分所描述的)。

默認的實現只是使用 error_status, error_headers, 和 error_body 屬性來生成一個輸出頁面。 子類可以重載此方法來產生更動態化的錯誤輸出。

但是請注意,從安全角度看來是不建議將診斷信息暴露給任何用戶的;理想的做法是你應當通過特別處理來啟用診斷輸出,因此默認的實現并不包括這樣的內容。

error_status?

用于錯誤響應的 HTTP 狀態。 這應當是一個在 PEP 3333 中定義的字符串;它默認為代碼 500 以相應的消息。

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 工廠對象,或為 None。 該屬性的默認值是 wsgiref.util.FileWrapper 類。

sendfile()?

重載以實現平臺專屬的文件傳輸。 此方法僅在應用程序的返回值是由 wsgi_file_wrapper 屬性指定的類的實例時會被調用。 如果它能夠成功地傳輸文件則應當返回真值,以使得默認的傳輸代碼將不會被執行。 此方法的默認實現只會返回假值。

雜項方法和屬性:

origin_server?

該屬性在處理句柄的 _write()_flush() 被用于同客戶端直接通信而不是通過需要 HTTP 狀態為某種特殊 Status: 標頭的 CGI 類網關協議時應當被設為真值

該屬性在 BaseHandler 中默認為真值,但在 BaseCGIHandlerCGIHandler 中則為假值。

http_version?

如果 origin_server 為真值,則該字符串屬性會被用來設置給客戶端的響應的 HTTP 版本。 它的默認值為 "1.0"

wsgiref.handlers.read_environ()?

Transcode CGI variables from os.environ to PEP 3333 "bytes in unicode" strings, returning a new dictionary. This function is used by CGIHandler and IISCGIHandler in place of directly using os.environ, which is not necessarily WSGI-compliant on all platforms and web servers using Python 3 -- specifically, ones where the OS's actual environment is Unicode (i.e. Windows), or ones where the environment is bytes, but the system encoding used by Python to decode it is anything other than ISO-8859-1 (e.g. Unix systems using UTF-8).

如果你要實現自己的基于 CGI 的處理句柄,你可能會想要使用此例程而不是簡單地從 os.environ 直接拷貝值。

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()