0
# Request and Response Handling
1
2
Comprehensive HTTP request and response objects that provide extensive properties and methods for accessing headers, parameters, media content, and managing response data.
3
4
## Capabilities
5
6
### Request Object
7
8
Represents an HTTP request with comprehensive access to all request data including headers, parameters, body content, and metadata.
9
10
```python { .api }
11
class Request:
12
def __init__(self, env: dict, options: RequestOptions = None):
13
"""
14
Create a Request object from WSGI environment.
15
16
Args:
17
env: WSGI environment dictionary
18
options: Request processing options
19
"""
20
21
# Core Properties
22
method: str # HTTP method (GET, POST, etc.)
23
uri: str # Full request URI
24
relative_uri: str # URI relative to app
25
forwarded_uri: str # URI from Forwarded header
26
scheme: str # URI scheme (http/https)
27
forwarded_scheme: str # Scheme from Forwarded header
28
host: str # Host header value
29
forwarded_host: str # Host from Forwarded header
30
path: str # URI path component
31
query_string: str # Query string
32
headers: dict # Case-insensitive headers dict
33
params: dict # Query parameters dict
34
cookies: dict # Request cookies
35
content_length: int # Content-Length header value
36
content_type: str # Content-Type header value
37
media: object # Parsed request body (JSON, form data, etc.)
38
bounded_stream: object # Raw request body stream
39
context: object # User data storage
40
41
# Accept header properties
42
accept: str # Accept header value
43
accept_charset: str # Accept-Charset header
44
accept_encoding: str # Accept-Encoding header
45
accept_language: str # Accept-Language header
46
47
# Conditional request headers
48
date: datetime # Date header as datetime
49
if_match: str # If-Match header value
50
if_none_match: str # If-None-Match header value
51
if_modified_since: datetime # If-Modified-Since as datetime
52
if_unmodified_since: datetime # If-Unmodified-Since as datetime
53
if_range: str # If-Range header value
54
55
# Range request properties
56
range: tuple # Range header as (start, end) tuple
57
range_unit: str # Range unit (usually 'bytes')
58
59
# Forwarded header information
60
forwarded: list # Parsed Forwarded headers
61
62
# Authentication
63
auth: str # Authorization header value
64
65
# Client information
66
user_agent: str # User-Agent header
67
referer: str # Referer header
68
remote_addr: str # Client IP address
69
70
# Methods
71
def get_header(self, name: str, default: str = None) -> str:
72
"""
73
Get header value by name.
74
75
Args:
76
name: Header name (case-insensitive)
77
default: Default value if header not found
78
79
Returns:
80
Header value or default
81
"""
82
83
def get_param(self, name: str, default: str = None) -> str:
84
"""
85
Get query parameter value by name.
86
87
Args:
88
name: Parameter name
89
default: Default value if parameter not found
90
91
Returns:
92
Parameter value or default
93
"""
94
95
def get_param_as_bool(self, name: str, default: bool = None) -> bool:
96
"""Get query parameter as boolean value."""
97
98
def get_param_as_int(self, name: str, default: int = None) -> int:
99
"""Get query parameter as integer value."""
100
101
def get_param_as_float(self, name: str, default: float = None) -> float:
102
"""Get query parameter as float value."""
103
104
def get_param_as_date(self, name: str, format_string: str = '%Y-%m-%d', default: datetime = None) -> datetime:
105
"""Get query parameter as date value."""
106
107
def get_param_as_list(self, name: str, transform: callable = None, default: list = None) -> list:
108
"""Get query parameter as list of values."""
109
110
def client_accepts_json(self) -> bool:
111
"""Check if client accepts JSON responses."""
112
113
def client_accepts_msgpack(self) -> bool:
114
"""Check if client accepts MessagePack responses."""
115
116
def client_accepts_xml(self) -> bool:
117
"""Check if client accepts XML responses."""
118
119
def client_prefers(self, media_types: list) -> str:
120
"""
121
Determine client's preferred media type from a list.
122
123
Args:
124
media_types: List of media types to choose from
125
126
Returns:
127
Preferred media type or None
128
"""
129
```
130
131
#### Request Usage Example
132
133
```python
134
class UserResource:
135
def on_get(self, req, resp):
136
# Access request properties
137
user_id = req.get_param('user_id')
138
page = req.get_param_as_int('page', default=1)
139
include_deleted = req.get_param_as_bool('include_deleted', default=False)
140
141
# Check headers
142
api_key = req.get_header('X-API-Key')
143
if not api_key:
144
raise falcon.HTTPUnauthorized(title='API key required')
145
146
# Content negotiation
147
if req.client_accepts_json():
148
resp.content_type = falcon.MEDIA_JSON
149
elif req.client_accepts_xml():
150
resp.content_type = falcon.MEDIA_XML
151
152
# Use context for request-scoped data
153
req.context.current_user = authenticate_user(api_key)
154
155
resp.media = {'users': get_users(page, include_deleted)}
156
157
def on_post(self, req, resp):
158
# Access parsed request body
159
user_data = req.media
160
161
# Validate content type
162
if req.content_type != falcon.MEDIA_JSON:
163
raise falcon.HTTPUnsupportedMediaType(
164
description='This endpoint only accepts JSON'
165
)
166
167
# Create user
168
new_user = create_user(user_data)
169
resp.status = falcon.HTTP_201
170
resp.media = new_user
171
```
172
173
### Response Object
174
175
Represents an HTTP response with methods for setting headers, status codes, body content, and managing output data.
176
177
```python { .api }
178
class Response:
179
def __init__(self, options: ResponseOptions = None):
180
"""
181
Create a Response object.
182
183
Args:
184
options: Response processing options
185
"""
186
187
# Core Properties
188
status: str # HTTP status line
189
status_code: int # HTTP status code as integer
190
headers: dict # Response headers dict
191
data: bytes # Raw response body bytes
192
media: object # Structured response data (auto-serialized)
193
text: str # Response body as text
194
content_type: str # Content-Type header value
195
content_length: int # Content-Length header value
196
context: object # User data storage
197
198
# Caching headers
199
cache_control: list # Cache-Control directives
200
etag: str # ETag header value
201
last_modified: datetime # Last-Modified as datetime
202
expires: datetime # Expires as datetime
203
vary: list # Vary header values
204
205
# Methods
206
def set_header(self, name: str, value: str):
207
"""
208
Set response header.
209
210
Args:
211
name: Header name
212
value: Header value
213
"""
214
215
def append_header(self, name: str, value: str):
216
"""
217
Append value to response header.
218
219
Args:
220
name: Header name
221
value: Value to append
222
"""
223
224
def get_header(self, name: str, default: str = None) -> str:
225
"""
226
Get response header value.
227
228
Args:
229
name: Header name
230
default: Default if not found
231
232
Returns:
233
Header value or default
234
"""
235
236
def delete_header(self, name: str):
237
"""
238
Delete response header.
239
240
Args:
241
name: Header name to delete
242
"""
243
244
def set_cookie(
245
self,
246
name: str,
247
value: str,
248
expires: datetime = None,
249
max_age: int = None,
250
domain: str = None,
251
path: str = None,
252
secure: bool = None,
253
http_only: bool = None,
254
same_site: str = None
255
):
256
"""
257
Set response cookie.
258
259
Args:
260
name: Cookie name
261
value: Cookie value
262
expires: Expiration datetime
263
max_age: Max age in seconds
264
domain: Cookie domain
265
path: Cookie path
266
secure: Secure flag
267
http_only: HttpOnly flag
268
same_site: SameSite attribute
269
"""
270
271
def unset_cookie(self, name: str, domain: str = None, path: str = None):
272
"""
273
Unset/delete a cookie.
274
275
Args:
276
name: Cookie name
277
domain: Cookie domain
278
path: Cookie path
279
"""
280
281
def set_stream(self, stream: object, content_length: int, content_type: str = None):
282
"""
283
Set streaming response body.
284
285
Args:
286
stream: File-like object or iterable
287
content_length: Content length in bytes
288
content_type: Content type
289
"""
290
291
def render_body(self) -> bytes:
292
"""
293
Render response body to bytes.
294
295
Returns:
296
Response body as bytes
297
"""
298
299
def append_link(self, target: str, rel: str, title: str = None, **kwargs):
300
"""
301
Add Link header for resource relationships.
302
303
Args:
304
target: Link target URI
305
rel: Link relationship
306
title: Optional link title
307
**kwargs: Additional link parameters
308
"""
309
```
310
311
#### Response Usage Example
312
313
```python
314
class FileResource:
315
def on_get(self, req, resp, file_id):
316
# Get file info
317
file_info = get_file_info(file_id)
318
if not file_info:
319
raise falcon.HTTPNotFound()
320
321
# Set response headers
322
resp.status = falcon.HTTP_200
323
resp.content_type = file_info['content_type']
324
resp.set_header('X-File-Size', str(file_info['size']))
325
326
# Set caching headers
327
resp.etag = file_info['etag']
328
resp.last_modified = file_info['modified_date']
329
resp.cache_control = ['public', 'max-age=3600']
330
331
# Handle conditional requests
332
if req.if_none_match == resp.etag:
333
resp.status = falcon.HTTP_304
334
return
335
336
# Stream file content
337
file_stream = open_file(file_id)
338
resp.set_stream(file_stream, file_info['size'])
339
340
class APIResource:
341
def on_post(self, req, resp):
342
# Process data
343
result = process_data(req.media)
344
345
# Set structured response
346
resp.status = falcon.HTTP_201
347
resp.media = {
348
'success': True,
349
'data': result,
350
'timestamp': datetime.utcnow().isoformat()
351
}
352
353
# Add custom headers
354
resp.set_header('X-Processing-Time', '150ms')
355
resp.append_link('/api/status', 'status')
356
357
# Set cookie
358
resp.set_cookie(
359
'session_id',
360
'abc123',
361
secure=True,
362
http_only=True,
363
same_site='Strict'
364
)
365
```
366
367
### ASGI Request and Response
368
369
Specialized request and response classes for ASGI applications with async support.
370
371
```python { .api }
372
class falcon.asgi.Request(Request):
373
"""
374
ASGI Request class with async-specific features.
375
Inherits all methods and properties from WSGI Request.
376
"""
377
378
async def get_media(self) -> object:
379
"""
380
Asynchronously parse request media.
381
382
Returns:
383
Parsed request body
384
"""
385
386
async def bounded_stream(self) -> object:
387
"""
388
Get async stream for request body.
389
390
Returns:
391
Async stream object
392
"""
393
394
class falcon.asgi.Response(Response):
395
"""
396
ASGI Response class with async-specific features.
397
Inherits all methods and properties from WSGI Response.
398
"""
399
400
async def render_body(self) -> bytes:
401
"""
402
Asynchronously render response body.
403
404
Returns:
405
Response body as bytes
406
"""
407
```
408
409
### Forwarded Header Support
410
411
Support for RFC 7239 Forwarded headers and proxy information.
412
413
```python { .api }
414
class Forwarded:
415
def __init__(self, forwarded_header: str):
416
"""
417
Parse Forwarded header.
418
419
Args:
420
forwarded_header: Raw Forwarded header value
421
"""
422
423
# Properties
424
src: str # Source IP address
425
host: str # Host value
426
proto: str # Protocol (http/https)
427
for_: str # For parameter value
428
429
# Class methods
430
@classmethod
431
def parse(cls, forwarded_header: str) -> list:
432
"""
433
Parse Forwarded header into list of Forwarded objects.
434
435
Args:
436
forwarded_header: Raw header value
437
438
Returns:
439
List of Forwarded objects
440
"""
441
```
442
443
## Types
444
445
```python { .api }
446
# Main request/response types
447
Request: type # WSGI request class
448
Response: type # WSGI response class
449
falcon.asgi.Request: type # ASGI request class
450
falcon.asgi.Response: type # ASGI response class
451
452
# Configuration types
453
RequestOptions: type # Request configuration
454
ResponseOptions: type # Response configuration
455
456
# Support types
457
Forwarded: type # Forwarded header parser
458
```