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