tornado.httpclient — 非同步 HTTP 客戶端

阻塞式和非阻塞式 HTTP 客戶端介面。

此模組定義了兩個實作(simple_httpclientcurl_httpclient)共用的通用介面。應用程式可以直接實例化所選的實作類別,或使用此模組中的 AsyncHTTPClient 類別,此類別會選擇一個可使用 AsyncHTTPClient.configure 方法覆寫的實作。

預設實作是 simple_httpclient,預計這足以滿足大多數使用者的需求。但是,某些應用程式可能希望切換到 curl_httpclient,原因如下:

  • curl_httpclient 有一些在 simple_httpclient 中沒有的功能,包括支援 HTTP Proxy 以及使用指定網路介面的能力。

  • curl_httpclient 更可能與不完全符合 HTTP 規範的網站或使用 HTTP 中較少使用的功能的網站相容。

  • curl_httpclient 速度更快。

請注意,如果您正在使用 curl_httpclient,強烈建議您使用最新版本的 libcurlpycurl。目前支援的 libcurl 最低版本為 7.22.0,pycurl 的最低版本為 7.18.2。強烈建議您的 libcurl 安裝是使用非同步 DNS 解析器(線程或 c-ares)建置的,否則您可能會遇到各種請求超時的問題(如需更多資訊,請參閱 http://curl.haxx.se/libcurl/c/curl_easy_setopt.html#CURLOPTCONNECTTIMEOUTMS 和 curl_httpclient.py 中的註解)。

若要選擇 curl_httpclient,請在啟動時呼叫 AsyncHTTPClient.configure

AsyncHTTPClient.configure("tornado.curl_httpclient.CurlAsyncHTTPClient")

HTTP 客戶端介面

class tornado.httpclient.HTTPClient(async_client_class: Optional[Type[AsyncHTTPClient]] = None, **kwargs: Any)[原始碼]

一個阻塞式的 HTTP 客戶端。

提供此介面是為了更容易在同步和非同步應用程式之間共享程式碼。正在執行 IOLoop 的應用程式必須改用 AsyncHTTPClient

典型的用法如下所示

http_client = httpclient.HTTPClient()
try:
    response = http_client.fetch("http://www.google.com/")
    print(response.body)
except httpclient.HTTPError as e:
    # HTTPError is raised for non-200 responses; the response
    # can be found in e.response.
    print("Error: " + str(e))
except Exception as e:
    # Other errors are possible, such as IOError.
    print("Error: " + str(e))
http_client.close()

變更於版本 5.0: 由於 asyncio 的限制,在 IOLoop 正在執行時,不再可能使用同步 HTTPClient。請改用 AsyncHTTPClient

close() None[原始碼]

關閉 HTTPClient,釋放任何使用的資源。

fetch(request: Union[HTTPRequest, str], **kwargs: Any) HTTPResponse[原始碼]

執行請求,傳回一個 HTTPResponse

請求可以是字串 URL 或 HTTPRequest 物件。如果它是字串,我們會使用任何額外的 kwargs 建構一個 HTTPRequestHTTPRequest(request, **kwargs)

如果在提取期間發生錯誤,我們會引發 HTTPError,除非將 raise_error 關鍵字引數設定為 False。

class tornado.httpclient.AsyncHTTPClient(force_instance: bool = False, **kwargs: Any)[原始碼]

一個非阻塞式的 HTTP 客戶端。

範例用法

async def f():
    http_client = AsyncHTTPClient()
    try:
        response = await http_client.fetch("http://www.google.com")
    except Exception as e:
        print("Error: %s" % e)
    else:
        print(response.body)

這個類別的建構子在幾個方面都很神奇:它實際上建立了一個實作特定子類別的實例,並且實例會被重複使用為一種偽單例(每個 IOLoop 一個)。關鍵字引數 force_instance=True 可用於抑制這種單例行為。除非使用 force_instance=True,否則不應將任何引數傳遞給 AsyncHTTPClient 建構子。可以使用靜態方法 configure() 設定實作子類別及其建構子的引數

所有 AsyncHTTPClient 實作都支援 defaults 關鍵字引數,可用於設定 HTTPRequest 屬性的預設值。例如

AsyncHTTPClient.configure(
    None, defaults=dict(user_agent="MyUserAgent"))
# or with force_instance:
client = AsyncHTTPClient(force_instance=True,
    defaults=dict(user_agent="MyUserAgent"))

變更於版本 5.0: 已移除 io_loop 引數(自版本 4.1 起已棄用)。

close() None[原始碼]

銷毀此 HTTP 客戶端,釋放任何使用的檔案描述符。

此方法在正常使用情況下並不需要,因為 AsyncHTTPClient 物件會以透明方式重複使用。close() 通常僅在 IOLoop 也正在關閉時,或是建立 AsyncHTTPClient 時使用了 force_instance=True 參數時才需要。

close() 之後,不能再對 AsyncHTTPClient 呼叫其他方法。

fetch(request: Union[str, HTTPRequest], raise_error: bool = True, **kwargs: Any) Future[HTTPResponse][原始碼]

非同步執行請求,並回傳 HTTPResponse

請求可以是字串 URL 或 HTTPRequest 物件。如果它是字串,我們會使用任何額外的 kwargs 建構一個 HTTPRequestHTTPRequest(request, **kwargs)

此方法會回傳一個 Future,其結果為 HTTPResponse。預設情況下,如果請求回傳的響應代碼不是 200(如果無法連線到伺服器,也可能引發其他錯誤),Future 會引發 HTTPError。相反地,如果 raise_error 設定為 False,則無論響應代碼為何,都會回傳響應。

如果有給定 callback,將會使用 HTTPResponse 呼叫它。在回呼介面中,不會自動引發 HTTPError。相反地,您必須檢查響應的 error 屬性或呼叫其 rethrow 方法。

變更於版本 6.0: 已移除 callback 參數。請改用回傳的 Future

raise_error=False 參數僅影響在使用非 200 響應代碼時引發的 HTTPError,而不是抑制所有錯誤。

classmethod configure(impl: Union[None, str, Type[Configurable]], **kwargs: Any) None[原始碼]

設定要使用的 AsyncHTTPClient 子類別。

AsyncHTTPClient() 實際上會建立子類別的實例。可以使用類別物件或此類別的完整限定名稱呼叫此方法(或者可以使用 None 來使用預設的 SimpleAsyncHTTPClient)。

如果給定其他關鍵字參數,它們將會傳遞到所建立的每個子類別實例的建構函式。關鍵字參數 max_clients 決定每個 IOLoop 上可以平行執行的 fetch() 操作的最大數量。根據正在使用的實作類別,可能會支援其他參數。

範例

AsyncHTTPClient.configure("tornado.curl_httpclient.CurlAsyncHTTPClient")

請求物件

class tornado.httpclient.HTTPRequest(url: str, method: str = 'GET', headers: Optional[Union[Dict[str, str], HTTPHeaders]] = None, body: Optional[Union[bytes, str]] = None, auth_username: Optional[str] = None, auth_password: Optional[str] = None, auth_mode: Optional[str] = None, connect_timeout: Optional[float] = None, request_timeout: Optional[float] = None, if_modified_since: Optional[Union[float, datetime]] = None, follow_redirects: Optional[bool] = None, max_redirects: Optional[int] = None, user_agent: Optional[str] = None, use_gzip: Optional[bool] = None, network_interface: Optional[str] = None, streaming_callback: Optional[Callable[[bytes], None]] = None, header_callback: Optional[Callable[[str], None]] = None, prepare_curl_callback: Optional[Callable[[Any], None]] = None, proxy_host: Optional[str] = None, proxy_port: Optional[int] = None, proxy_username: Optional[str] = None, proxy_password: Optional[str] = None, proxy_auth_mode: Optional[str] = None, allow_nonstandard_methods: Optional[bool] = None, validate_cert: Optional[bool] = None, ca_certs: Optional[str] = None, allow_ipv6: Optional[bool] = None, client_key: Optional[str] = None, client_cert: Optional[str] = None, body_producer: Optional[Callable[[Callable[[bytes], None]], Future[None]]] = None, expect_100_continue: bool = False, decompress_response: Optional[bool] = None, ssl_options: Optional[Union[Dict[str, Any], SSLContext]] = None)[source]

HTTP 客戶端請求物件。

除了 url 之外的所有參數都是選用的。

參數
  • url (str) – 要擷取的 URL

  • method (str) – HTTP 方法,例如「GET」或「POST」

  • headers (HTTPHeadersdict) – 要在請求中傳遞的其他 HTTP 標頭

  • body (strbytes) – HTTP 請求主體,為字串(位元組或 Unicode;如果為 Unicode,將會使用 utf-8 編碼)

  • body_producer (collections.abc.Callable) – 用於延遲/非同步請求主體的可呼叫物件。它會使用一個參數(一個 write 函數)呼叫,並應回傳一個 Future。它應在有新資料可用時呼叫 write 函數並傳遞新資料。write 函數會回傳一個可用於流量控制的 Future。只能指定 bodybody_producer 其中之一。curl_httpclient 不支援 body_producer。當使用 body_producer 時,建議在標頭中傳遞 Content-Length,否則將會使用分塊編碼,而許多伺服器不支援對請求使用分塊編碼。Tornado 4.0 新增

  • auth_username (str) – HTTP 驗證的使用者名稱

  • auth_password (str) – HTTP 驗證的密碼

  • auth_mode (str) – 驗證模式;預設值為 “basic”。允許的值由實作定義;curl_httpclient 支援 “basic” 和 “digest”;simple_httpclient 僅支援 “basic”。

  • connect_timeout (float) – 初始連線的逾時時間,以秒為單位,預設值為 20 秒(0 表示無逾時)。

  • request_timeout (float) – 整個請求的逾時時間,以秒為單位,預設值為 20 秒(0 表示無逾時)。

  • if_modified_since (datetimefloat) – If-Modified-Since 標頭的時間戳記。

  • follow_redirects (bool) – 是否自動追蹤重新導向,或返回 3xx 回應?預設值為 True。

  • max_redirects (int) – follow_redirects 的限制,預設值為 5。

  • user_agent (str) – 作為 User-Agent 標頭發送的字串。

  • decompress_response (bool) – 要求伺服器傳送壓縮的回應,並在下載後解壓縮。預設值為 True。Tornado 4.0 新增功能。

  • use_gzip (bool) – 自 Tornado 4.0 起,已棄用的 decompress_response 別名。

  • network_interface (str) – 用於請求的網路介面或來源 IP。請參閱下方 curl_httpclient 的注意事項。

  • streaming_callback (collections.abc.Callable) – 如果設定,streaming_callback 將在收到每個資料區塊時執行,並且最終回應中的 HTTPResponse.bodyHTTPResponse.buffer 將會是空的。

  • header_callback (collections.abc.Callable) – 如果設定,header_callback 將在收到每個標頭行時執行(包括第一行,例如 HTTP/1.0 200 OK\r\n,以及最後一行僅包含 \r\n。所有行都包含尾隨的換行字元)。最終回應中的 HTTPResponse.headers 將會是空的。這與 streaming_callback 結合使用最為有用,因為這是唯一在請求進行時存取標頭資料的方式。

  • prepare_curl_callback (collections.abc.Callable) – 如果設定,將以 pycurl.Curl 物件呼叫,允許應用程式進行額外的 setopt 呼叫。

  • proxy_host (str) – HTTP 代理主機名稱。要使用代理,必須設定 proxy_hostproxy_portproxy_usernameproxy_passproxy_auth_mode 是可選的。目前僅有 curl_httpclient 支援代理。

  • proxy_port (int) – HTTP 代理埠號。

  • proxy_username (str) – HTTP 代理使用者名稱。

  • proxy_password (str) – HTTP 代理密碼。

  • proxy_auth_mode (str) – HTTP 代理驗證模式;預設值為 “basic”。支援 “basic” 和 “digest”。

  • allow_nonstandard_methods (bool) – 是否允許 method 參數使用未知的值?預設值為 False。

  • validate_cert (bool) – 對於 HTTPS 請求,是否驗證伺服器的憑證?預設值為 True。

  • ca_certs (str) – PEM 格式的 CA 憑證檔案名稱,或 None 以使用預設值。請參閱下方搭配 curl_httpclient 使用時的注意事項。

  • client_key (str) – 用於用戶端 SSL 金鑰的檔案名稱(如果有的話)。請參閱下方搭配 curl_httpclient 使用時的注意事項。

  • client_cert (str) – 用於用戶端 SSL 憑證的檔案名稱(如果有的話)。請參閱下方搭配 curl_httpclient 使用時的注意事項。

  • ssl_options (ssl.SSLContext) – 在 simple_httpclient 中使用的 ssl.SSLContext 物件(curl_httpclient 不支援)。覆寫 validate_certca_certsclient_keyclient_cert

  • allow_ipv6 (bool) – 在可用時使用 IPv6 嗎?預設值為 True。

  • expect_100_continue (bool) – 如果為 true,則發送 Expect: 100-continue 標頭,並在發送請求主體之前等待繼續回應。僅 simple_httpclient 支援。

注意

使用 curl_httpclient 時,某些選項可能會被後續的獲取操作繼承,因為 pycurl 不允許它們被乾淨地重設。這適用於 ca_certsclient_keyclient_certnetwork_interface 參數。如果您使用這些選項,則應在每個請求上傳遞它們(您不必總是使用相同的值,但是無法將指定這些選項的請求與使用預設值的請求混合)。

3.1 版本新增: auth_mode 參數。

4.0 版本新增: body_producerexpect_100_continue 參數。

4.2 版本新增: ssl_options 參數。

4.5 版本新增: proxy_auth_mode 參數。

回應物件

class tornado.httpclient.HTTPResponse(request: HTTPRequest, code: int, headers: Optional[HTTPHeaders] = None, buffer: Optional[BytesIO] = None, effective_url: Optional[str] = None, error: Optional[BaseException] = None, request_time: Optional[float] = None, time_info: Optional[Dict[str, float]] = None, reason: Optional[str] = None, start_time: Optional[float] = None)[原始碼]

HTTP 回應物件。

屬性

  • request: HTTPRequest 物件

  • code: 數值的 HTTP 狀態碼,例如 200 或 404

  • reason: 描述狀態碼的可讀原因短語

  • headers: tornado.httputil.HTTPHeaders 物件

  • effective_url: 在追蹤任何重新導向後,資源的最終位置

  • buffer: 回應主體的 cStringIO 物件

  • body: 以位元組表示的回應主體(從 self.buffer 依需求建立)

  • error: 異常物件,如果有的話

  • request_time: 從請求開始到結束的秒數。包含從 DNS 解析到接收到最後一個位元組的所有網路操作。不包含在佇列中花費的時間(因為 max_clients 選項)。如果追蹤了重新導向,則只包含最終請求。

  • start_time: HTTP 操作開始的時間,基於 time.time (而非 IOLoop.time 使用的單調時鐘)。如果在佇列中逾時,可能為 None

  • time_info: 來自請求的診斷計時資訊字典。可用的資料可能會變動,但目前使用來自 http://curl.haxx.se/libcurl/c/curl_easy_getinfo.html 的計時,再加上 queue,這是在 AsyncHTTPClientmax_clients 設定下,等待插槽所造成的延遲(如果有的話)。

5.1 版本新增: 新增了 start_time 屬性。

在 5.1 版本變更: request_time 屬性先前包含了 simple_httpclient 在佇列中花費的時間,但不包含在 curl_httpclient 中。現在,兩種實作都排除了佇列時間。request_time 現在對於 curl_httpclient 更準確,因為它在可用時使用單調時鐘。

rethrow() None[原始碼]

如果請求發生錯誤,則引發 HTTPError

例外狀況

exception tornado.httpclient.HTTPClientError(code: int, message: Optional[str] = None, response: Optional[HTTPResponse] = None)[原始碼]

當 HTTP 請求不成功時拋出的例外狀況。

屬性

  • code - HTTP 錯誤整數錯誤碼,例如 404。當未收到 HTTP 回應時,例如逾時,則使用錯誤碼 599。

  • response - HTTPResponse 物件,如果有的話。

請注意,如果 follow_redirects 為 False,重新導向會變成 HTTPErrors,您可以查看 error.response.headers['Location'] 來了解重新導向的目的地。

變更於 5.1 版本:HTTPError 重新命名為 HTTPClientError,以避免與 tornado.web.HTTPError 衝突。名稱 tornado.httpclient.HTTPError 仍作為別名保留。

例外 tornado.httpclient.HTTPError

HTTPClientError 的別名。

命令列介面

此模組提供一個簡單的命令列介面,使用 Tornado 的 HTTP 客戶端擷取 URL。範例用法

# Fetch the url and print its body
python -m tornado.httpclient http://www.google.com

# Just print the headers
python -m tornado.httpclient --print_headers --print_body=false http://www.google.com

實作

類別 tornado.simple_httpclient.SimpleAsyncHTTPClient(force_instance: bool = False, **kwargs: Any)[原始碼]

不需外部相依性的非阻塞 HTTP 客戶端。

此類別在 Tornado 的 IOStreams 之上實作 HTTP 1.1 客戶端。基於 curl 的 AsyncHTTPClient 中某些功能尚未支援。特別是,不支援代理,不重複使用連線,而且呼叫者無法選擇要使用的網路介面。

此實作支援以下參數,這些參數可以傳遞至 configure() 來控制全域單例,或在 force_instance=True 時傳遞給建構函式。

max_clients 是可以同時進行的最大請求數量;當達到此限制時,額外的請求將會排隊。請注意,在此佇列中等待的時間仍然計入 request_timeout

defaults 是一個參數字典,將會作為提交至此客戶端的所有 HTTPRequest 物件的預設值。

hostname_mapping 是一個將主機名稱對應至 IP 位址的字典。當修改系統範圍設定(如 /etc/hosts)不可行或不理想時(例如在單元測試中),可以用來進行本機 DNS 變更。resolver 類似,但使用 Resolver 介面而不是簡單的對應。

max_buffer_size(預設為 100MB)是一次可以讀入記憶體的位元組數。max_body_size(預設為 max_buffer_size)是客戶端將接受的最大回應主體。如果沒有 streaming_callback,則適用這兩個限制中較小的那個;如果有 streaming_callback,則只適用 max_body_size

變更於 4.2 版本:新增 max_body_size 參數。

類別 tornado.curl_httpclient.CurlAsyncHTTPClient(max_clients=10, defaults=None)

基於 libcurl 的 HTTP 客戶端。

此實作支援以下參數,這些參數可以傳遞至 configure() 來控制全域單例,或在 force_instance=True 時傳遞給建構函式。

max_clients 是可以同時進行的最大請求數量;當達到此限制時,額外的請求將會排隊。

defaults 是一個參數字典,將會作為提交至此客戶端的所有 HTTPRequest 物件的預設值。

範例程式碼