tornado.httpclient — 异步 HTTP 客户端

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

此模块定义了两个实现 simple_httpclientcurl_httpclient 共享的通用接口。应用程序可以实例化其选择的实现类,也可以使用来自此模块的 AsyncHTTPClient 类,该类选择可以被 AsyncHTTPClient.configure 方法覆盖的实现。

默认实现是 simple_httpclient,预计这将满足大多数用户的需求。但是,某些应用程序可能希望出于以下原因切换到 curl_httpclient

  • curl_httpclient 具有 simple_httpclient 中没有的某些功能,包括对 HTTP 代理的支持以及使用指定网络接口的能力。

  • 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)[source]

阻塞 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[source]

关闭 HTTPClient,释放使用的任何资源。

fetch(request: Union[HTTPRequest, str], **kwargs: Any) HTTPResponse[source]

执行请求,返回一个 HTTPResponse

请求可以是字符串 URL 或 HTTPRequest 对象。如果是字符串,我们使用任何附加的 kwargs 构造一个 HTTPRequestHTTPRequest(request, **kwargs)

如果在获取过程中出现错误,我们将引发一个 HTTPError,除非 raise_error 关键字参数设置为 False。

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

非阻塞 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[source]

销毁此 HTTP 客户端,释放使用的任何文件描述符。

由于 AsyncHTTPClient 对象的透明重用方式,此方法在正常使用情况下不需要close() 通常仅在 IOLoop 也要关闭或在创建 AsyncHTTPClient 时使用了 force_instance=True 参数时才需要。

close() 之后,不能再对 AsyncHTTPClient 调用任何其他方法。

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

异步执行请求,返回一个 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[source]

配置要使用的 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 中的一个。body_producer 不支持 curl_httpclient。使用 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) – CA 证书的 PEM 格式文件名,或 None 以使用默认值。请参阅在 curl_httpclient 中使用时的说明。

  • client_key (str) – 客户端 SSL 密钥的文件名(如果有)。请参阅在 curl_httpclient 中使用时的说明。

  • client_cert (str) – 客户端 SSL 证书的文件名(如果有)。请参阅在 curl_httpclient 中使用时的说明。

  • ssl_options (ssl.SSLContext) – ssl.SSLContext 对象,用于 simple_httpclientcurl_httpclient 不支持)。覆盖 validate_certca_certsclient_keyclient_cert

  • allow_ipv6 (bool) – 在可用时使用 IPv6?默认值为 True。

  • expect_100_continue (bool) – 如果为真,则发送 Expect: 100-continue 标头,并在发送请求主体之前等待继续响应。仅在 simple_httpclient 中受支持。

注意

在使用 curl_httpclient 时,某些选项可能会被后续获取继承,因为 pycurl 不允许它们被干净地重置。这适用于 ca_certsclient_keyclient_certnetwork_interface 参数。如果您使用这些选项,则应在每个请求中都传递它们(您不必始终使用相同的值,但不能将指定这些选项的请求与使用默认值的请求混合使用)。

3.1 版新增: The auth_mode argument.

4.0 版新增: The body_producer and expect_100_continue arguments.

4.2 版新增: The ssl_options argument.

4.5 版新增: The proxy_auth_mode argument.

响应对象

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)[source]

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 中。现在,两种实现中都排除了排队时间。对于 curl_httpclientrequest_time 现在更准确,因为它在可用时使用单调时钟。

rethrow() None[source]

如果请求中存在错误,则引发 HTTPError

异常

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

为不成功的 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 仍然作为别名存在。

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

实现

class tornado.simple_httpclient.SimpleAsyncHTTPClient(force_instance: bool = False, **kwargs: Any)[source]

没有外部依赖的非阻塞 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 参数。

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

libcurl 基于的 HTTP 客户端。

此实现支持以下参数,这些参数可以传递给 configure() 以控制全局单例,或者当 force_instance=True 时传递给构造函数。

max_clients 是可以同时进行的请求数;当达到此限制时,额外的请求将被排队。

defaults 是一个字典,其中包含将在所有提交给此客户端的 HTTPRequest 对象上用作默认值的参数。

示例代码