事件钩子

HTTPX 允许你为客户端注册"事件钩子",这些钩子会在特定类型的事件发生时被调用。

当前支持两种事件钩子:

  • request - 在请求完全准备就绪后、但发送到网络之前调用。接收 request 实例作为参数。
  • response - 在从网络获取响应后、但返回给调用者之前调用。接收 response 实例作为参数。

这些钩子可用于实现客户端级别的功能,如日志记录、监控或追踪。

def log_request(request):
    print(f"请求事件钩子: {request.method} {request.url} - 等待响应")

def log_response(response):
    request = response.request
    print(f"响应事件钩子: {request.method} {request.url} - 状态码 {response.status_code}")

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

你也可以使用这些钩子来安装响应处理代码,例如以下示例创建了一个客户端实例,该实例会在 4xx 和 5xx 响应时始终抛出 httpx.HTTPStatusError

def raise_on_4xx_5xx(response):
    response.raise_for_status()

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

注意

响应事件钩子会在决定是否读取响应体之前被调用。

如果你需要在事件钩子中访问响应体,必须调用 response.read(),对于 AsyncClient 则需要调用 response.aread()

钩子也可以修改 requestresponse 对象。

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 属性来检查和修改已安装的钩子。

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

注意

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