0
# Synchronous HTTP Client
1
2
The `Client` class provides a synchronous HTTP client with connection pooling, cookie persistence, and configuration reuse across multiple requests. It's more efficient than top-level functions when making multiple requests.
3
4
## Overview
5
6
The client maintains connection pools, persistent cookies, and default configuration that applies to all requests. It's thread-safe and can be shared between threads.
7
8
## Capabilities
9
10
### Client Class
11
12
#### Constructor
13
14
```python { .api }
15
class Client:
16
def __init__(self, *, auth=None, params=None, headers=None, cookies=None, verify=True, cert=None, trust_env=True, http1=True, http2=False, proxy=None, mounts=None, timeout=DEFAULT_TIMEOUT_CONFIG, follow_redirects=False, limits=DEFAULT_LIMITS, max_redirects=DEFAULT_MAX_REDIRECTS, event_hooks=None, base_url="", transport=None, default_encoding="utf-8"):
17
"""
18
Initialize a synchronous HTTP client.
19
20
Args:
21
auth (Auth, optional): Default authentication for all requests
22
params (dict, optional): Default query parameters for all requests
23
headers (dict, optional): Default headers for all requests
24
cookies (dict, optional): Default cookies for all requests
25
verify (bool | str | SSLContext): SSL certificate verification (default: True)
26
cert (str | tuple, optional): Client certificate file path or (cert, key) tuple
27
http1 (bool): Enable HTTP/1.1 (default: True)
28
http2 (bool): Enable HTTP/2 (default: False)
29
proxy (str | Proxy, optional): Proxy URL or configuration
30
mounts (dict, optional): Mapping of URL prefixes to custom transports
31
timeout (Timeout): Default timeout configuration (default: 5.0s)
32
follow_redirects (bool): Default redirect behavior (default: False)
33
limits (Limits): Connection pool limits (default: max_connections=100, max_keepalive_connections=20)
34
max_redirects (int): Maximum number of redirect hops (default: 20)
35
event_hooks (dict, optional): Request/response event hooks
36
base_url (str): Base URL to prepend to relative URLs
37
transport (BaseTransport, optional): Custom transport implementation
38
trust_env (bool): Use environment variables for proxy/SSL config (default: True)
39
default_encoding (str | callable): Default text encoding for responses (default: "utf-8")
40
"""
41
```
42
43
#### Request Methods
44
45
```python { .api }
46
def get(
47
self,
48
url: URL | str,
49
*,
50
params: QueryParamTypes | None = None,
51
headers: HeaderTypes | None = None,
52
cookies: CookieTypes | None = None,
53
auth: AuthTypes | UseClientDefault = USE_CLIENT_DEFAULT,
54
follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT,
55
timeout: TimeoutTypes | UseClientDefault = USE_CLIENT_DEFAULT,
56
extensions: RequestExtensions | None = None,
57
) -> Response:
58
"""
59
Send a GET request.
60
61
Args:
62
url (str): URL for the request (can be relative to base_url)
63
params (dict, optional): Query parameters to append to URL
64
headers (dict, optional): HTTP headers (merged with client defaults)
65
cookies (dict, optional): Cookies (merged with client defaults)
66
auth (Auth | USE_CLIENT_DEFAULT): Authentication (overrides client default)
67
follow_redirects (bool | USE_CLIENT_DEFAULT): Redirect behavior (overrides client default)
68
timeout (Timeout | USE_CLIENT_DEFAULT): Timeout configuration (overrides client default)
69
extensions (dict, optional): Protocol extensions
70
71
Returns:
72
Response: HTTP response object
73
74
Raises:
75
RequestError: If the request fails
76
"""
77
78
def post(
79
self,
80
url: URL | str,
81
*,
82
content: RequestContent | None = None,
83
data: RequestData | None = None,
84
files: RequestFiles | None = None,
85
json: Any | None = None,
86
params: QueryParamTypes | None = None,
87
headers: HeaderTypes | None = None,
88
cookies: CookieTypes | None = None,
89
auth: AuthTypes | UseClientDefault = USE_CLIENT_DEFAULT,
90
follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT,
91
timeout: TimeoutTypes | UseClientDefault = USE_CLIENT_DEFAULT,
92
extensions: RequestExtensions | None = None,
93
) -> Response:
94
"""
95
Send a POST request.
96
97
Args:
98
url (str): URL for the request (can be relative to base_url)
99
content (bytes, optional): Raw bytes content for request body
100
data (dict, optional): Form data to send in request body
101
files (dict, optional): Files to upload
102
json (any, optional): JSON-serializable object for request body
103
params (dict, optional): Query parameters to append to URL
104
headers (dict, optional): HTTP headers (merged with client defaults)
105
cookies (dict, optional): Cookies (merged with client defaults)
106
auth (Auth | USE_CLIENT_DEFAULT): Authentication (overrides client default)
107
follow_redirects (bool | USE_CLIENT_DEFAULT): Redirect behavior (overrides client default)
108
timeout (Timeout | USE_CLIENT_DEFAULT): Timeout configuration (overrides client default)
109
extensions (dict, optional): Protocol extensions
110
111
Returns:
112
Response: HTTP response object
113
114
Raises:
115
RequestError: If the request fails
116
"""
117
118
def put(self, url, *, content=None, data=None, files=None, json=None, params=None, headers=None, cookies=None, auth=USE_CLIENT_DEFAULT, follow_redirects=USE_CLIENT_DEFAULT, timeout=USE_CLIENT_DEFAULT, extensions=None):
119
"""Send a PUT request. Same arguments as post()."""
120
121
def patch(self, url, *, content=None, data=None, files=None, json=None, params=None, headers=None, cookies=None, auth=USE_CLIENT_DEFAULT, follow_redirects=USE_CLIENT_DEFAULT, timeout=USE_CLIENT_DEFAULT, extensions=None):
122
"""Send a PATCH request. Same arguments as post()."""
123
124
def delete(self, url, *, params=None, headers=None, cookies=None, auth=USE_CLIENT_DEFAULT, follow_redirects=USE_CLIENT_DEFAULT, timeout=USE_CLIENT_DEFAULT, extensions=None):
125
"""Send a DELETE request. Same arguments as get()."""
126
127
def head(self, url, *, params=None, headers=None, cookies=None, auth=USE_CLIENT_DEFAULT, follow_redirects=USE_CLIENT_DEFAULT, timeout=USE_CLIENT_DEFAULT, extensions=None):
128
"""Send a HEAD request. Same arguments as get()."""
129
130
def options(self, url, *, params=None, headers=None, cookies=None, auth=USE_CLIENT_DEFAULT, follow_redirects=USE_CLIENT_DEFAULT, timeout=USE_CLIENT_DEFAULT, extensions=None):
131
"""Send an OPTIONS request. Same arguments as get()."""
132
133
def request(
134
self,
135
method: str,
136
url: URL | str,
137
*,
138
content: RequestContent | None = None,
139
data: RequestData | None = None,
140
files: RequestFiles | None = None,
141
json: Any | None = None,
142
params: QueryParamTypes | None = None,
143
headers: HeaderTypes | None = None,
144
cookies: CookieTypes | None = None,
145
auth: AuthTypes | UseClientDefault = USE_CLIENT_DEFAULT,
146
follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT,
147
timeout: TimeoutTypes | UseClientDefault = USE_CLIENT_DEFAULT,
148
extensions: RequestExtensions | None = None,
149
) -> Response:
150
"""
151
Send an HTTP request with specified method.
152
153
Args:
154
method (str): HTTP method (GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS)
155
url (str): URL for the request (can be relative to base_url)
156
content (bytes, optional): Raw bytes content for request body
157
data (dict, optional): Form data to send in request body
158
files (dict, optional): Files to upload
159
json (any, optional): JSON-serializable object for request body
160
params (dict, optional): Query parameters to append to URL
161
headers (dict, optional): HTTP headers (merged with client defaults)
162
cookies (dict, optional): Cookies (merged with client defaults)
163
auth (Auth | USE_CLIENT_DEFAULT): Authentication (overrides client default)
164
follow_redirects (bool | USE_CLIENT_DEFAULT): Redirect behavior (overrides client default)
165
timeout (Timeout | USE_CLIENT_DEFAULT): Timeout configuration (overrides client default)
166
extensions (dict, optional): Protocol extensions
167
168
Returns:
169
Response: HTTP response object
170
171
Raises:
172
RequestError: If the request fails
173
"""
174
```
175
176
#### Advanced Methods
177
178
```python { .api }
179
def send(
180
self,
181
request: Request,
182
*,
183
stream: bool = False,
184
auth: AuthTypes | UseClientDefault = USE_CLIENT_DEFAULT,
185
follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT,
186
timeout: TimeoutTypes | UseClientDefault = USE_CLIENT_DEFAULT,
187
) -> Response:
188
"""
189
Send a pre-built Request object.
190
191
Args:
192
request (Request): Request object to send
193
stream (bool): Whether to return a streaming response (default: False)
194
auth (Auth | USE_CLIENT_DEFAULT): Authentication (overrides client default)
195
follow_redirects (bool | USE_CLIENT_DEFAULT): Redirect behavior (overrides client default)
196
timeout (Timeout | USE_CLIENT_DEFAULT): Timeout configuration (overrides client default)
197
198
Returns:
199
Response: HTTP response object
200
201
Raises:
202
RequestError: If the request fails
203
"""
204
205
def build_request(self, method, url, *, content=None, data=None, files=None, json=None, params=None, headers=None, cookies=None):
206
"""
207
Build a Request object without sending it.
208
209
Args:
210
method (str): HTTP method
211
url (str): URL for the request
212
content (bytes, optional): Raw bytes content for request body
213
data (dict, optional): Form data to send in request body
214
files (dict, optional): Files to upload
215
json (any, optional): JSON-serializable object for request body
216
params (dict, optional): Query parameters to append to URL
217
headers (dict, optional): HTTP headers (merged with client defaults)
218
cookies (dict, optional): Cookies (merged with client defaults)
219
220
Returns:
221
Request: Prepared request object
222
"""
223
224
def stream(self, method, url, **kwargs):
225
"""
226
Stream a request response.
227
228
Args:
229
method (str): HTTP method
230
url (str): URL for the request
231
**kwargs: Same arguments as request() method
232
233
Returns:
234
Generator yielding Response: Context manager for streaming response
235
236
Usage:
237
with client.stream('GET', '/large-file') as response:
238
for chunk in response.iter_bytes():
239
process(chunk)
240
"""
241
242
def close(self):
243
"""
244
Close the client and release all connections.
245
246
Should be called when done with the client to ensure connections
247
are properly closed and resources are released.
248
"""
249
```
250
251
#### Context Manager Support
252
253
```python { .api }
254
def __enter__(self):
255
"""Enter context manager."""
256
return self
257
258
def __exit__(self, exc_type=None, exc_value=None, traceback=None):
259
"""Exit context manager and close client."""
260
self.close()
261
```
262
263
## Usage Examples
264
265
### Basic Client Usage
266
267
```python
268
import httpx
269
270
# Create and use client
271
client = httpx.Client()
272
try:
273
response = client.get('https://httpbin.org/get')
274
print(response.json())
275
finally:
276
client.close()
277
```
278
279
### Context Manager (Recommended)
280
281
```python
282
import httpx
283
284
with httpx.Client() as client:
285
response = client.get('https://httpbin.org/get')
286
print(response.json())
287
# Client automatically closed
288
```
289
290
### Client with Default Configuration
291
292
```python
293
import httpx
294
295
# Client with base URL and default headers
296
with httpx.Client(
297
base_url='https://api.example.com',
298
headers={'User-Agent': 'MyApp/1.0'},
299
timeout=10.0
300
) as client:
301
# Relative URLs are resolved against base_url
302
users = client.get('/users').json()
303
user = client.get('/users/123').json()
304
```
305
306
### Authentication and Cookies
307
308
```python
309
import httpx
310
311
auth = httpx.BasicAuth('username', 'password')
312
313
with httpx.Client(auth=auth) as client:
314
# All requests use authentication
315
response = client.get('https://example.com/protected')
316
317
# Cookies are automatically persisted
318
client.post('https://example.com/login', data={'user': 'me'})
319
profile = client.get('https://example.com/profile') # Uses login cookies
320
```
321
322
### HTTP/2 Support
323
324
```python
325
import httpx
326
327
with httpx.Client(http2=True) as client:
328
response = client.get('https://http2.example.com')
329
print(response.http_version) # "HTTP/2"
330
```
331
332
### Custom Timeouts and Limits
333
334
```python
335
import httpx
336
337
timeout = httpx.Timeout(10.0, connect=5.0)
338
limits = httpx.Limits(max_connections=50, max_keepalive_connections=10)
339
340
with httpx.Client(timeout=timeout, limits=limits) as client:
341
response = client.get('https://example.com')
342
```
343
344
### Proxy Support
345
346
```python
347
import httpx
348
349
# HTTP proxy
350
with httpx.Client(proxy='http://proxy.example.com:8080') as client:
351
response = client.get('https://example.com')
352
353
# SOCKS proxy
354
with httpx.Client(proxy='socks5://proxy.example.com:1080') as client:
355
response = client.get('https://example.com')
356
```
357
358
### Stream Large Responses
359
360
```python
361
import httpx
362
363
with httpx.Client() as client:
364
with client.stream('GET', 'https://example.com/large-file') as response:
365
for chunk in response.iter_bytes(chunk_size=1024):
366
# Process chunk without loading entire response into memory
367
process_chunk(chunk)
368
```
369
370
### Build and Send Requests
371
372
```python
373
import httpx
374
375
with httpx.Client() as client:
376
# Build request
377
request = client.build_request('POST', '/api/data', json={'key': 'value'})
378
379
# Inspect or modify request
380
print(request.headers)
381
382
# Send the request
383
response = client.send(request)
384
```
385
386
### Event Hooks
387
388
```python
389
import httpx
390
391
def log_request(request):
392
print(f"Request: {request.method} {request.url}")
393
394
def log_response(response):
395
print(f"Response: {response.status_code}")
396
397
with httpx.Client(event_hooks={'request': [log_request], 'response': [log_response]}) as client:
398
response = client.get('https://example.com')
399
```