通讀Python官方文檔之wsgiref(未完成)

wsgirf-WSGI功能及參考實現

源碼:Lib/wsgirefhtml

Web服務器網關接口(Web Server Gateway Interface, WSGI),是用Python寫的一個服務器軟件和web應用之間的通用接口。使用通用接口,可以使同一個應用方便的被不一樣過的web服務器調用。python

只有web服務器和軟件框架做者須要知道WSGI設計的細節和極端狀況。你只須要安裝一個WSGI應用或者用現有框架寫一個web應用,並不須要知道WSGI的所有細節。git

wsgirefWSGI細則的一個參考實現,用於給web服務器和框架提供WSGI支持。它提供了處理WSGI環境變量、response頭和WSGI服務器基類的功能,一個服務於WSGI應用的HTTP服務器demo,以及檢測WSGI服務器和應用是否和WSGI細則(PEP 3333)是否一致的驗證工具。github

wsgi官網獲取更多信息和相關教程。web

wsgiref.util - WSGI環境工具

本模塊提供了一些列用於WSGI環境的適用功能。 根據PEP 3333WSGI環境是一個包含HTTP請求變量的字典。全部接受environ參數的函數都預期接受一個兼容於WSGI的字典。詳見PEP 3333算法

wsgiref.util.guess_scheme(environ)

經過檢查環境變量中的HTTPS,返回wsgi.url_schemehttp仍是https
這個函數用於,建立一個包裝CGI或者FastCGI協議的網關。通常來講,提供這些協議的服務器,當使用SSL時,會提供一個值爲"1", "yes"或者"on"的HTTPS變量。若是找到了,這個函數返回'https';不然,返回'http'。api

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

返回請求的URI,可選參數決定是否返回查詢字符串,使用PEP 3333中的"URL Reconstruction"算法。服務器

wsgiref.util.application_uri(environ)

request_uri方法相似,除了忽略PATH_INFO 還有QUERY_STRING變量。返回結果爲發起請求的應用對象的基地址(base uri)。app

wsgiref.util.shift_pathi_info(environ)

將環境變量中PAHT_INFO移動一個名字到SCRIPT_NAME,並返回。環境變量會被原地修改,若是你要保存原始值,存一個備份 。
若是PAHT_INFO中沒有剩餘的路徑節段,返回None
通常來講,這一例行程序用於處理請求URI的每一部分,例如把路徑做爲一系列字典鍵值進行處理。這一例行程序,修改傳入的環境變量,使其用於激活目標URI的WSGI應用。好比,在路徑/foo上有一個WSGI應用,請求URI爲/foo/bar/baz/foo處的WSGI應用調用shift_path_info(),將會獲得"bar",環境變量會被更新,使其傳向/foo/bar/處的WSGI應用。也就是說SCRIPT_NAME/foo變爲/foo/barPATH_INFO/bar/baz變爲/baz
當路徑僅爲"/"時,該例行程序返回空字符串,並在SCRIPT_NAME處添加末尾斜槓。儘管空路徑片斷通常都被忽略了。但SCRIPT_NAME通常不以斜槓結束。故意這樣設計,是爲了讓應用在作對象遍歷時,可以區分/x/x/這兩個不一樣的路徑。框架

# 源碼
# https://github.com/python/cpython/blob/master/Lib/wsgiref/util.py#L102
if not name and not script_name.endswith('/'):
    script_name += '/'

wsgiref.util.setup_testing_defaults(environ)

爲了測試而更新環境變量。

這個例行程序爲WSGI添加各類參數,包括HTTP_HOST, SERVER_NAME, SERVER_PORT, REQUESTS_METHOD, SCRIPT_NAME。以及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

# 這行代碼我在3.6.1下運行會出錯,make_server不支持上下文管理?
# 把with 語句改爲普通的語句好像就沒問題了。
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)

根據[RFC 2616](https://tools.ietf.org/html/rfc2616.html),若是`header_name`是`"Hop-by-Hop"`返回True.

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

一個把類文件對象轉變爲成迭代器的包裝器。結果支持`__getitem__()`和`__iter__()`。當迭代遍歷這個對象時,`blksize`參數會被重複地傳給類文件對象地`read()`方法,獲取產生的字節。當`read()`產生空字節時,迭代結束。
若是這個類文件對象有`close()`方法,返回的對象也有`close()`方法,當被調用時,會激活類文件對象的`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)

wsgi.headers WSGI response 頭工具

本模塊只提供一個類:Headers。使用(mapping-like interface)映射接口, 方便操做地操做WSGI地響應頭。

wsgiref.headers.Headers([headers])

建立一個映射對象包裝headersheaders,必須是按照PEP 3333中所規定地鍵值元組列表。默認值時一個空列表。】

Headers對象支持映射操做,包括__getitem()get(), __setitem()setdefault()__delitem(), 以及__contain__()。key是name,值是該name下的第一個值。

與字典不一樣,在你試圖刪除或者get一個不存在key時,Headers對象不會拋出異常。Headers的長度等於它items()的長度,

bytes()函數,返回一個格式化的字符串,用於傳輸HTTP響應頭。每一個頭佔一行,用冒號和控開關白分割。行爲時回車+換行。結尾是一個空行

get_all(name)

返回對應name下全部的值

返回順序爲他們在最初的頭中的位置,或者他們被添加進實例的順序。可能會重複。

add_header(name, value, **_params)

添加一個頭,經過關鍵詞參數能夠添加MIME參數。

在參數名裏的下劃線會被轉換成鏈接符。由於鏈接符在python標識符中不合法,但在MIME參數中有不少鏈接符。

wsgiref.simple_server一個簡單的WSGI HTTP服務器

本模塊提供了一個簡單的基於http.server的,可服務於WSGI應用的HTTP服務器。每個服務器實例,在一個給定的主機和端口上服務於一個WSGI應用。若是你想在一個主機和端口上,服務於多個應用,你應當建立一個WSGI應用,解析PATH_INFO決定對於每一個請求,應該選擇哪一個應用。

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

在指定host和port上,建立一個新的WSGI服務器,接受來自app的鏈接。返回值是傳入的server_class的一個實例。並會使用handler_class處理requests。app參數必須是一個符合PEP 3333定義的WSGI應用對象。

wsgirfe.simple_server.demo_app(environ, start_response)

本函數是一個小而徹底的WSGI程序,返回一個包含"Hello world!"和環境變量k-v值對的文本頁。用於確認WSGI服務器可以爭取的處理WSGI程序。

wsgiref.simple_server.WSGIServer(server_address, RequestsHandlerClass)

建立一個WSGISever實例,server_address應當是(host, port)元組,RequestHandlerClass應當是http.server.BasedHTTPRequestHandler的子類,用於處理requests。

你不須要正式調用構造器,由於make_server()函數會幫你處理細節。

WSGIServerhttp.server.HTTPServer的子類,因此繼承了其方法,如:serve_forever()handle_request()WSGIServer同時也提供了一些WSGI專有的方法。好比:

set_app(application)

設置一個可調用應用,做爲接收requests的WSGI應用。

get_app()

返回目前設置的可調用應用。

通常來講,你不要調用這些額外的方法。 set_app()通常有make_server()調用,get_app()主要是爲了requests handler實例而存在。

wsgiref.simple_server.WSGIRequestHandler(reqeust, client_address, server)

對於給定的request(例如,一個socket), client_address (一個(host, port)元組)server,建立一個HTTP handler。

你不須要直接建立這個類的實例,他們會由WSGIServer對象按需建立。單你能夠建立一個該類的子類,做爲handler_class參數,傳給make_server()函數。如下爲一些在子類中可能相關的須要重寫的函數。

get_environ()

返回一個包含WSGI環境的字典。默認設置返回WSGIServer對象的base_environ字典屬性,並加上來自HTTP request的各類頭部。每次調用這個方法,都會放回一個新的字典,包含各類PEP 3333中規定的CGI環境變量。

get_stderr()

返回被用做wsgi.errors流的對象。默認設置返回sys.stderr

handle()

處理HTTP請求,默認這是使用wsgiref.hanlder類建立一個handler實例,執行真實的WSGI應用接口。

wsgirref.validate WSGI一致性檢查器

當建立新的WSGI應用對象、框架、服務器和中間件時,用wsgiref.validate檢查新代碼是否可用是很是有用過的。本模塊提供了一個能建立WSGI應用對象的函數,使WSGI服務器和WSGI應用對象可以正常通訊,檢查兩側協議的一致性。

注意這個應用不保證徹底符合PEP 3333。這個模塊不報錯,不意味着確定沒錯。可是,若是這個模塊報錯,就意味着確定有錯誤。不是100%兼容。

這個模塊基於Python Paste

wsgiref.validate.validator(application)`

包裝application並返回一個新的WSGI應用對象,返回的應用將會把全部的請求發送給最初的應用。而且檢查這個應用和啓動它的服務器是否遵循WSGI規則和RFC 2616

任何檢測到的不一致的結果,都會拋出一個AssertionError。但,如何處理這些異常取決於服務器。好比,wsgiref.simple_server和提早基於wsgiref.handlers的服務器,會直接輸出錯誤信息,將回溯信息輸出到sys.stderr或者其餘錯誤流中。

這個包裝器也可能用warning模塊指明那些有問題的,但不徹底違反PEP 3333的行爲。除非用Python命令行選項或者是warning的api禁止,這些細心會被輸出至sys.stderr

wsgirf.handlers 服務器/網管基類

這個模塊提供了配置WSGI服務器和網關的基類。這些基類處理了大部分與一個WSGI應用之間的通訊,只要給與了他們一個CGI樣的環境,以及輸入/輸出及錯誤流。

wsgiref.hanlder.CGIHandler

經過sys.stdin, sys.stdout, sys.stderros.environ喚起CGI。當你想要經過一個CGI腳本運行一個WSGI程序時頗有用。你可使用CGIHandler().run(app)

這個類是BaseCGIHandler的子類,並將wsgi.run()=True, wsgi.multithread=False, wsgi.multiprocess=True,並使用sysos獲取必要的CGI流和環境。(參見CGI部分和前驅知識)

wsgiref.handler.IISCGIHandler

在微軟的IIS服務器上激活CGIHandler

wsgiref.handlers.BaseCGIHandler()

CGIHandler類 相似。

wsgiref.handlers.BaseHandler

一個抽象類。每一個實例處理一個HTTP請求。儘管原則上你能夠建立一個子類,從而能被多個請求服用。

只有一個方法能被外部調用。

run(app)

相關文章
相關標籤/搜索