Tornado 異步HTTP客戶端

2022-03-09 14:45 更新

阻塞和非阻塞HTTP客戶端接口。

該模塊定義了一個由兩個實現(xiàn)共享的公共接口,即?simple_httpclient?和?curl_httpclient?。應(yīng)用程序可以直接實例化所選的實現(xiàn)類,也可以使用此模塊中的?AsyncHTTPClient?類,該模塊選擇可以用?AsyncHTTPClient.configure?方法重寫的實現(xiàn)。

默認(rèn)實現(xiàn)是 ?simple_httpclient?,并且這將適合大多數(shù)用戶的需求。 但是,某些應(yīng)用程序可能希望切換到 ?curl_httpclient?,原因如下:

  • ?curl_httpclient?有一些 ?simple_httpclient中沒有的特性,包括對 HTTP 代理的支持和使用指定網(wǎng)絡(luò)接口的能力。
  • ?curl_httpclient?更可能與不太符合 HTTP 規(guī)范的站點或使用很少使用 HTTP 功能的站點兼容。
  • ?curl_httpclient?更快。

請注意,如果您使用 ?curl_httpclient?,強烈建議您使用最新版本的 ?libcurl ?和 ?pycurl?。 目前支持的libcurl最低版本是7.22.0,pycurl最低版本是7.18.2。 強烈建議您的 ?libcurl ?安裝使用異步 DNS 解析器(threaded或 c-ares)構(gòu)建,否則您可能會遇到請求超時的各種問題

要選擇 ?curl_httpclient?,請在啟動時調(diào)用 ?AsyncHTTPClient.configure?:

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

HTTP客戶端接口

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

提供此接口是為了更輕松地在同步和異步應(yīng)用程序之間共享代碼。 運行 ?IOLoop的應(yīng)用程序必須改用?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

關(guān)閉 HTTPClient,釋放所有使用的資源。

fetch(request: Union[HTTPRequest, str], **kwargs) → tornado.httpclient.HTTPResponse

執(zhí)行一個請求,返回一個 HTTPResponse。

請求可以是字符串 URL 或 HTTPRequest 對象。 如果它是一個字符串,我們使用任何額外的 kwargs 構(gòu)造一個 HTTPRequest:?HTTPRequest(request, **kwargs)?

如果在獲取過程中發(fā)生錯誤,我們會引發(fā) HTTPError,除非 ?raise_error關(guān)鍵字參數(shù)設(shè)置為 False。

class tornado.httpclient.AsyncHTTPClient

非阻塞 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)

這個類的構(gòu)造函數(shù)在幾個方面很神奇:它實際上創(chuàng)建了一個特定于實現(xiàn)的子類的實例,并且實例被重用為一種偽單例(每個 ?IOLoop ?一個)。 關(guān)鍵字參數(shù) ?force_instance=True? 可用于抑制這種單例行為。 除非使用 ?force_instance=True?,否則不應(yīng)將任何參數(shù)傳遞給 ?AsyncHTTPClient構(gòu)造函數(shù)。 可以使用靜態(tài)方法 ?configure()? 設(shè)置實現(xiàn)子類及其構(gòu)造函數(shù)的參數(shù)

所有 ?AsyncHTTPClient實現(xiàn)都支持 ?defaults關(guān)鍵字參數(shù),可用于設(shè)置 ?HTTPRequest屬性的默認(rèn)值。 例如:

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參數(shù)(自 4.1 版以來已棄用)已被刪除。

close() → None

銷毀這個 HTTP 客戶端,釋放所有使用的文件描述符。

由于 ?AsyncHTTPClient對象被透明地重用的方式,在正常使用中不需要此方法。 ?close()? 通常僅在 ?IOLoop ?也被關(guān)閉或在創(chuàng)建 ?AsyncHTTPClient時使用 ?force_instance=True? 參數(shù)時才需要。

在 ?close()? 之后,不能在 ?AsyncHTTPClient ?上調(diào)用其他方法

fetch(request: Union[str, HTTPRequest], raise_error: bool = True, **kwargs) → Future[HTTPResponse]

執(zhí)行一個請求,異步返回一個 ?HTTPResponse?。

請求可以是字符串 URL 或 ?HTTPRequest ?對象。如果它是一個字符串,我們使用任何額外的 kwargs 構(gòu)造一個 HTTPRequest: ?HTTPRequest(request, **kwargs)?

此方法返回一個 ?Future?,其結(jié)果是一個 ?HTTPResponse?。默認(rèn)情況下,如果請求返回非 200 響應(yīng)代碼,?Future ?將引發(fā) ?HTTPError?(如果無法聯(lián)系服務(wù)器,也可能引發(fā)其他錯誤)。相反,如果 ?raise_error設(shè)置為 False,則無論響應(yīng)代碼如何,都將始終返回響應(yīng)。

如果給出回調(diào),它將使用 ?HTTPResponse ?調(diào)用。在回調(diào)接口中,?HTTPError ?不會自動引發(fā)。相反,您必須檢查響應(yīng)的錯誤屬性或調(diào)用其 ?rethrow方法。

在 6.0 版更改: 回調(diào)參數(shù)已刪除。改用返回的 ?Future?。

?raise_error=False? 參數(shù)僅影響使用非 200 響應(yīng)代碼時引發(fā)的 HTTPError,而不是抑制所有錯誤。

classmethodconfigure(impl: Union[None, str, Type[tornado.util.Configurable]], **kwargs) → None

配置要使用的 ?AsyncHTTPClient子類。

?AsyncHTTPClient()? 實際上創(chuàng)建了一個子類的實例。 可以使用類對象或此類的完全限定名稱(或 ?None使用默認(rèn)值 ?SimpleAsyncHTTPClient?)調(diào)用此方法

如果給出了額外的關(guān)鍵字參數(shù),它們將被傳遞給每個創(chuàng)建的子類實例的構(gòu)造函數(shù)。 關(guān)鍵字參數(shù) ?max_clients確定可以在每個 IOLoop 上并行執(zhí)行的同時 fetch() 操作的最大數(shù)量。 根據(jù)使用的實現(xiàn)類,可能支持其他參數(shù)。

例如:

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

請求對象

class tornado.httpclient.HTTPRequest(url: str, method: str = 'GET', headers: Union[Dict[str, str], tornado.httputil.HTTPHeaders, None] = None, body: Union[bytes, str, None] = 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: Union[float, datetime.datetime, None] = 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: Union[Dict[str, Any], ssl.SSLContext, None] = None)

HTTP 客戶端請求對象。

除 ?url之外的所有參數(shù)都是可選的。

參數(shù):

  • ?url ?(str) -- 要獲取的 URL
  • ?method ?(str) -- HTTP 方法,例如“GET”和“POST”
  • ?headers?(HTTPHeaders or dict)– 用于傳遞請求的附加 HTTP 表頭
  • ?body ?(str or bytes) -- 字符串形式的 HTTP 請求正文(字節(jié)或 unicode;如果是 unicode,將使用 utf-8 編碼)
  • ?body_producer ?(collections.abc.Callable) – 用于惰性/異步請求主體的可調(diào)用對象。它用一個參數(shù)調(diào)用,一個寫函數(shù),并且應(yīng)該返回一個 Future。它應(yīng)該在新數(shù)據(jù)可用時調(diào)用 write 函數(shù)。 write 函數(shù)返回一個可用于流控制的 Future。只能指定 body 和 body_producer 之一。 curl_httpclient 不支持 body_producer。使用 body_producer 時,建議在表頭中傳遞 Content-Length,否則將使用分塊編碼,并且許多服務(wù)器不支持請求的分塊編碼。
  • ?auth_username? (str) -- HTTP 身份驗證的用戶名
  • ?auth_password? (str) – HTTP 身份驗證的密碼
  • ?auth_mode? (str) -- 身份驗證模式;默認(rèn)為“基本”。允許的值是實現(xiàn)定義的; curl_httpclient 支持“basic”和“digest”; simple_httpclient 僅支持“基本”
  • ?connect_timeout? (float) – 初始連接超時時間,默認(rèn) 20 秒(0 表示無超時)
  • ?request_timeout? (float) – 整個請求的超時時間,以秒為單位,默認(rèn) 20 秒(0 表示沒有超時)
  • ?if_modified_since?(datatime or float)– If-Modified-Since 表頭的時間戳
  • ?follow_redirects? (bool) – 應(yīng)該自動跟隨重定向還是返回 3xx 響應(yīng)?默認(rèn)為True。
  • ?max_redirects ?(int) -- follow_redirects 的限制,默認(rèn)為 5。
  • ?user_agent ?(str) -- 作為 User-Agent 表頭發(fā)送的字符串
  • ?decompress_response ?(bool) – 從服務(wù)器請求壓縮響應(yīng)并在下載后解壓縮。默認(rèn)為True。
  • ?use_gzip ?(bool) – 自 Tornado 4.0 以來已棄用的 decompress_response 的別名。
  • ?network_interface ?(str) -- 用于請求的網(wǎng)絡(luò)接口或源 IP。
  • ?streaming_callback ?(collections.abc.Callable) – 如果設(shè)置,streaming_callback 將在收到每個數(shù)據(jù)塊時運行,并且 HTTPResponse.body 和 HTTPResponse.buffer 在最終響應(yīng)中將為空。
  • ?header_callback ?(collections.abc.Callable) – 如果設(shè)置,header_callback 將在收到每個標(biāo)題行時運行(包括第一行,例如 HTTP/1.0 200 OK\r\n,最后一行僅包含 \r\ n. 所有行都包括尾隨的換行符)。 HTTPResponse.headers 在最終響應(yīng)中將為空。這與 streaming_callback 結(jié)合使用最有用,因為它是在請求進行時訪問表頭數(shù)據(jù)的唯一方法。?prepare_curl_callback ?(collections.abc.Callable) - 如果設(shè)置,將使用 pycurl.Curl 對象調(diào)用,以允許應(yīng)用程序進行額外的 setopt 調(diào)用。
  • ?proxy_host ?(str) -- HTTP 代理主機名。要使用代理,必須設(shè)置 proxy_host 和 proxy_port; proxy_username、proxy_pass 和 proxy_auth_mode 是可選的。當(dāng)前僅 curl_httpclient 支持代理。
  • ?proxy_port ?(int) – HTTP 代理端口
  • ?proxy_username ?(str) – HTTP 代理用戶名
  • ?proxy_password ?(str) – HTTP 代理密碼
  • ?proxy_auth_mode ?(str) – HTTP 代理認(rèn)證模式;默認(rèn)為“basic”。支持“basic”和“digest”
  • ?allow_nonstandard_methods ?(bool) – 允許方法參數(shù)的未知值?默認(rèn)為False。
  • ?validate_cert ?(bool) - 對于 HTTPS 請求,驗證服務(wù)器的證書?默認(rèn)為True。
  • ?ca_certs ?(str) – PEM 格式的 CA 證書的文件名,或者使用None默認(rèn)值。
  • ?client_key ?(str) -- 客戶端 SSL 密鑰的文件名(如果有)。
  • ?client_cert ?(str) -- 客戶端 SSL 證書的文件名(如果有)。
  • ?ssl_options ?(ssl.SSLContext) – 用于 simple_httpclient 的 ssl.SSLContext 對象(curl_httpclient 不支持)。覆蓋 validate_cert、ca_certs、client_key 和 client_cert。?allow_ipv6 ?(bool) – 可用時使用 IPv6?默認(rèn)為True。
  • ?expect_100_continue ?(bool) -- 如果為True,則發(fā)送 Expect: 100-continue 表頭并在發(fā)送請求正文之前等待 continue 響應(yīng)。僅支持 simple_httpclient。

注意:

使用 ?curl_httpclient時,某些選項可能會被后續(xù)提取繼承,因為 ?pycurl不允許它們被干凈地重置。 這適用于 ?ca_certs?、?client_key?、?client_cert ?和 ?network_interface參數(shù)。 如果您使用這些選項,您應(yīng)該在每個請求中傳遞它們(您不必總是使用相同的值,但不能將指定這些選項的請求與使用默認(rèn)值的請求混合)。

響應(yīng)對象

class tornado.httpclient.HTTPResponse(request: tornado.httpclient.HTTPRequest, code: int, headers: Optional[tornado.httputil.HTTPHeaders] = None, buffer: Optional[_io.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)

屬性:

?request?:HTTPRequest 對象

?code?:數(shù)字 HTTP 狀態(tài)代碼,例如 200 或 404

?reason?:描述人類可讀的狀態(tài)代碼的原因短語

?headers?:tornado.httputil.HTTPHeaders 對象

?Effective_url?:跟隨任何重定向后資源的最終位置

?buffer?:響應(yīng)主體的 cStringIO 對象

?body?:以字節(jié)的形式響應(yīng)正文(根據(jù)需要從 self.buffer 創(chuàng)建)

?error?:異常對象,如果有的話

?request_time?:從請求開始到結(jié)束的秒數(shù)。 包括從 DNS 解析到接收最后一個數(shù)據(jù)字節(jié)的所有網(wǎng)絡(luò)操作。 不包括在隊列中花費的時間(由于 max_clients 選項)。 如果遵循重定向,則僅包括最終請求。

?start_time?:HTTP 操作開始的時間,基于 time.time(不是 IOLoop.time 使用的單調(diào)時鐘)。 如果請求在隊列中超時,則可能為 None。

?time_info?:來自請求的診斷時間信息字典。 可用數(shù)據(jù)可能會發(fā)生變化,但目前使用 http://curl.haxx.se/libcurl/c/curl_easy_getinfo.html 提供的時間,加上隊列,這是等待 ?AsyncHTTPClient下的插槽時引入的延遲(如果有) ?max_clients設(shè)置。

5.1 新版功能:添加了 ?start_time屬性。

在 5.1 版更改: ?request_time屬性以前包括在 ?simple_httpclient隊列中花費的時間,但不包括在 ?curl_httpclient中。 現(xiàn)在,兩種實現(xiàn)都排除了排隊時間。 ?request_time現(xiàn)在比 ?curl_httpclient更準(zhǔn)確,因為它在可用時使用單調(diào)時鐘。

rethrow() → None

如果請求出現(xiàn)錯誤,則引發(fā) HTTPError。

例外

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

不成功的 HTTP 請求引發(fā)異常。

屬性:

?code?-HTTP錯誤整數(shù)錯誤代碼,例如404。當(dāng)沒有收到HTTP響應(yīng)時(例如超時),使用錯誤代碼599。

?response?-HTTPResponse對象(如果有)。

請注意,如果 ?follow_redirects為 False,則重定向變?yōu)?nbsp;HTTPErrors,您可以查看 ?error.response.headers['Location']? 以查看重定向的目的地。

在 5.1 版更改: 從 ?HTTPError重命名為 ?HTTPClientError以避免與 ?tornado.web.HTTPError? 沖突。 ?tornado.httpclient.HTTPError? 保留為別名。

exception 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

實現(xiàn)

class tornado.simple_httpclient.SimpleAsyncHTTPClient

沒有外部依賴的非阻塞 HTTP 客戶端。

這個類在 Tornado 的 IOStreams 之上實現(xiàn)了一個 HTTP 1.1 客戶端。 尚不支持基于 curl 的 AsyncHTTPClient 中的某些功能。 特別是不支持代理,不重用連接,調(diào)用者無法選擇要使用的網(wǎng)絡(luò)接口。

initialize(max_clients: int = 10, hostname_mapping: Optional[Dict[str, str]] = None, max_buffer_size: int = 104857600, resolver: Optional[tornado.netutil.Resolver] = None, defaults: Optional[Dict[str, Any]] = None, max_header_size: Optional[int] = None, max_body_size: Optional[int] = None) → None

創(chuàng)建一個 AsyncHTTPClient。

每個 IOLoop 僅存在一個 AsyncHTTPClient 實例,以限制掛起的連接數(shù)。 ?force_instance=True? 可用于抑制此行為。

請注意,由于這種隱式重用,除非使用 ?force_instance?,否則只有對構(gòu)造函數(shù)的第一次調(diào)用才會真正使用其參數(shù)。 建議使用 ?configure方法代替構(gòu)造函數(shù),以確保參數(shù)生效。

?max_clients是可以進行的并發(fā)請求數(shù); 當(dāng)達到此限制時,其他請求將排隊。 請注意,在此隊列中等待的時間仍然計入 ?request_timeout?。

?hostname_mapping是將主機名映射到 IP 地址的字典。 當(dāng)修改系統(tǒng)范圍的設(shè)置(如 ?/etc/hosts?)是不可能或不可取的(例如在單元測試中)時,它可用于進行本地 DNS 更改。

?max_buffer_size?(默認(rèn)100MB)是一次可以讀入內(nèi)存的字節(jié)數(shù)。 ?max_body_size?(默認(rèn)為 ?max_buffer_size?)是客戶端將接受的最大響應(yīng)正文。 如果沒有 ?streaming_callback?,則適用這兩個限制中的較小者; 使用 ?streaming_callback ?只有 ?max_body_size ?。

在 4.2 版更改: 添加了 ?max_body_size ?參數(shù)。


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號