Skip to content

扩展

¥Extensions

请求和响应扩展提供了一个可以添加附加信息的非类型空间。

¥Request and response extensions provide a untyped space where additional information may be added.

扩展应该用于那些并非所有传输都可用且不能完全适应的功能简化的请求/响应模型底层httpcore包使用作为其 API。

¥Extensions should be used for features that may not be available on all transports, and that do not fit neatly into the simplified request/response model that the underlying httpcore package uses as its API.

请求支持多种扩展:

¥Several extensions are supported on the request:

# Request timeouts actually implemented as an extension on
# the request, ensuring that they are passed throughout the
# entire call stack.
client = httpx.Client()
response = client.get(
    "https://www.example.com",
    extensions={"timeout": {"connect": 5.0}}
)
response.request.extensions["timeout"]
{"connect": 5.0}

回应如下:

¥And on the response:

client = httpx.Client()
response = client.get("https://www.example.com")
print(response.extensions["http_version"])  # b"HTTP/1.1"
# Other server responses could have been
# b"HTTP/0.9", b"HTTP/1.0", or b"HTTP/1.1"

请求扩展

¥Request Extensions

"trace"

¥"trace"

跟踪扩展允许安装回调处理程序来监视底层内部事件流httpcore运输。

¥The trace extension allows a callback handler to be installed to monitor the internal flow of events within the underlying httpcore transport.

解释这一点的最简单方法是举一个例子:

¥The simplest way to explain this is with an example:

import httpx

def log(event_name, info):
    print(event_name, info)

client = httpx.Client()
response = client.get("https://www.example.com/", extensions={"trace": log})
# connection.connect_tcp.started {'host': 'www.example.com', 'port': 443, 'local_address': None, 'timeout': None}
# connection.connect_tcp.complete {'return_value': <httpcore.backends.sync.SyncStream object at 0x1093f94d0>}
# connection.start_tls.started {'ssl_context': <ssl.SSLContext object at 0x1093ee750>, 'server_hostname': b'www.example.com', 'timeout': None}
# connection.start_tls.complete {'return_value': <httpcore.backends.sync.SyncStream object at 0x1093f9450>}
# http11.send_request_headers.started {'request': <Request [b'GET']>}
# http11.send_request_headers.complete {'return_value': None}
# http11.send_request_body.started {'request': <Request [b'GET']>}
# http11.send_request_body.complete {'return_value': None}
# http11.receive_response_headers.started {'request': <Request [b'GET']>}
# http11.receive_response_headers.complete {'return_value': (b'HTTP/1.1', 200, b'OK', [(b'Age', b'553715'), (b'Cache-Control', b'max-age=604800'), (b'Content-Type', b'text/html; charset=UTF-8'), (b'Date', b'Thu, 21 Oct 2021 17:08:42 GMT'), (b'Etag', b'"3147526947+ident"'), (b'Expires', b'Thu, 28 Oct 2021 17:08:42 GMT'), (b'Last-Modified', b'Thu, 17 Oct 2019 07:18:26 GMT'), (b'Server', b'ECS (nyb/1DCD)'), (b'Vary', b'Accept-Encoding'), (b'X-Cache', b'HIT'), (b'Content-Length', b'1256')])}
# http11.receive_response_body.started {'request': <Request [b'GET']>}
# http11.receive_response_body.complete {'return_value': None}
# http11.response_closed.started {}
# http11.response_closed.complete {'return_value': None}

event_nameinfo此处的参数将是以下之一:

¥The event_name and info arguments here will be one of the following:

  • {event_type}.{event_name}.started<dictionary of keyword arguments>

    ¥{event_type}.{event_name}.started, <dictionary of keyword arguments>

  • {event_type}.{event_name}.complete{"return_value": <...>}

    ¥{event_type}.{event_name}.complete, {"return_value": <...>}

  • {event_type}.{event_name}.failed{"exception": <...>}

    ¥{event_type}.{event_name}.failed, {"exception": <...>}

请注意,当使用异步代码时,传递给"trace"必须是async def ...功能。

¥Note that when using async code the handler function passed to "trace" must be an async def ... function.

当前显示的事件类型如下...

¥The following event types are currently exposed...

建立连接

¥Establishing the connection

  • "connection.connect_tcp"

    ¥"connection.connect_tcp"

  • "connection.connect_unix_socket"

    ¥"connection.connect_unix_socket"

  • "connection.start_tls"

    ¥"connection.start_tls"

HTTP/1.1 事件

¥HTTP/1.1 events

  • "http11.send_request_headers"

    ¥"http11.send_request_headers"

  • "http11.send_request_body"

    ¥"http11.send_request_body"

  • "http11.receive_response"

    ¥"http11.receive_response"

  • "http11.receive_response_body"

    ¥"http11.receive_response_body"

  • "http11.response_closed"

    ¥"http11.response_closed"

HTTP/2 事件

¥HTTP/2 events

  • "http2.send_connection_init"

    ¥"http2.send_connection_init"

  • "http2.send_request_headers"

    ¥"http2.send_request_headers"

  • "http2.send_request_body"

    ¥"http2.send_request_body"

  • "http2.receive_response_headers"

    ¥"http2.receive_response_headers"

  • "http2.receive_response_body"

    ¥"http2.receive_response_body"

  • "http2.response_closed"

    ¥"http2.response_closed"

确切的跟踪事件集可能会因不同版本的httpcore。如果您需要依赖一组特定的事件,建议您将包的安装固定到固定版本。

¥The exact set of trace events may be subject to change across different versions of httpcore. If you need to rely on a particular set of events it is recommended that you pin installation of the package to a fixed version.

"sni_hostname"

¥"sni_hostname"

服务器的主机名,用于确认 SSL 证书提供的主机名。

¥The server's hostname, which is used to confirm the hostname supplied by the SSL certificate.

如果您想连接到明确的 IP 地址而不是使用标准 DNS 主机名查找,那么您将需要使用此请求扩展。

¥If you want to connect to an explicit IP address rather than using the standard DNS hostname lookup, then you'll need to use this request extension.

例如:

¥For example:

# Connect to '185.199.108.153' but use 'www.encode.io' in the Host header,
# and use 'www.encode.io' when SSL verifying the server hostname.
client = httpx.Client()
headers = {"Host": "www.encode.io"}
extensions = {"sni_hostname": "www.encode.io"}
response = client.get(
    "https://185.199.108.153/path",
    headers=headers,
    extensions=extensions
)

"timeout"

¥"timeout"

一本词典str: Optional[float]超时值。

¥A dictionary of str: Optional[float] timeout values.

可能包括以下值'connect''read''write', 或者'pool'

¥May include values for 'connect', 'read', 'write', or 'pool'.

例如:

¥For example:

# Timeout if a connection takes more than 5 seconds to established, or if
# we are blocked waiting on the connection pool for more than 10 seconds.
client = httpx.Client()
response = client.get(
    "https://www.example.com",
    extensions={"timeout": {"connect": 5.0, "pool": 10.0}}
)

此扩展是如何httpx已实现超时,确保超时值与请求实例关联并在整个堆栈中传递。通常不应直接使用此扩展,而应使用更高级别的timeoutAPI。

¥This extension is how the httpx timeouts are implemented, ensuring that the timeout values are associated with the request instance and passed throughout the stack. You shouldn't typically be working with this extension directly, but use the higher level timeout API instead.

"target"

¥"target"

用作HTTP 目标而不是 URL 路径

¥The target that is used as the HTTP target instead of the URL path.

这使得构建原本不受支持的请求成为可能。

¥This enables support constructing requests that would otherwise be unsupported.

  • 应用了非标准转义的 URL 路径。

    ¥URL paths with non-standard escaping applied.

  • 使用绝对 URI 转发代理请求。

    ¥Forward proxy requests using an absolute URI.

  • 使用隧道代理请求CONNECT以主机名作为目标。

    ¥Tunneling proxy requests using CONNECT with hostname as the target.

  • 服务器范围OPTIONS *要求。

    ¥Server-wide OPTIONS * requests.

一些例子:

¥Some examples:

使用“目标”扩展发送没有标准路径转义规则的请求......

¥Using the 'target' extension to send requests without the standard path escaping rules...

# Typically a request to "https://www.example.com/test^path" would
# connect to "www.example.com" and send an HTTP/1.1 request like...
#
# GET /test%5Epath HTTP/1.1
#
# Using the target extension we can include the literal '^'...
#
# GET /test^path HTTP/1.1
#
# Note that requests must still be valid HTTP requests.
# For example including whitespace in the target will raise a `LocalProtocolError`.
extensions = {"target": b"/test^path"}
response = httpx.get("https://www.example.com", extensions=extensions)

target扩展还允许服务器范围OPTIONS *请求构建...

¥The target extension also allows server-wide OPTIONS * requests to be constructed...

# This will send the following request...
#
# CONNECT * HTTP/1.1
extensions = {"target": b"*"}
response = httpx.request("CONNECT", "https://www.example.com", extensions=extensions)

响应扩展

¥Response Extensions

"http_version"

¥"http_version"

HTTP 版本,以字节为单位。例如:b"HTTP/1.1"

¥The HTTP version, as bytes. Eg. b"HTTP/1.1".

当使用 HTTP/1.1 时,响应行包含一个明确的版本,并且该键的值可能是b"HTTP/0.9"b"HTTP/1.0", 或者b"HTTP/1.1"

¥When using HTTP/1.1 the response line includes an explicit version, and the value of this key could feasibly be one of b"HTTP/0.9", b"HTTP/1.0", or b"HTTP/1.1".

使用 HTTP/2 时,协议中不再包含响应​​版本控制,并且此键的值始终为b"HTTP/2"

¥When using HTTP/2 there is no further response versioning included in the protocol, and the value of this key will always be b"HTTP/2".

"reason_phrase"

¥"reason_phrase"

HTTP 响应的原因短语,以字节为单位。例如b"OK"。某些服务器可能包含自定义原因短语,尽管我们不建议这样做。

¥The reason-phrase of the HTTP response, as bytes. For example b"OK". Some servers may include a custom reason phrase, although this is not recommended.

HTTP/2 及更高版本不包含线路上的原因短语。

¥HTTP/2 onwards does not include a reason phrase on the wire.

当不包含任何键时,可以使用基于状态代码的默认值。

¥When no key is included, a default based on the status code may be used.

"stream_id"

¥"stream_id"

当使用 HTTP/2 时"stream_id"可以访问响应扩展来确定发送响应的数据流的 ID。

¥When HTTP/2 is being used the "stream_id" response extension can be accessed to determine the ID of the data stream that the response was sent on.

"network_stream"

¥"network_stream"

"network_stream"扩展允许开发人员处理 HTTPCONNECTUpgrade请求,通过提供超出标准请求/响应模型的 API,可以直接读取或写入网络。

¥The "network_stream" extension allows developers to handle HTTP CONNECT and Upgrade requests, by providing an API that steps outside the standard request/response model, and can directly read or write to the network.

网络流提供的接口:

¥The interface provided by the network stream:

  • read(max_bytes, timeout = None) -> bytes

    ¥read(max_bytes, timeout = None) -> bytes

  • write(buffer, timeout = None)

    ¥write(buffer, timeout = None)

  • close()

    ¥close()

  • start_tls(ssl_context, server_hostname = None, timeout = None) -> NetworkStream

    ¥start_tls(ssl_context, server_hostname = None, timeout = None) -> NetworkStream

  • get_extra_info(info) -> Any

    ¥get_extra_info(info) -> Any

此 API 可用作使用 HTTP 代理、WebSocket 升级和其他高级用例的基础。

¥This API can be used as the foundation for working with HTTP proxies, WebSocket upgrades, and other advanced use-cases.

查看网络后端文档有关直接使用网络流的更多信息。

¥See the network backends documentation for more information on working directly with network streams.

额外的网络信息

¥Extra network information

网络流抽象还允许访问底层套接字可能公开的各种低级信息:

¥The network stream abstraction also allows access to various low-level information that may be exposed by the underlying socket:

response = httpx.get("https://www.example.com")
network_stream = response.extensions["network_stream"]

client_addr = network_stream.get_extra_info("client_addr")
server_addr = network_stream.get_extra_info("server_addr")
print("Client address", client_addr)
print("Server address", server_addr)

套接字 SSL 信息也可以通过此接口获得,但您需要确保底层连接仍然打开,才能访问它......

¥The socket SSL information is also available through this interface, although you need to ensure that the underlying connection is still open, in order to access it...

with httpx.stream("GET", "https://www.example.com") as response:
    network_stream = response.extensions["network_stream"]

    ssl_object = network_stream.get_extra_info("ssl_object")
    print("TLS version", ssl_object.version())