Skip to content

Commit 074cd25

Browse files
Document client block-usage and close() (#487)
* Document client context manager vs close() usage * Convert client snippets to use context-managed syntax
1 parent 7200717 commit 074cd25

File tree

5 files changed

+86
-55
lines changed

5 files changed

+86
-55
lines changed

docs/advanced.md

+67-37
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,36 @@ Using a Client instance to make requests will give you HTTP connection pooling,
66
will provide cookie persistence, and allows you to apply configuration across
77
all outgoing requests.
88

9-
A Client instance is equivalent to a Session instance in `requests`.
9+
!!! hint
10+
A Client instance is equivalent to a Session instance in `requests`.
11+
12+
### Usage
13+
14+
The recommended way to use a `Client` is as a context manager. This will ensure that connections are properly cleaned up when leaving the `with` block:
15+
16+
```python
17+
>>> with httpx.Client() as client:
18+
... r = client.get('https://example.com')
19+
...
20+
>>> r
21+
<Response [200 OK]>
22+
```
23+
24+
Alternatively, you can explicitly close the connection pool without block-usage using `.close()`:
1025

1126
```python
1227
>>> client = httpx.Client()
13-
>>> r = client.get('https://example.org/')
28+
>>> try:
29+
... r = client.get('https://example.com')
30+
... finally:
31+
... client.close()
32+
...
1433
>>> r
1534
<Response [200 OK]>
1635
```
1736

37+
Once you have a `Client`, you can use all the features documented in the [Quickstart](/quickstart) guide.
38+
1839
## Calling into Python Web Apps
1940

2041
You can configure an `httpx` client to call directly into a Python web
@@ -38,10 +59,10 @@ app = Flask(__name__)
3859
def hello():
3960
return "Hello World!"
4061

41-
client = httpx.Client(app=app)
42-
r = client.get('http://example/')
43-
assert r.status_code == 200
44-
assert r.text == "Hello World!"
62+
with httpx.Client(app=app) as client:
63+
r = client.get('http://example/')
64+
assert r.status_code == 200
65+
assert r.text == "Hello World!"
4566
```
4667

4768
For some more complex cases you might need to customize the WSGI or ASGI
@@ -56,7 +77,8 @@ For example:
5677
```python
5778
# Instantiate a client that makes WSGI requests with a client IP of "1.2.3.4".
5879
dispatch = httpx.dispatch.WSGIDispatch(app=app, remote_addr="1.2.3.4")
59-
client = httpx.Client(dispatch=dispatch)
80+
with httpx.Client(dispatch=dispatch) as client:
81+
...
6082
```
6183

6284
## Build Request
@@ -65,10 +87,12 @@ You can use `Client.build_request()` to build a request and
6587
make modifications before sending the request.
6688

6789
```python
68-
>>> client = httpx.Client()
69-
>>> req = client.build_request("OPTIONS", "https://example.com")
70-
>>> req.url.full_path = "*" # Build an 'OPTIONS *' request for CORS
71-
>>> client.send(r)
90+
>>> with httpx.Client() as client:
91+
... req = client.build_request("OPTIONS", "https://example.com")
92+
... req.url.full_path = "*" # Build an 'OPTIONS *' request for CORS
93+
... r = client.send(req)
94+
...
95+
>>> r
7296
<Response [200 OK]>
7397
```
7498

@@ -79,11 +103,11 @@ One can set the version of the HTTP protocol for the client in case you want to
79103
For example:
80104

81105
```python
82-
h11_client = httpx.Client(http_versions=["HTTP/1.1"])
83-
h11_response = h11_client.get("https://myserver.com")
106+
with httpx.Client(http_versions=["HTTP/1.1"]) as h11_client:
107+
h11_response = h11_client.get("https://myserver.com")
84108

85-
h2_client = httpx.Client(http_versions=["HTTP/2"])
86-
h2_response = h2_client.get("https://myserver.com")
109+
with httpx.Client(http_versions=["HTTP/2"]) as h2_client:
110+
h2_response = h2_client.get("https://myserver.com")
87111
```
88112

89113
## .netrc Support
@@ -126,24 +150,31 @@ For example to forward all HTTP traffic to `http://127.0.0.1:3080` and all HTTPS
126150
to `http://127.0.0.1:3081` your `proxies` config would look like this:
127151

128152
```python
129-
>>> client = httpx.Client(proxies={
130-
"http": "http://127.0.0.1:3080",
131-
"https": "http://127.0.0.1:3081"
132-
})
153+
>>> proxies = {
154+
... "http": "http://127.0.0.1:3080",
155+
... "https": "http://127.0.0.1:3081"
156+
... }
157+
>>> with httpx.Client(proxies=proxies) as client:
158+
... ...
133159
```
134160

135161
Proxies can be configured for a specific scheme and host, all schemes of a host,
136162
all hosts for a scheme, or for all requests. When determining which proxy configuration
137163
to use for a given request this same order is used.
138164

139165
```python
140-
>>> client = httpx.Client(proxies={
141-
"http://example.com": "...", # Host+Scheme
142-
"all://example.com": "...", # Host
143-
"http": "...", # Scheme
144-
"all": "...", # All
145-
})
146-
>>> client = httpx.Client(proxies="...") # Shortcut for 'all'
166+
>>> proxies = {
167+
... "http://example.com": "...", # Host+Scheme
168+
... "all://example.com": "...", # Host
169+
... "http": "...", # Scheme
170+
... "all": "...", # All
171+
... }
172+
>>> with httpx.Client(proxies=proxies) as client:
173+
... ...
174+
...
175+
>>> proxy = "..." # Shortcut for {'all': '...'}
176+
>>> with httpx.Client(proxies=proxy) as client:
177+
... ...
147178
```
148179

149180
!!! warning
@@ -162,10 +193,9 @@ proxy = httpx.HTTPProxy(
162193
proxy_url="https://127.0.0.1",
163194
proxy_mode=httpx.HTTPProxyMode.TUNNEL_ONLY
164195
)
165-
client = httpx.Client(proxies=proxy)
166-
167-
# This request will be tunneled instead of forwarded.
168-
client.get("http://example.com")
196+
with httpx.Client(proxies=proxy) as client:
197+
# This request will be tunneled instead of forwarded.
198+
r = client.get("http://example.com")
169199
```
170200

171201

@@ -190,15 +220,15 @@ You can set timeouts on two levels:
190220
httpx.get('http://example.com/api/v1/example', timeout=5)
191221

192222
# Or, with a client:
193-
client = httpx.Client()
194-
client.get("http://example.com/api/v1/example", timeout=5)
223+
with httpx.Client() as client:
224+
client.get("http://example.com/api/v1/example", timeout=5)
195225
```
196226

197227
- On a client instance, which results in the given `timeout` being used as a default for requests made with this client:
198228

199229
```python
200-
client = httpx.Client(timeout=5)
201-
client.get('http://example.com/api/v1/example')
230+
with httpx.Client(timeout=5) as client:
231+
client.get('http://example.com/api/v1/example')
202232
```
203233

204234
Besides, you can pass timeouts in two forms:
@@ -229,8 +259,8 @@ url = "http://example.com/api/v1/delay/10"
229259
httpx.get(url, timeout=None) # Times out after 5s
230260

231261

232-
client = httpx.Client(timeout=None)
233-
client.get(url) # Does not timeout, returns after 10s
262+
with httpx.Client(timeout=None) as client:
263+
client.get(url) # Does not timeout, returns after 10s
234264

235265

236266
timeout = httpx.TimeoutConfig(
@@ -239,4 +269,4 @@ timeout = httpx.TimeoutConfig(
239269
write_timeout=5
240270
)
241271
httpx.get(url, timeout=timeout) # Does not timeout, returns after 10s
242-
```
272+
```

docs/api.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@
2323
*An HTTP client, with connection pooling, HTTP/2, redirects, cookie persistence, etc.*
2424

2525
```python
26-
>>> client = httpx.Client()
27-
>>> response = client.get('https://example.org')
26+
>>> with httpx.Client() as client:
27+
... response = client.get('https://example.org')
2828
```
2929

3030
* `def __init__([auth], [params], [headers], [cookies], [verify], [cert], [timeout], [pool_limits], [max_redirects], [app], [dispatch])`

docs/compatibility.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ session = requests.Session(**kwargs)
2727
is equivalent to
2828

2929
```python
30-
client = httpx.Client(**kwargs)
30+
with httpx.Client(**kwargs) as client:
31+
...
3132
```
3233

3334
More detailed documentation and usage of `Client` can be found in [Advanced Usage](advanced.md).

docs/environment_variables.md

+6-6
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,10 @@ Example:
2626

2727
```python
2828
# test_script.py
29-
3029
import httpx
31-
client = httpx.Client()
32-
client.get("https://google.com")
30+
31+
with httpx.Client() as client:
32+
r = client.get("https://google.com")
3333
```
3434

3535
```console
@@ -64,10 +64,10 @@ Example:
6464

6565
```python
6666
# test_script.py
67-
6867
import httpx
69-
client = httpx.Client()
70-
client.get("https://google.com")
68+
69+
with httpx.Client() as client:
70+
r = client.get("https://google.com")
7171
```
7272

7373
```console

docs/parallel.md

+9-9
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,9 @@ control the authentication or dispatch behavior for all requests within the
4848
block.
4949

5050
```python
51-
>>> client = httpx.Client()
52-
>>> with client.parallel() as parallel:
53-
>>> ...
51+
>>> with httpx.Client() as client:
52+
... with client.parallel() as parallel:
53+
... ...
5454
```
5555

5656
## Async parallel requests
@@ -59,12 +59,12 @@ If you're working within an async framework, then you'll want to use a fully
5959
async API for making requests.
6060

6161
```python
62-
>>> client = httpx.AsyncClient()
63-
>>> async with client.parallel() as parallel:
64-
>>> pending_one = await parallel.get('https://example.com/1')
65-
>>> pending_two = await parallel.get('https://example.com/2')
66-
>>> response_one = await pending_one.get_response()
67-
>>> response_two = await pending_two.get_response()
62+
>>> async with httpx.AsyncClient() as client:
63+
... async with client.parallel() as parallel:
64+
... pending_one = await parallel.get('https://example.com/1')
65+
... pending_two = await parallel.get('https://example.com/2')
66+
... response_one = await pending_one.get_response()
67+
... response_two = await pending_two.get_response()
6868
```
6969

7070
See [the Async Client documentation](async.md) for more details.

0 commit comments

Comments
 (0)