事件挂钩

¥Event Hooks

HTTPX 允许您向客户端注册“事件挂钩”,每次发生特定类型的事件时都会调用这些挂钩。

¥HTTPX allows you to register "event hooks" with the client, that are called every time a particular type of event takes place.

目前有两个事件挂钩:

¥There are currently two event hooks:

  • request- 在请求完全准备好之后,但在发送到网络之前调用。通过request实例。

    ¥request - Called after a request is fully prepared, but before it is sent to the network. Passed the request instance.

  • response- 在从网络获取响应之后、返回给调用者之前调用。传递response实例。

    ¥response - Called after the response has been fetched from the network, but before it is returned to the caller. Passed the response instance.

这些允许您安装客户端范围的功能,例如日志记录、监控或跟踪。

¥These allow you to install client-wide functionality such as logging, monitoring or tracing.

def log_request(request):
    print(f"Request event hook: {request.method} {request.url} - Waiting for response")

def log_response(response):
    request = response.request
    print(f"Response event hook: {request.method} {request.url} - Status {response.status_code}")

client = httpx.Client(event_hooks={'request': [log_request], 'response': [log_response]})

您还可以使用这些钩子来安装响应处理代码,例如此示例,它创建一个始终引发的客户端实例httpx.HTTPStatusError关于 4xx 和 5xx 响应。

¥You can also use these hooks to install response processing code, such as this example, which creates a client instance that always raises httpx.HTTPStatusError on 4xx and 5xx responses.

def raise_on_4xx_5xx(response):
    response.raise_for_status()

client = httpx.Client(event_hooks={'response': [raise_on_4xx_5xx]})

笔记

¥Note

在确定是否应该读取响应主体之前,会调用响应事件挂钩。

¥Response event hooks are called before determining if the response body should be read or not.

如果您需要访问事件钩子内的响应主体,则需要调用response.read(),或者对于 AsyncClients,response.aread()

¥If you need access to the response body inside an event hook, you'll need to call response.read(), or for AsyncClients, response.aread().

钩子也可以修改requestresponse对象。

¥The hooks are also allowed to modify request and response objects.

def add_timestamp(request):
    request.headers['x-request-timestamp'] = datetime.now(tz=datetime.utc).isoformat()

client = httpx.Client(event_hooks={'request': [add_timestamp]})

事件钩子必须始终设置为可调用列表,并且可以为每种类型的事件注册多个事件挂钩。

¥Event hooks must always be set as a list of callables, and you may register multiple event hooks for each type of event.

除了能够在实例化客户端时设置事件钩子之外,还有一个.event_hooks属性,允许您检查和修改已安装的钩子。

¥As well as being able to set event hooks on instantiating the client, there is also an .event_hooks property, that allows you to inspect and modify the installed hooks.

client = httpx.Client()
client.event_hooks['request'] = [log_request]
client.event_hooks['response'] = [log_response, raise_on_4xx_5xx]

笔记

¥Note

如果你正在使用 HTTPX 的异步支持,那么你需要注意注册到httpx.AsyncClient必须是异步函数,而不是普通函数。

¥If you are using HTTPX's async support, then you need to be aware that hooks registered with httpx.AsyncClient MUST be async functions, rather than plain functions.