httpx 自定义传输
HTTPX Client
也接受一个transport
参数。此参数允许您提供将用于执行请求实际发送的自定义transport
对象。
用法
对于某些高级配置,您可能需要直接实例化transport
类,并将其传递到client
实例。一个例子是local_address
的配置只能通过此低级 API 获得。
>>> import httpx
>>> transport = httpx.HTTPTransport(local_address="0.0.0.0")
>>> client = httpx.Client(transport=transport)
也可以通过此接口重试连接。
>>> import httpx
>>> transport = httpx.HTTPTransport(retries=1)
>>> client = httpx.Client(transport=transport)
类似地,直接实例化transport
提供了一个uds
选项,用于通过Unix域套接字进行连接,该套接字仅可通过此低级API进行连接:
>>> import httpx
>>> # Connect to the Docker API via a Unix Socket.
>>> transport = httpx.HTTPTransport(uds="/var/run/docker.sock")
>>> client = httpx.Client(transport=transport)
>>> response = client.get("http://docker/info")
>>> response.json()
{"ID": "...", "Containers": 4, "Images": 74, ...}
urllib3 transport
这个公共gist提供了一个使用优秀的urllib3库的transport
,并且可以与同步的Client
一起使用...
>>> import httpx
>>> from urllib3_transport import URLLib3Transport
>>> client = httpx.Client(transport=URLLib3Transport())
>>> client.get("https://example.org")
<Response [200 OK]>
编写自定义transport
transport
实例必须实现低级 transport
API,该API处理发送单个请求和返回响应。您应该创建httpx
的子类。您应该使用子类httpx.BaseTransport
来实现与Client
一起使用的transport
,或者使用子类httpx.AsyncBaseTransport
来实现与AsyncClient
一起使用的transport
。
在transport API
层,我们使用的是熟悉的Request
和Response
模型。
有关transport API
细节的更多详细信息,请参阅 handle_request
和 handle_async_request
文档字符串。
自定义transport
实现的完整示例如下:
import json
import httpx
class HelloWorldTransport(httpx.BaseTransport):
"""
A mock transport that always returns a JSON "Hello, world!" response.
"""
def handle_request(self, request):
message = {"text": "Hello, world!"}
content = json.dumps(message).encode("utf-8")
stream = httpx.ByteStream(content)
headers = [(b"content-type", b"application/json")]
return httpx.Response(200, headers=headers, stream=stream)
我们可以以相同的方式使用它:
>>> import httpx
>>> client = httpx.Client(transport=HelloWorldTransport())
>>> response = client.get("https://example.org/")
>>> response.json()
{"text": "Hello, world!"}
模拟transport
在测试期间,能够模拟transport
并返回预先确定的响应,而不是发出实际的网络请求,这通常很有用。
httpx.MockTransport
类接受一个处理程序函数,该函数可用于将请求映射到预先确定的响应上:
def handler(request):
return httpx.Response(200, json={"text": "Hello, world!"})
# Switch to a mock transport, if the TESTING environment variable is set.
if os.environ.get('TESTING', '').upper() == "TRUE":
transport = httpx.MockTransport(handler)
else:
transport = httpx.HTTPTransport()
client = httpx.Client(transport=transport)
对于更高级的用例,您可能需要查看第三方模拟库,例如RESPX或pytest-httpx库。
安装transport
您还可以针对给定的方案或域挂载transport,以控制传出请求应通过哪个transport进行路由,其样式与指定代理路由的样式相同。
import httpx
class HTTPSRedirectTransport(httpx.BaseTransport):
"""
A transport that always redirects to HTTPS.
"""
def handle_request(self, method, url, headers, stream, extensions):
scheme, host, port, path = url
if port is None:
location = b"https://%s%s" % (host, path)
else:
location = b"https://%s:%d%s" % (host, port, path)
stream = httpx.ByteStream(b"")
headers = [(b"location", location)]
extensions = {}
return 303, headers, stream, extensions
# A client where any `http` requests are always redirected to `https`
mounts = {'http://': HTTPSRedirectTransport()}
client = httpx.Client(mounts=mounts)
关于如何利用已安装的transport工具的其他一些草图...
正在禁用单个给定域上的 HTTP/2...
mounts = {
"all://": httpx.HTTPTransport(http2=True),
"all://*example.org": httpx.HTTPTransport()
}
client = httpx.Client(mounts=mounts)
模拟对给定域的请求:
# All requests to "example.org" should be mocked out.
# Other requests occur as usual.
def handler(request):
return httpx.Response(200, json={"text": "Hello, World!"})
mounts = {"all://example.org": httpx.MockTransport(handler)}
client = httpx.Client(mounts=mounts)
添加对自定义方案的支持:
# Support URLs like "file:///Users/sylvia_green/websites/new_client/index.html"
mounts = {"file://": FileSystemTransport()}
client = httpx.Client(mounts=mounts)
更多建议: