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 接收到請求時,會包含一個值為“1”、“yes”或“on”的
HTTPS
變數。因此,如果找到這樣的值,此函式將返回“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 伺服器和閘道器提供了基本的處理程式類。這些基類處理與 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¶
當部署在 Microsoft 的 IIS Web 伺服器上,而沒有設定 config allowPathInfo 選項(IIS>=7)或 metabase allowPathInfoForScriptMappings(IIS<7)時,
CGIHandler
的一個專門的替代方案。預設情況下,IIS 給出的
PATH_INFO
在前面複製了SCRIPT_NAME
,這會導致希望實現路由的 WSGI 應用程式出現問題。此處理程式會剝離任何此類重複的路徑。可以配置 IIS 以傳遞正確的
PATH_INFO
,但這會導致另一個錯誤,即PATH_TRANSLATED
是錯誤的。幸運的是,此變數很少使用,並且 WSGI 不保證它。但是,在 IIS<7 上,只能在 vhost 級別進行設定,影響所有其他指令碼對映,其中許多在暴露於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
屬性。如果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 時應將該資訊傳遞給 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¶
一個
wsgi.file_wrapper
工廠,與wsgiref.types.FileWrapper
相容,或者為None
。此屬性的預設值是wsgiref.util.FileWrapper
類。
- sendfile()¶
重寫此方法以實現特定於平臺的的檔案傳輸。僅當應用程式的返回值是
wsgi_file_wrapper
屬性指定的類的例項時,才會呼叫此方法。如果它能夠成功傳輸檔案,則應該返回真值,以便不執行預設的傳輸程式碼。此方法的預設實現只返回假值。
其他方法和屬性
- origin_server¶
如果處理程式的
_write()
和_flush()
用於直接與客戶端通訊,而不是透過 CGI 式的閘道器協議(該協議希望 HTTP 狀態位於特殊的Status:
標頭中),則應將此屬性設定為真值。此屬性在
BaseHandler
中的預設值為真,但在BaseCGIHandler
和CGIHandler
中為假。
- http_version¶
如果
origin_server
為真,則此字串屬性用於設定傳送給客戶端的響應的 HTTP 版本。它預設為"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
中複製值。在 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 應用程式
"""
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()