...
```
+Similarly, if you are implementing a scheme that requires access to the response body, then use the `requires_response_body` property. You will then be able to access response body properties and methods such as `response.content`, `response.text`, `response.json()`, etc.
+
+```python
+class MyCustomAuth(httpx.Auth):
+ requires_response_body = True
+
+ def __init__(self, access_token, refresh_token, refresh_url):
+ self.access_token = access_token
+ self.refresh_token = refresh_token
+ self.refresh_url = refresh_url
+
+ def auth_flow(self, request):
+ request.headers["X-Authentication"] = self.access_token
+ response = yield request
+
+ if response.status_code == 401:
+ # If the server issues a 401 response, then issue a request to
+ # refresh tokens, and resend the request.
+ refresh_response = yield self.build_refresh_request()
+ self.update_tokens(refresh_response)
+
+ request.headers["X-Authentication"] = self.access_token
+ yield request
+
+ def build_refresh_request(self):
+ # Return an `httpx.Request` for refreshing tokens.
+ ...
+
+ def update_tokens(self, response):
+ # Update the `.access_token` and `.refresh_token` tokens
+ # based on a refresh response.
+ data = response.json()
+ ...
+```
+
## SSL certificates
When making a request over HTTPS, HTTPX needs to verify the identity of the requested host. To do this, it uses a bundle of SSL certificates (a.k.a. CA bundle) delivered by a trusted certificate authority (CA).
"""
requires_request_body = False
+ requires_response_body = False
def auth_flow(self, request: Request) -> typing.Generator[Request, Response, None]:
"""
request = next(auth_flow)
while True:
response = self.send_single_request(request, timeout)
+ if auth.requires_response_body:
+ response.read()
try:
next_request = auth_flow.send(response)
except StopIteration:
request = next(auth_flow)
while True:
response = await self.send_single_request(request, timeout)
+ if auth.requires_response_body:
+ await response.aread()
try:
next_request = auth_flow.send(response)
except StopIteration:
with pytest.raises(RequestBodyUnavailable):
await client.post(url, data=streaming_body(), auth=auth)
+
+
+@pytest.mark.asyncio
+async def test_auth_reads_response_body() -> None:
+ """
+ Test that we can read the response body in an auth flow if `requires_response_body`
+ is set.
+ """
+
+ class ResponseBodyAuth(Auth):
+ """
+ A mock authentication scheme that requires clients to send an 'Authorization'
+ header, then send back the contents of the response in the 'Authorization'
+ header.
+ """
+
+ requires_response_body = True
+
+ def __init__(self, token):
+ self.token = token
+
+ def auth_flow(
+ self, request: Request
+ ) -> typing.Generator[Request, Response, None]:
+ request.headers["Authorization"] = self.token
+ response = yield request
+ data = response.text
+ request.headers["Authorization"] = data
+ yield request
+
+ url = "https://example.org/"
+ auth = ResponseBodyAuth("xyz")
+ client = AsyncClient(dispatch=MockDispatch())
+
+ response = await client.get(url, auth=auth)
+ assert response.status_code == 200
+ assert response.json() == {"auth": '{"auth": "xyz"}'}