Tornado 異步HTTP客戶端

2022-03-09 14:45 更新

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

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

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

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

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

要選擇 ?curl_httpclient?,請(qǐng)?jiān)趩?dòng)時(shí)調(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)用程序之間共享代碼。 運(yùn)行 ?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運(yùn)行時(shí)不再可能使用同步 ?HTTPClient。 請(qǐng)改用 ?AsyncHTTPClient?。

close() → None

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

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

執(zhí)行一個(gè)請(qǐng)求,返回一個(gè) HTTPResponse。

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

如果在獲取過(guò)程中發(fā)生錯(cuò)誤,我們會(huì)引發(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è)類的構(gòu)造函數(shù)在幾個(gè)方面很神奇:它實(shí)際上創(chuàng)建了一個(gè)特定于實(shí)現(xiàn)的子類的實(shí)例,并且實(shí)例被重用為一種偽單例(每個(gè) ?IOLoop ?一個(gè))。 關(guān)鍵字參數(shù) ?force_instance=True? 可用于抑制這種單例行為。 除非使用 ?force_instance=True?,否則不應(yīng)將任何參數(shù)傳遞給 ?AsyncHTTPClient構(gòu)造函數(shù)。 可以使用靜態(tài)方法 ?configure()? 設(shè)置實(shí)現(xiàn)子類及其構(gòu)造函數(shù)的參數(shù)

所有 ?AsyncHTTPClient實(shí)現(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 版以來(lái)已棄用)已被刪除。

close() → None

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

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

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

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

執(zhí)行一個(gè)請(qǐng)求,異步返回一個(gè) ?HTTPResponse?。

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

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

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

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

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

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

配置要使用的 ?AsyncHTTPClient子類。

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

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

例如:

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

請(qǐng)求對(duì)象

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 客戶端請(qǐng)求對(duì)象。

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

參數(shù):

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

注意:

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

響應(yīng)對(duì)象

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 對(duì)象

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

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

?headers?:tornado.httputil.HTTPHeaders 對(duì)象

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

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

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

?error?:異常對(duì)象,如果有的話

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

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

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

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

在 5.1 版更改: ?request_time屬性以前包括在 ?simple_httpclient隊(duì)列中花費(fèi)的時(shí)間,但不包括在 ?curl_httpclient中。 現(xiàn)在,兩種實(shí)現(xiàn)都排除了排隊(duì)時(shí)間。 ?request_time現(xiàn)在比 ?curl_httpclient更準(zhǔn)確,因?yàn)樗诳捎脮r(shí)使用單調(diào)時(shí)鐘。

rethrow() → None

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

例外

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

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

屬性:

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

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

請(qǐng)注意,如果 ?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 的別名

命令行界面

這個(gè)模塊提供了一個(gè)簡(jiǎn)單的命令行界面來(lái)使用 Tornado 的 HTTP 客戶端獲取一個(gè) 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

實(shí)現(xiàn)

class tornado.simple_httpclient.SimpleAsyncHTTPClient

沒(méi)有外部依賴的非阻塞 HTTP 客戶端。

這個(gè)類在 Tornado 的 IOStreams 之上實(shí)現(xiàn)了一個(gè) HTTP 1.1 客戶端。 尚不支持基于 curl 的 AsyncHTTPClient 中的某些功能。 特別是不支持代理,不重用連接,調(diào)用者無(wú)法選擇要使用的網(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)建一個(gè) AsyncHTTPClient。

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

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

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

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

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

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


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

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)