HTTPX ?Client
?也接受一個?transport
?參數(shù)。此參數(shù)允許您提供將用于執(zhí)行請求實際發(fā)送的自定義?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域套接字進(jìn)行連接,該套接字僅可通過此低級API進(jìn)行連接:
>>> 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, ...}
這個公共gist提供了一個使用優(yōu)秀的urllib3庫的?transport
?,并且可以與同步的?Client
?一起使用...
>>> import httpx
>>> from urllib3_transport import URLLib3Transport
>>> client = httpx.Client(transport=URLLib3Transport())
>>> client.get("https://example.org")
<Response [200 OK]>
?transport
?實例必須實現(xiàn)低級 ?transport
?API,該API處理發(fā)送單個請求和返回響應(yīng)。您應(yīng)該創(chuàng)建?httpx
?的子類。您應(yīng)該使用子類?httpx.BaseTransport
?來實現(xiàn)與?Client
?一起使用的?transport
?,或者使用子類?httpx.AsyncBaseTransport
?來實現(xiàn)與?AsyncClient
?一起使用的?transport
?。
在?transport API
?層,我們使用的是熟悉的?Request
?和?Response
?模型。
有關(guān)?transport API
?細(xì)節(jié)的更多詳細(xì)信息,請參閱 ?handle_request
?和 ?handle_async_request
?文檔字符串。
自定義?transport
?實現(xiàn)的完整示例如下:
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
?并返回預(yù)先確定的響應(yīng),而不是發(fā)出實際的網(wǎng)絡(luò)請求,這通常很有用。
?httpx.MockTransport
?類接受一個處理程序函數(shù),該函數(shù)可用于將請求映射到預(yù)先確定的響應(yīng)上:
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,以控制傳出請求應(yīng)通過哪個transport進(jìn)行路由,其樣式與指定代理路由的樣式相同。
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)
關(guān)于如何利用已安裝的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)
更多建議: