0
# Utilities
1
2
Extensive utility functions and data structures for HTTP dates, URI handling, async/sync conversion, file operations, introspection, and common web development tasks in Falcon applications.
3
4
## Capabilities
5
6
### HTTP Utility Functions
7
8
Utilities for working with HTTP dates, status codes, and web-related operations.
9
10
```python { .api }
11
def http_now() -> str:
12
"""
13
Get current time as HTTP date string.
14
15
Returns:
16
RFC 1123 formatted HTTP date string
17
"""
18
19
def http_date_to_dt(http_date: str) -> datetime:
20
"""
21
Convert HTTP date string to datetime object.
22
23
Args:
24
http_date: HTTP date string in RFC 1123 format
25
26
Returns:
27
Datetime object in UTC
28
"""
29
30
def dt_to_http(dt: datetime) -> str:
31
"""
32
Convert datetime object to HTTP date string.
33
34
Args:
35
dt: Datetime object (assumed UTC if no timezone)
36
37
Returns:
38
RFC 1123 formatted HTTP date string
39
"""
40
41
def secure_filename(filename: str) -> str:
42
"""
43
Sanitize filename for security by removing dangerous characters.
44
45
Args:
46
filename: Original filename
47
48
Returns:
49
Sanitized filename safe for filesystem use
50
"""
51
52
def code_to_http_status(status_code: int) -> str:
53
"""
54
Convert numeric status code to HTTP status line.
55
56
Args:
57
status_code: Numeric HTTP status code (e.g., 200)
58
59
Returns:
60
Full HTTP status line (e.g., '200 OK')
61
"""
62
63
def http_status_to_code(status_line: str) -> int:
64
"""
65
Extract status code from HTTP status line.
66
67
Args:
68
status_line: HTTP status line (e.g., '404 Not Found')
69
70
Returns:
71
Numeric status code (e.g., 404)
72
"""
73
74
def to_query_str(params: dict, comma_delimited_lists: bool = True, prefix: bool = True) -> str:
75
"""
76
Build query string from parameters dictionary.
77
78
Args:
79
params: Parameters dictionary
80
comma_delimited_lists: Use comma separation for list values
81
prefix: Include '?' prefix
82
83
Returns:
84
URL-encoded query string
85
"""
86
```
87
88
#### HTTP Utilities Usage
89
90
```python
91
import falcon
92
from datetime import datetime
93
94
# HTTP date handling
95
current_date = falcon.http_now()
96
# Returns: 'Wed, 07 Sep 2025 10:30:00 GMT'
97
98
# Parse HTTP date
99
dt = falcon.http_date_to_dt('Wed, 07 Sep 2025 10:30:00 GMT')
100
back_to_http = falcon.dt_to_http(dt)
101
102
# Secure filename handling
103
user_filename = "../../../etc/passwd"
104
safe_name = falcon.secure_filename(user_filename)
105
# Returns: 'etc_passwd'
106
107
# Status code conversion
108
status_line = falcon.code_to_http_status(404)
109
# Returns: '404 Not Found'
110
111
code = falcon.http_status_to_code('201 Created')
112
# Returns: 201
113
114
# Query string building
115
params = {'search': 'python', 'tags': ['web', 'api'], 'limit': 10}
116
query = falcon.to_query_str(params)
117
# Returns: '?search=python&tags=web,api&limit=10'
118
```
119
120
### Async/Sync Conversion Utilities
121
122
Functions for converting between synchronous and asynchronous code patterns.
123
124
```python { .api }
125
def async_to_sync(coroutine_func: callable) -> callable:
126
"""
127
Convert async function to synchronous function.
128
129
Args:
130
coroutine_func: Async function to convert
131
132
Returns:
133
Synchronous wrapper function
134
"""
135
136
def sync_to_async(sync_func: callable) -> callable:
137
"""
138
Convert synchronous function to async function.
139
140
Args:
141
sync_func: Synchronous function to convert
142
143
Returns:
144
Async wrapper function
145
"""
146
147
def create_task(coro: object) -> object:
148
"""
149
Create asyncio task from coroutine.
150
151
Args:
152
coro: Coroutine object
153
154
Returns:
155
Asyncio Task object
156
"""
157
158
def get_running_loop() -> object:
159
"""
160
Get currently running asyncio event loop.
161
162
Returns:
163
Current event loop or None
164
"""
165
166
def runs_sync(func: callable) -> bool:
167
"""
168
Check if function is synchronous.
169
170
Args:
171
func: Function to check
172
173
Returns:
174
True if function is synchronous, False if async
175
"""
176
177
def wrap_sync_to_async(func: callable) -> callable:
178
"""
179
Wrap synchronous function for async execution.
180
181
Args:
182
func: Synchronous function to wrap
183
184
Returns:
185
Async wrapper that executes func in thread pool
186
"""
187
188
def wrap_sync_to_async_unsafe(func: callable) -> callable:
189
"""
190
Wrap synchronous function for async execution without thread safety.
191
192
Args:
193
func: Synchronous function to wrap
194
195
Returns:
196
Async wrapper (use with caution)
197
"""
198
```
199
200
#### Async/Sync Conversion Usage
201
202
```python
203
import falcon
204
import asyncio
205
206
# Convert async function to sync
207
async def fetch_user_async(user_id):
208
# Async database call
209
return await db.get_user(user_id)
210
211
fetch_user_sync = falcon.async_to_sync(fetch_user_async)
212
user = fetch_user_sync(123) # Can be called synchronously
213
214
# Convert sync function to async
215
def compute_hash(data):
216
# CPU intensive synchronous operation
217
return hashlib.sha256(data).hexdigest()
218
219
compute_hash_async = falcon.sync_to_async(compute_hash)
220
hash_result = await compute_hash_async(b'data')
221
222
# Check if function is async
223
print(falcon.runs_sync(compute_hash)) # True
224
print(falcon.runs_sync(fetch_user_async)) # False
225
```
226
227
### Data Structures
228
229
Specialized data structures for web applications.
230
231
```python { .api }
232
class CaseInsensitiveDict(dict):
233
def __init__(self, data: dict = None):
234
"""
235
Case-insensitive dictionary (like HTTP headers).
236
237
Args:
238
data: Initial dictionary data
239
"""
240
241
def __getitem__(self, key: str) -> object:
242
"""Get item with case-insensitive key"""
243
244
def __setitem__(self, key: str, value: object):
245
"""Set item with case-insensitive key"""
246
247
def __contains__(self, key: str) -> bool:
248
"""Check if key exists (case-insensitive)"""
249
250
def get(self, key: str, default: object = None) -> object:
251
"""Get item with default fallback"""
252
253
class Context:
254
def __init__(self, **kwargs):
255
"""
256
Generic context container for request/response data.
257
258
Args:
259
**kwargs: Initial context data as keyword arguments
260
"""
261
262
def __getattr__(self, name: str) -> object:
263
"""Get context attribute"""
264
265
def __setattr__(self, name: str, value: object):
266
"""Set context attribute"""
267
268
def __contains__(self, name: str) -> bool:
269
"""Check if attribute exists"""
270
271
def get(self, name: str, default: object = None) -> object:
272
"""Get attribute with default fallback"""
273
274
class ETag:
275
def __init__(self, value: str, is_weak: bool = False):
276
"""
277
HTTP ETag representation.
278
279
Args:
280
value: ETag value
281
is_weak: Whether ETag is weak (W/ prefix)
282
"""
283
284
@property
285
def value(self) -> str:
286
"""ETag value without quotes"""
287
288
@property
289
def is_weak(self) -> bool:
290
"""Whether ETag is weak"""
291
292
def __str__(self) -> str:
293
"""Full ETag string representation"""
294
295
def __eq__(self, other: object) -> bool:
296
"""Compare ETags for equality"""
297
298
@classmethod
299
def from_str(cls, etag_str: str) -> 'ETag':
300
"""
301
Parse ETag from string.
302
303
Args:
304
etag_str: ETag string (e.g., '"abc123"' or 'W/"abc123"')
305
306
Returns:
307
ETag instance
308
"""
309
```
310
311
#### Data Structures Usage
312
313
```python
314
import falcon
315
316
# Case-insensitive dictionary (useful for headers)
317
headers = falcon.CaseInsensitiveDict({
318
'Content-Type': 'application/json',
319
'authorization': 'Bearer token123'
320
})
321
322
print(headers['content-type']) # 'application/json'
323
print(headers['AUTHORIZATION']) # 'Bearer token123'
324
print('content-length' in headers) # False
325
326
# Context for storing request data
327
class MyResource:
328
def on_get(self, req, resp):
329
# Store data in request context
330
req.context.user_id = 123
331
req.context.start_time = time.time()
332
333
# Access context data
334
if hasattr(req.context, 'user_id'):
335
user = get_user(req.context.user_id)
336
resp.media = user
337
338
# ETag handling
339
etag = falcon.ETag('abc123')
340
print(str(etag)) # '"abc123"'
341
342
weak_etag = falcon.ETag('def456', is_weak=True)
343
print(str(weak_etag)) # 'W/"def456"'
344
345
# Parse ETag from string
346
parsed = falcon.ETag.from_str('W/"xyz789"')
347
print(parsed.value) # 'xyz789'
348
print(parsed.is_weak) # True
349
```
350
351
### Stream Utilities
352
353
Utilities for handling streaming data and file operations.
354
355
```python { .api }
356
class BoundedStream:
357
def __init__(self, stream: object, content_length: int):
358
"""
359
Bounded stream wrapper that limits read operations.
360
361
Args:
362
stream: Underlying stream object
363
content_length: Maximum bytes to read
364
"""
365
366
def read(self, size: int = -1) -> bytes:
367
"""
368
Read data from stream with bounds checking.
369
370
Args:
371
size: Number of bytes to read (-1 for all remaining)
372
373
Returns:
374
Read bytes (up to content_length limit)
375
"""
376
377
def readline(self, size: int = -1) -> bytes:
378
"""Read line from stream with bounds checking"""
379
380
def readlines(self, hint: int = -1) -> list:
381
"""Read lines from stream with bounds checking"""
382
383
@property
384
def eof(self) -> bool:
385
"""Whether end of stream reached"""
386
387
class BufferedReader:
388
def __init__(self, stream: object, buffer_size: int = 8192):
389
"""
390
Efficient buffered reader for file-like objects.
391
392
Args:
393
stream: Stream to read from
394
buffer_size: Buffer size in bytes
395
"""
396
397
def read(self, size: int = -1) -> bytes:
398
"""Read with internal buffering for efficiency"""
399
400
def peek(self, size: int) -> bytes:
401
"""Peek at data without consuming it"""
402
```
403
404
### Introspection Utilities
405
406
Functions for code inspection and reflection.
407
408
```python { .api }
409
def get_argnames(func: callable) -> list:
410
"""
411
Get function argument names.
412
413
Args:
414
func: Function to inspect
415
416
Returns:
417
List of argument names
418
"""
419
420
def get_bound_method(obj: object, method_name: str) -> callable:
421
"""
422
Get bound method from object.
423
424
Args:
425
obj: Object instance
426
method_name: Method name to get
427
428
Returns:
429
Bound method or None if not found
430
"""
431
432
def is_python_func(func: callable) -> bool:
433
"""
434
Check if callable is a Python function.
435
436
Args:
437
func: Callable to check
438
439
Returns:
440
True if Python function, False otherwise
441
"""
442
```
443
444
### URI Utilities
445
446
URI encoding, decoding, and manipulation functions.
447
448
```python { .api }
449
# URI utilities (available as falcon.uri module)
450
def encode(uri: str, safe: str = '') -> str:
451
"""
452
Percent-encode URI string.
453
454
Args:
455
uri: URI string to encode
456
safe: Characters to not encode
457
458
Returns:
459
Percent-encoded URI
460
"""
461
462
def encode_check_escaped(uri: str, safe: str = '') -> str:
463
"""
464
Encode URI, preserving existing percent-encoding.
465
466
Args:
467
uri: URI string to encode
468
safe: Characters to not encode
469
470
Returns:
471
Encoded URI with existing encoding preserved
472
"""
473
474
def decode(encoded_uri: str, unquote_plus: bool = True) -> str:
475
"""
476
Decode percent-encoded URI string.
477
478
Args:
479
encoded_uri: Percent-encoded URI
480
unquote_plus: Whether to decode '+' as space
481
482
Returns:
483
Decoded URI string
484
"""
485
486
def encode_value(value: str) -> str:
487
"""
488
Encode single URI value (like query parameter).
489
490
Args:
491
value: Value to encode
492
493
Returns:
494
Percent-encoded value
495
"""
496
497
def decode_value(encoded_value: str, unquote_plus: bool = True) -> str:
498
"""
499
Decode single URI value.
500
501
Args:
502
encoded_value: Encoded value
503
unquote_plus: Whether to decode '+' as space
504
505
Returns:
506
Decoded value
507
"""
508
```
509
510
#### URI Utilities Usage
511
512
```python
513
import falcon.uri
514
515
# Encode URI components
516
encoded = falcon.uri.encode('hello world/path')
517
# Returns: 'hello%20world%2Fpath'
518
519
# Decode URI components
520
decoded = falcon.uri.decode('hello%20world%2Fpath')
521
# Returns: 'hello world/path'
522
523
# Encode query parameter value
524
param_value = falcon.uri.encode_value('user@example.com')
525
# Returns: 'user%40example.com'
526
527
# Safe encoding (preserve certain characters)
528
safe_encoded = falcon.uri.encode('/api/v1/users', safe='/')
529
# Returns: '/api/v1/users'
530
```
531
532
### Media Type Utilities
533
534
Functions for parsing and working with HTTP media types and headers.
535
536
```python { .api }
537
def parse_header(header_value: str) -> tuple:
538
"""
539
Parse HTTP header value with parameters.
540
541
Args:
542
header_value: HTTP header value string
543
544
Returns:
545
Tuple of (main_value, parameters_dict)
546
"""
547
```
548
549
#### Media Type Usage
550
551
```python
552
# Parse Content-Type header
553
content_type = 'application/json; charset=utf-8; boundary=something'
554
media_type, params = falcon.parse_header(content_type)
555
556
print(media_type) # 'application/json'
557
print(params) # {'charset': 'utf-8', 'boundary': 'something'}
558
```
559
560
### Time Utilities
561
562
Timezone and time-related utilities.
563
564
```python { .api }
565
class TimezoneGMT:
566
"""GMT timezone implementation for datetime objects."""
567
568
def utcoffset(self, dt: datetime) -> timedelta:
569
"""Return UTC offset (always 0 for GMT)"""
570
571
def dst(self, dt: datetime) -> timedelta:
572
"""Return DST offset (always 0 for GMT)"""
573
574
def tzname(self, dt: datetime) -> str:
575
"""Return timezone name ('GMT')"""
576
```
577
578
### Deprecation Utilities
579
580
Tools for marking deprecated functionality.
581
582
```python { .api }
583
def deprecated(instructions: str = None, is_property: bool = False) -> callable:
584
"""
585
Mark function or property as deprecated.
586
587
Args:
588
instructions: Deprecation message or migration instructions
589
is_property: Whether decorating a property
590
591
Returns:
592
Decorator that issues deprecation warnings
593
"""
594
```
595
596
#### Deprecation Usage
597
598
```python
599
import falcon
600
601
class MyResource:
602
@falcon.deprecated('Use new_method() instead')
603
def old_method(self):
604
"""This method is deprecated"""
605
return "old functionality"
606
607
def new_method(self):
608
"""New improved method"""
609
return "new functionality"
610
611
# Using deprecated method will issue warning
612
resource = MyResource()
613
result = resource.old_method() # Issues deprecation warning
614
```
615
616
## Types
617
618
```python { .api }
619
# HTTP utilities
620
http_now: callable
621
http_date_to_dt: callable
622
dt_to_http: callable
623
secure_filename: callable
624
code_to_http_status: callable
625
http_status_to_code: callable
626
to_query_str: callable
627
628
# Async/sync utilities
629
async_to_sync: callable
630
sync_to_async: callable
631
create_task: callable
632
get_running_loop: callable
633
runs_sync: callable
634
wrap_sync_to_async: callable
635
wrap_sync_to_async_unsafe: callable
636
637
# Data structures
638
CaseInsensitiveDict: type
639
Context: type
640
ETag: type
641
642
# Stream utilities
643
BoundedStream: type
644
BufferedReader: type
645
646
# Introspection utilities
647
get_argnames: callable
648
get_bound_method: callable
649
is_python_func: callable
650
651
# URI utilities (falcon.uri module)
652
encode: callable
653
encode_check_escaped: callable
654
decode: callable
655
encode_value: callable
656
decode_value: callable
657
658
# Media type utilities
659
parse_header: callable
660
661
# Time utilities
662
TimezoneGMT: type
663
664
# Deprecation utilities
665
deprecated: callable
666
```