0
# Request Response Models
1
2
Comprehensive objects for handling HTTP requests and responses with full data access, streaming support, content processing, and type safety. HTTP3 provides both synchronous and asynchronous versions of request and response models to support different programming patterns.
3
4
These models handle all aspects of HTTP communication including headers, cookies, content encoding/decoding, streaming, and provide convenient methods for common data access patterns.
5
6
## Capabilities
7
8
### Request Models
9
10
#### Synchronous Request
11
12
Represents an HTTP request with all necessary data and metadata.
13
14
```python { .api }
15
class Request:
16
def __init__(self, method, url, *, data=b"", params=None, headers=None):
17
"""
18
Create an HTTP request.
19
20
Parameters:
21
- method (str): HTTP method (GET, POST, etc.)
22
- url (URLTypes): Request URL
23
- data (RequestData): Request body data
24
- params (QueryParamTypes, optional): URL query parameters
25
- headers (HeaderTypes, optional): HTTP headers
26
"""
27
28
@property
29
def method(self) -> str:
30
"""HTTP method (GET, POST, PUT, etc.)."""
31
32
@property
33
def url(self) -> URL:
34
"""Request URL object."""
35
36
@property
37
def headers(self) -> Headers:
38
"""Request headers."""
39
40
@property
41
def content(self) -> bytes:
42
"""Request body content as bytes."""
43
44
def prepare(self):
45
"""Prepare the request for sending."""
46
```
47
48
#### Asynchronous Request
49
50
Asynchronous version of the Request class for non-blocking operations.
51
52
```python { .api }
53
class AsyncRequest:
54
def __init__(self, method, url, *, data=b"", params=None, headers=None):
55
"""
56
Create an async HTTP request.
57
58
Parameters: Same as Request.__init__()
59
"""
60
61
@property
62
def method(self) -> str:
63
"""HTTP method (GET, POST, PUT, etc.)."""
64
65
@property
66
def url(self) -> URL:
67
"""Request URL object."""
68
69
@property
70
def headers(self) -> Headers:
71
"""Request headers."""
72
73
async def content(self) -> bytes:
74
"""Request body content as bytes (async)."""
75
76
async def prepare(self):
77
"""Prepare the request for sending (async)."""
78
```
79
80
### Response Models
81
82
#### Synchronous Response
83
84
Represents an HTTP response with comprehensive data access and processing capabilities.
85
86
```python { .api }
87
class Response:
88
@property
89
def status_code(self) -> int:
90
"""HTTP status code (200, 404, etc.)."""
91
92
@property
93
def reason_phrase(self) -> str:
94
"""HTTP reason phrase (OK, Not Found, etc.)."""
95
96
@property
97
def protocol(self) -> str:
98
"""HTTP protocol version (HTTP/1.1, HTTP/2)."""
99
100
@property
101
def headers(self) -> Headers:
102
"""Response headers."""
103
104
@property
105
def cookies(self) -> Cookies:
106
"""Response cookies."""
107
108
@property
109
def url(self) -> URL:
110
"""Final URL (after redirects)."""
111
112
@property
113
def request(self) -> Request:
114
"""Original request object."""
115
116
@property
117
def content(self) -> bytes:
118
"""Response content as bytes."""
119
120
@property
121
def text(self) -> str:
122
"""Response content as decoded text."""
123
124
@property
125
def encoding(self) -> str:
126
"""Response content encoding."""
127
128
@property
129
def charset_encoding(self) -> str:
130
"""Character set encoding from headers."""
131
132
def json(self) -> typing.Any:
133
"""
134
Parse response content as JSON.
135
136
Returns:
137
Parsed JSON data
138
139
Raises:
140
json.JSONDecodeError: If content is not valid JSON
141
"""
142
143
def read(self) -> bytes:
144
"""
145
Read and return the response content.
146
147
Returns:
148
bytes: Complete response content
149
"""
150
151
def stream(self) -> typing.Iterator[bytes]:
152
"""
153
A byte-iterator over the decoded response content.
154
This allows handling of gzip, deflate, and brotli encoded responses.
155
156
Yields:
157
bytes: Content chunks
158
"""
159
160
def raise_for_status(self):
161
"""
162
Raise an HTTPError for bad HTTP status codes.
163
164
Raises:
165
HTTPError: If status code indicates an error (4xx or 5xx)
166
"""
167
168
@property
169
def is_error(self) -> bool:
170
"""True if status code indicates an error (4xx or 5xx)."""
171
172
@property
173
def is_redirect(self) -> bool:
174
"""True if status code indicates a redirect (3xx)."""
175
176
@property
177
def is_client_error(self) -> bool:
178
"""True if status code indicates a client error (4xx)."""
179
180
@property
181
def is_server_error(self) -> bool:
182
"""True if status code indicates a server error (5xx)."""
183
184
def close(self):
185
"""Close the response and release resources."""
186
```
187
188
#### Asynchronous Response
189
190
Asynchronous version of the Response class for non-blocking content processing.
191
192
```python { .api }
193
class AsyncResponse:
194
@property
195
def status_code(self) -> int:
196
"""HTTP status code (200, 404, etc.)."""
197
198
@property
199
def reason_phrase(self) -> str:
200
"""HTTP reason phrase (OK, Not Found, etc.)."""
201
202
@property
203
def protocol(self) -> str:
204
"""HTTP protocol version (HTTP/1.1, HTTP/2)."""
205
206
@property
207
def headers(self) -> Headers:
208
"""Response headers."""
209
210
@property
211
def cookies(self) -> Cookies:
212
"""Response cookies."""
213
214
@property
215
def url(self) -> URL:
216
"""Final URL (after redirects)."""
217
218
@property
219
def request(self) -> AsyncRequest:
220
"""Original request object."""
221
222
async def content(self) -> bytes:
223
"""Response content as bytes (async)."""
224
225
async def text(self) -> str:
226
"""Response content as decoded text (async)."""
227
228
@property
229
def encoding(self) -> str:
230
"""Response content encoding."""
231
232
@property
233
def charset_encoding(self) -> str:
234
"""Character set encoding from headers."""
235
236
async def json(self) -> typing.Any:
237
"""
238
Parse response content as JSON (async).
239
240
Returns:
241
Parsed JSON data
242
243
Raises:
244
json.JSONDecodeError: If content is not valid JSON
245
"""
246
247
async def stream(self) -> typing.AsyncIterator[bytes]:
248
"""
249
A byte-iterator over the decoded response content (async).
250
This allows handling of gzip, deflate, and brotli encoded responses.
251
252
Yields:
253
bytes: Content chunks
254
"""
255
256
def raise_for_status(self):
257
"""
258
Raise an HTTPError for bad HTTP status codes.
259
260
Raises:
261
HTTPError: If status code indicates an error (4xx or 5xx)
262
"""
263
264
@property
265
def is_error(self) -> bool:
266
"""True if status code indicates an error (4xx or 5xx)."""
267
268
@property
269
def is_redirect(self) -> bool:
270
"""True if status code indicates a redirect (3xx)."""
271
272
@property
273
def is_client_error(self) -> bool:
274
"""True if status code indicates a client error (4xx)."""
275
276
@property
277
def is_server_error(self) -> bool:
278
"""True if status code indicates a server error (5xx)."""
279
280
async def close(self):
281
"""Close the response and release resources (async)."""
282
```
283
284
### Content Types
285
286
#### Request Data Types
287
288
```python { .api }
289
# Synchronous request data
290
RequestData = Union[dict, str, bytes, Iterator[bytes]]
291
292
# Asynchronous request data
293
AsyncRequestData = Union[dict, str, bytes, AsyncIterator[bytes]]
294
295
# File upload types
296
RequestFiles = Dict[str, Union[
297
IO[AnyStr], # Simple file object
298
Tuple[str, IO[AnyStr]], # (filename, file)
299
Tuple[str, IO[AnyStr], str] # (filename, file, content_type)
300
]]
301
```
302
303
#### Response Content Types
304
305
```python { .api }
306
# Synchronous response content
307
ResponseContent = Union[bytes, Iterator[bytes]]
308
309
# Asynchronous response content
310
AsyncResponseContent = Union[bytes, AsyncIterator[bytes]]
311
```
312
313
## Usage Examples
314
315
### Basic Response Handling
316
317
```python
318
import http3
319
320
# Synchronous response handling
321
response = http3.get('https://api.example.com/users')
322
323
print(f"Status: {response.status_code} {response.reason_phrase}")
324
print(f"Protocol: {response.protocol}")
325
print(f"Content-Type: {response.headers['content-type']}")
326
327
# Handle different content types
328
if response.headers.get('content-type', '').startswith('application/json'):
329
data = response.json()
330
print(f"JSON data: {data}")
331
else:
332
text = response.text
333
print(f"Text content: {text}")
334
```
335
336
### Streaming Response Content
337
338
```python
339
import http3
340
341
# Stream large responses
342
response = http3.get('https://example.com/large-file.zip', stream=True)
343
344
with open('downloaded-file.zip', 'wb') as f:
345
for chunk in response.stream():
346
f.write(chunk)
347
348
response.close()
349
```
350
351
### Asynchronous Response Handling
352
353
```python
354
import http3
355
import asyncio
356
357
async def fetch_data():
358
async with http3.AsyncClient() as client:
359
response = await client.get('https://api.example.com/data')
360
361
# Async content access
362
content = await response.content()
363
text = await response.text()
364
data = await response.json()
365
366
# Async streaming
367
async for chunk in response.stream():
368
process_chunk(chunk)
369
370
return data
371
372
asyncio.run(fetch_data())
373
```
374
375
### Error Handling with Responses
376
377
```python
378
import http3
379
380
try:
381
response = http3.get('https://api.example.com/users')
382
383
# Check for HTTP errors
384
response.raise_for_status()
385
386
# Or check status manually
387
if response.is_error:
388
print(f"HTTP Error: {response.status_code}")
389
elif response.is_redirect:
390
print(f"Redirected to: {response.url}")
391
else:
392
data = response.json()
393
394
except http3.ProtocolError as e:
395
print(f"Protocol error: {e}")
396
except http3.DecodingError as e:
397
print(f"Content decoding error: {e}")
398
```
399
400
### Request Construction
401
402
```python
403
import http3
404
405
# Manual request construction
406
request = http3.Request(
407
'POST',
408
'https://api.example.com/users',
409
data=b'{"name": "John"}',
410
headers={'Content-Type': 'application/json'}
411
)
412
413
# Send with client
414
with http3.Client() as client:
415
response = client.send(request)
416
417
# Async request construction
418
async_request = http3.AsyncRequest(
419
'GET',
420
'https://api.example.com/users',
421
params={'limit': 10}
422
)
423
```
424
425
### Content Encoding and Decoding
426
427
```python
428
import http3
429
430
response = http3.get('https://api.example.com/data')
431
432
# Automatic encoding detection
433
print(f"Detected encoding: {response.encoding}")
434
print(f"Charset from headers: {response.charset_encoding}")
435
436
# Force specific encoding
437
response.encoding = 'utf-8'
438
text = response.text
439
440
# Handle binary content
441
if response.headers.get('content-type', '').startswith('application/octet-stream'):
442
binary_data = response.content
443
# Process binary data
444
```