阅读(1505) (0)

Tornado 异步HTTP客户端

2022-03-09 11:15:41 更新

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

该模块定义了一个由两个实现共享的公共接口,即​simple_httpclient​和​curl_httpclient​。应用程序可以直接实例化所选的实现类,也可以使用此模块中的​AsyncHTTPClient​类,该模块选择可以用​AsyncHTTPClient.configure​方法重写的实现。

默认实现是 ​simple_httpclient​,并且这将适合大多数用户的需求。 但是,某些应用程序可能希望切换到 ​curl_httpclient​,原因如下:

  • curl_httpclient​有一些 ​simple_httpclient中没有的特性,包括对 HTTP 代理的支持和使用指定网络接口的能力。
  • curl_httpclient​更可能与不太符合 HTTP 规范的站点或使用很少使用 HTTP 功能的站点兼容。
  • curl_httpclient​更快。

请注意,如果您使用 ​curl_httpclient​,强烈建议您使用最新版本的 ​libcurl ​和 ​pycurl​。 目前支持的libcurl最低版本是7.22.0,pycurl最低版本是7.18.2。 强烈建议您的 ​libcurl ​安装使用异步 DNS 解析器(threaded或 c-ares)构建,否则您可能会遇到请求超时的各种问题

要选择 ​curl_httpclient​,请在启动时调用 ​AsyncHTTPClient.configure​:

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

HTTP客户端接口

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

提供此接口是为了更轻松地在同步和异步应用程序之间共享代码。 运行 ​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) → tornado.httpclient.HTTPResponse

执行一个请求,返回一个 HTTPResponse。

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

如果在获取过程中发生错误,我们会引发 HTTPError,除非 ​raise_error关键字参数设置为 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)

这个类的构造函数在几个方面很神奇:它实际上创建了一个特定于实现的子类的实例,并且实例被重用为一种伪单例(每个 ​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) → Future[HTTPResponse]

执行一个请求,异步返回一个 ​HTTPResponse​。

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

此方法返回一个 ​Future​,其结果是一个 ​HTTPResponse​。默认情况下,如果请求返回非 200 响应代码,​Future ​将引发 ​HTTPError​(如果无法联系服务器,也可能引发其他错误)。相反,如果 ​raise_error设置为 False,则无论响应代码如何,都将始终返回响应。

如果给出回调,它将使用 ​HTTPResponse ​调用。在回调接口中,​HTTPError ​不会自动引发。相反,您必须检查响应的错误属性或调用其 ​rethrow方法。

在 6.0 版更改: 回调参数已删除。改用返回的 ​Future​。

raise_error=False​ 参数仅影响使用非 200 响应代码时引发的 HTTPError,而不是抑制所有错误。

classmethodconfigure(impl: Union[None, str, Type[tornado.util.Configurable]], **kwargs) → 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: 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之外的所有参数都是可选的。

参数:

  • url ​(str) -- 要获取的 URL
  • method ​(str) -- HTTP 方法,例如“GET”和“POST”
  • headers​(HTTPHeaders or dict)– 用于传递请求的附加 HTTP 表头
  • body ​(str or bytes) -- 字符串形式的 HTTP 请求正文(字节或 unicode;如果是 unicode,将使用 utf-8 编码)
  • body_producer ​(collections.abc.Callable) – 用于惰性/异步请求主体的可调用对象。它用一个参数调用,一个写函数,并且应该返回一个 Future。它应该在新数据可用时调用 write 函数。 write 函数返回一个可用于流控制的 Future。只能指定 body 和 body_producer 之一。 curl_httpclient 不支持 body_producer。使用 body_producer 时,建议在表头中传递 Content-Length,否则将使用分块编码,并且许多服务器不支持请求的分块编码。
  • auth_username​ (str) -- HTTP 身份验证的用户名
  • auth_password​ (str) – HTTP 身份验证的密码
  • auth_mode​ (str) -- 身份验证模式;默认为“基本”。允许的值是实现定义的; curl_httpclient 支持“basic”和“digest”; simple_httpclient 仅支持“基本”
  • connect_timeout​ (float) – 初始连接超时时间,默认 20 秒(0 表示无超时)
  • request_timeout​ (float) – 整个请求的超时时间,以秒为单位,默认 20 秒(0 表示没有超时)
  • if_modified_since​(datatime or float)– If-Modified-Since 表头的时间戳
  • follow_redirects​ (bool) – 应该自动跟随重定向还是返回 3xx 响应?默认为True。
  • max_redirects ​(int) -- follow_redirects 的限制,默认为 5。
  • user_agent ​(str) -- 作为 User-Agent 表头发送的字符串
  • decompress_response ​(bool) – 从服务器请求压缩响应并在下载后解压缩。默认为True。
  • use_gzip ​(bool) – 自 Tornado 4.0 以来已弃用的 decompress_response 的别名。
  • network_interface ​(str) -- 用于请求的网络接口或源 IP。
  • streaming_callback ​(collections.abc.Callable) – 如果设置,streaming_callback 将在收到每个数据块时运行,并且 HTTPResponse.body 和 HTTPResponse.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_host 和 proxy_port; proxy_username、proxy_pass 和 proxy_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) – 允许方法参数的未知值?默认为False。
  • validate_cert ​(bool) - 对于 HTTPS 请求,验证服务器的证书?默认为True。
  • ca_certs ​(str) – PEM 格式的 CA 证书的文件名,或者使用None默认值。
  • 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?默认为True。
  • expect_100_continue ​(bool) -- 如果为True,则发送 Expect: 100-continue 表头并在发送请求正文之前等待 continue 响应。仅支持 simple_httpclient。

注意:

使用 ​curl_httpclient时,某些选项可能会被后续提取继承,因为 ​pycurl不允许它们被干净地重置。 这适用于 ​ca_certs​、​client_key​、​client_cert ​和 ​network_interface参数。 如果您使用这些选项,您应该在每个请求中传递它们(您不必总是使用相同的值,但不能将指定这些选项的请求与使用默认值的请求混合)。

响应对象

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​:数字 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 提供的时间,加上队列,这是等待 ​AsyncHTTPClient下的插槽时引入的延迟(如果有) ​max_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[tornado.httpclient.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​ 保留为别名。

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

没有外部依赖的非阻塞 HTTP 客户端。

这个类在 Tornado 的 IOStreams 之上实现了一个 HTTP 1.1 客户端。 尚不支持基于 curl 的 AsyncHTTPClient 中的某些功能。 特别是不支持代理,不重用连接,调用者无法选择要使用的网络接口。

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

创建一个 AsyncHTTPClient。

每个 IOLoop 仅存在一个 AsyncHTTPClient 实例,以限制挂起的连接数。 ​force_instance=True​ 可用于抑制此行为。

请注意,由于这种隐式重用,除非使用 ​force_instance​,否则只有对构造函数的第一次调用才会真正使用其参数。 建议使用 ​configure方法代替构造函数,以确保参数生效。

max_clients是可以进行的并发请求数; 当达到此限制时,其他请求将排队。 请注意,在此队列中等待的时间仍然计入 ​request_timeout​。

hostname_mapping是将主机名映射到 IP 地址的字典。 当修改系统范围的设置(如 ​/etc/hosts​)是不可能或不可取的(例如在单元测试中)时,它可用于进行本地 DNS 更改。

max_buffer_size​(默认100MB)是一次可以读入内存的字节数。 ​max_body_size​(默认为 ​max_buffer_size​)是客户端将接受的最大响应正文。 如果没有 ​streaming_callback​,则适用这两个限制中的较小者; 使用 ​streaming_callback ​只有 ​max_body_size ​。

在 4.2 版更改: 添加了 ​max_body_size ​参数。