事件钩子
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()
。
钩子也可以修改 request
和 response
对象。
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
的钩子必须是异步函数,而不是普通函数。