0
# Core Application Framework
1
2
Central application management, modular blueprint system, and configuration handling for building scalable async web applications with Flask-compatible APIs.
3
4
## Capabilities
5
6
### Main Application Class
7
8
The central `Quart` class handles HTTP and WebSocket requests, manages routing, and provides the foundation for async web applications.
9
10
```python { .api }
11
import asyncio
12
from typing import Any, Callable, Iterable
13
from quart.blueprints import Blueprint
14
from quart.wrappers import Response
15
16
class Quart:
17
def __init__(
18
self,
19
import_name: str,
20
static_url_path: str | None = None,
21
static_folder: str | None = "static",
22
static_host: str | None = None,
23
host_matching: bool = False,
24
subdomain_matching: bool = False,
25
template_folder: str | None = "templates",
26
instance_path: str | None = None,
27
instance_relative_config: bool = False,
28
root_path: str | None = None
29
):
30
"""
31
Initialize a Quart application.
32
33
Args:
34
import_name: The name of the application package
35
static_url_path: URL path for static files
36
static_folder: Folder containing static files
37
static_host: Host for static files
38
host_matching: Enable host matching for routes
39
subdomain_matching: Enable subdomain matching
40
template_folder: Folder containing templates
41
instance_path: Alternative instance path
42
instance_relative_config: Load config relative to instance path
43
root_path: Application root path
44
"""
45
46
def route(
47
self,
48
rule: str,
49
*,
50
methods: Iterable[str] | None = None,
51
host: str | None = None,
52
subdomain: str | None = None,
53
strict_slashes: bool | None = None,
54
merge_slashes: bool | None = None,
55
redirect_to: str | Callable[..., str] | None = None,
56
alias: bool = False,
57
endpoint: str | None = None,
58
defaults: dict[str, Any] | None = None,
59
**options: Any
60
) -> Callable[[Callable], Callable]:
61
"""
62
Decorator to register HTTP route handlers.
63
64
This is the most fundamental Flask method for defining HTTP routes.
65
The decorated function will be called when a request matches the route pattern.
66
67
Args:
68
rule: URL rule pattern (e.g., '/users/<int:id>')
69
methods: HTTP methods this route accepts (defaults to ['GET'])
70
host: Full host name for this route (cannot be used with subdomain)
71
subdomain: Subdomain for this specific route
72
strict_slashes: Strictly match trailing slashes in the path
73
merge_slashes: Merge consecutive slashes in the path
74
redirect_to: Redirect rule for this endpoint
75
alias: Whether this is an alias for another endpoint
76
endpoint: Custom endpoint name (defaults to function name)
77
defaults: Default values for URL variables
78
**options: Additional route options
79
80
Returns:
81
Decorated function that handles the route
82
83
Example:
84
@app.route('/users/<int:user_id>', methods=['GET', 'POST'])
85
async def user_profile(user_id):
86
return f'User {user_id}'
87
"""
88
89
def websocket(self, rule: str, **options):
90
"""
91
Decorator to register WebSocket handlers.
92
93
Args:
94
rule: WebSocket URL rule pattern
95
**options: Additional WebSocket options
96
"""
97
98
def add_url_rule(
99
self,
100
rule: str,
101
endpoint: str | None = None,
102
view_func: Callable | None = None,
103
*,
104
methods: Iterable[str] | None = None,
105
host: str | None = None,
106
subdomain: str | None = None,
107
strict_slashes: bool | None = None,
108
merge_slashes: bool | None = None,
109
redirect_to: str | Callable[..., str] | None = None,
110
alias: bool = False,
111
defaults: dict[str, Any] | None = None,
112
websocket: bool = False,
113
**options: Any
114
) -> None:
115
"""
116
Core method for programmatically adding routes.
117
118
This is the underlying method used by the @route decorator and other routing
119
utilities. It provides the most control over route registration.
120
121
Args:
122
rule: URL rule pattern (e.g., '/api/users/<int:id>')
123
endpoint: Endpoint name for URL generation (defaults to view_func.__name__)
124
view_func: Function to call for this route
125
methods: HTTP methods this route accepts
126
host: Full host name for this route (cannot be used with subdomain)
127
subdomain: Subdomain for this specific route
128
strict_slashes: Strictly match trailing slashes in the path
129
merge_slashes: Merge consecutive slashes in the path
130
redirect_to: Redirect rule for this endpoint
131
alias: Whether this is an alias for another endpoint
132
defaults: Default values for URL variables
133
websocket: Whether this is a WebSocket route
134
**options: Additional route configuration options
135
136
Example:
137
app.add_url_rule('/api/health', 'health_check', health_handler, methods=['GET'])
138
"""
139
140
def add_websocket(
141
self,
142
rule: str,
143
endpoint: str | None = None,
144
view_func: Callable | None = None,
145
**options
146
):
147
"""Add WebSocket route programmatically."""
148
149
def before_serving(self, func: Callable):
150
"""Decorator for functions to run before serving starts."""
151
152
def after_serving(self, func: Callable):
153
"""Decorator for functions to run after serving ends."""
154
155
def while_serving(self, func: Callable):
156
"""Decorator for startup/shutdown generator functions."""
157
158
def register_blueprint(
159
self,
160
blueprint: Blueprint,
161
*,
162
url_prefix: str | None = None,
163
subdomain: str | None = None,
164
url_defaults: dict[str, Any] | None = None,
165
**options: Any
166
) -> None:
167
"""
168
Register a Blueprint with the application.
169
170
Essential for modular app organization. Blueprints allow you to organize
171
your application into reusable components with their own routes, templates,
172
and static files.
173
174
Args:
175
blueprint: The Blueprint instance to register
176
url_prefix: URL prefix for all blueprint routes (overrides blueprint default)
177
subdomain: Subdomain for all blueprint routes (overrides blueprint default)
178
url_defaults: Default values for URL variables in blueprint routes
179
**options: Additional registration options
180
181
Example:
182
from myapp.auth import auth_bp
183
app.register_blueprint(auth_bp, url_prefix='/auth')
184
"""
185
186
def before_request(
187
self,
188
func: Callable[[], Any | Awaitable[Any]]
189
) -> Callable[[], Any | Awaitable[Any]]:
190
"""
191
Decorator for pre-request hooks.
192
193
Functions decorated with this will be called before processing each HTTP request.
194
If a before_request function returns a non-None value, it will be used as the
195
response instead of calling the view function.
196
197
Args:
198
func: Function to call before each request
199
200
Returns:
201
The decorated function
202
203
Example:
204
@app.before_request
205
async def load_user():
206
g.user = await get_current_user()
207
208
@app.before_request
209
async def check_auth():
210
if not session.get('authenticated'):
211
return redirect('/login')
212
"""
213
214
def after_request(
215
self,
216
func: Callable[[Response], Response | Awaitable[Response]]
217
) -> Callable[[Response], Response | Awaitable[Response]]:
218
"""
219
Decorator for post-request hooks.
220
221
Functions decorated with this will be called after each HTTP request is processed.
222
The function receives the response object and must return a (possibly modified)
223
response object.
224
225
Args:
226
func: Function to call after each request, receives response object
227
228
Returns:
229
The decorated function
230
231
Example:
232
@app.after_request
233
async def add_security_headers(response):
234
response.headers['X-Content-Type-Options'] = 'nosniff'
235
return response
236
237
@app.after_request
238
async def log_response(response):
239
app.logger.info(f'Response status: {response.status_code}')
240
return response
241
"""
242
243
def before_websocket(self, func: Callable):
244
"""Decorator for functions to run before WebSocket connections."""
245
246
def after_websocket(self, func: Callable):
247
"""Decorator for functions to run after WebSocket connections."""
248
249
def teardown_request(self, func: Callable):
250
"""Decorator for request teardown functions."""
251
252
def teardown_websocket(self, func: Callable):
253
"""Decorator for WebSocket teardown functions."""
254
255
def teardown_appcontext(self, func: Callable):
256
"""Decorator for app context teardown functions."""
257
258
def errorhandler(
259
self,
260
code_or_exception: int | type[Exception] | Exception
261
) -> Callable[[Callable], Callable]:
262
"""
263
Decorator for handling HTTP errors and exceptions.
264
265
Register functions to handle specific HTTP error codes or exception types.
266
Error handlers can return custom responses for different error conditions.
267
268
Args:
269
code_or_exception: HTTP status code (e.g., 404, 500) or exception class/instance
270
271
Returns:
272
Decorated function that handles the error
273
274
Example:
275
@app.errorhandler(404)
276
async def not_found(error):
277
return 'Page not found', 404
278
279
@app.errorhandler(ValueError)
280
async def handle_value_error(error):
281
return f'Invalid value: {error}', 400
282
"""
283
284
def url_for(
285
self,
286
endpoint: str,
287
*,
288
_anchor: str | None = None,
289
_external: bool | None = None,
290
_method: str | None = None,
291
_scheme: str | None = None,
292
**values: Any,
293
) -> str:
294
"""
295
Generate URLs for endpoints.
296
297
This is most useful in templates and redirects to create a URL
298
that can be used in the browser.
299
300
Args:
301
endpoint: The endpoint to build a url for, if prefixed with
302
'.' it targets endpoint's in the current blueprint.
303
_anchor: Additional anchor text to append (i.e. #text).
304
_external: Return an absolute url for external (to app) usage.
305
_method: The method to consider alongside the endpoint.
306
_scheme: A specific scheme to use.
307
**values: The values to build into the URL, as specified in
308
the endpoint rule.
309
310
Returns:
311
Generated URL string
312
313
Example:
314
url_for('user_profile', user_id=123)
315
url_for('api.get_user', user_id=123, _external=True)
316
"""
317
318
def run(
319
self,
320
host: str | None = None,
321
port: int | None = None,
322
debug: bool | None = None,
323
use_reloader: bool = True,
324
loop: asyncio.AbstractEventLoop | None = None,
325
ca_certs: str | None = None,
326
certfile: str | None = None,
327
keyfile: str | None = None,
328
**kwargs: Any,
329
) -> None:
330
"""
331
Run this application.
332
333
This is best used for development only, see Hypercorn for
334
production servers.
335
336
Args:
337
host: Hostname to listen on. By default this is loopback
338
only, use 0.0.0.0 to have the server listen externally.
339
port: Port number to listen on.
340
debug: If set enable (or disable) debug mode and debug output.
341
use_reloader: Automatically reload on code changes.
342
loop: Asyncio loop to create the server in, if None, take default one.
343
ca_certs: Path to the SSL CA certificate file.
344
certfile: Path to the SSL certificate file.
345
keyfile: Path to the SSL key file.
346
**kwargs: Additional arguments
347
"""
348
349
async def run_task(
350
self,
351
host: str = "127.0.0.1",
352
port: int = 5000,
353
debug: bool | None = None,
354
**kwargs
355
):
356
"""Return coroutine for running the application."""
357
358
def test_client(self, **kwargs):
359
"""Create test client instance."""
360
361
def test_cli_runner(self, **kwargs):
362
"""Create CLI test runner."""
363
364
def app_context(self):
365
"""Create application context."""
366
367
def request_context(self, request):
368
"""Create request context."""
369
370
def websocket_context(self, websocket):
371
"""Create WebSocket context."""
372
373
def test_request_context(self, path: str = "/", **kwargs):
374
"""Create test request context."""
375
376
def add_background_task(self, func: Callable, *args, **kwargs):
377
"""Add background task to be executed."""
378
379
async def make_response(self, result):
380
"""Create response from various inputs."""
381
382
def ensure_async(self, func: Callable):
383
"""Ensure function is async."""
384
385
def sync_to_async(self, func: Callable):
386
"""Convert sync function to async."""
387
388
# Key attributes
389
config: Config
390
debug: bool
391
testing: bool
392
secret_key: str | bytes | None
393
permanent_session_lifetime: timedelta
394
jinja_env: Environment
395
url_map: Map
396
view_functions: dict[str, Callable]
397
```
398
399
### Blueprint System
400
401
Modular application organization with Flask-compatible blueprint API for creating reusable application components.
402
403
```python { .api }
404
class Blueprint:
405
def __init__(
406
self,
407
name: str,
408
import_name: str,
409
static_folder: str | None = None,
410
static_url_path: str | None = None,
411
template_folder: str | None = None,
412
url_prefix: str | None = None,
413
subdomain: str | None = None,
414
url_defaults: dict | None = None,
415
root_path: str | None = None,
416
cli_group: str | None = None
417
):
418
"""
419
Initialize a blueprint for modular application organization.
420
421
Args:
422
name: Blueprint name
423
import_name: Blueprint package name
424
static_folder: Static files folder
425
static_url_path: URL path for static files
426
template_folder: Template folder
427
url_prefix: URL prefix for all routes
428
subdomain: Subdomain for all routes
429
url_defaults: Default values for URL variables
430
root_path: Blueprint root path
431
cli_group: CLI command group name
432
"""
433
434
def route(self, rule: str, **options):
435
"""Register routes on blueprint."""
436
437
def websocket(self, rule: str, **options):
438
"""Register WebSocket handlers on blueprint."""
439
440
def before_request(self, func: Callable):
441
"""Pre-request functions for blueprint."""
442
443
def after_request(self, func: Callable):
444
"""Post-request functions for blueprint."""
445
446
def before_websocket(self, func: Callable):
447
"""Pre-WebSocket functions for blueprint."""
448
449
def after_websocket(self, func: Callable):
450
"""Post-WebSocket functions for blueprint."""
451
452
def before_app_request(self, func: Callable):
453
"""Add pre-request function to app."""
454
455
def after_app_request(self, func: Callable):
456
"""Add post-request function to app."""
457
458
def before_app_serving(self, func: Callable):
459
"""Add pre-serving function to app."""
460
461
def after_app_serving(self, func: Callable):
462
"""Add post-serving function to app."""
463
464
def teardown_request(self, func: Callable):
465
"""Blueprint-specific teardown."""
466
467
def teardown_websocket(self, func: Callable):
468
"""WebSocket-specific teardown."""
469
470
def errorhandler(self, code_or_exception):
471
"""Blueprint error handlers."""
472
473
def register(self, app: Quart, options: dict):
474
"""Register blueprint with app."""
475
```
476
477
### Configuration Management
478
479
Flask-compatible configuration system with Quart-specific enhancements for environment variables and structured configuration.
480
481
```python { .api }
482
class Config(dict):
483
def from_envvar(self, variable_name: str, silent: bool = False) -> bool:
484
"""
485
Load config from environment variable pointing to config file.
486
487
Args:
488
variable_name: Environment variable name
489
silent: Don't raise error if variable doesn't exist
490
491
Returns:
492
True if config was loaded successfully
493
"""
494
495
def from_pyfile(self, filename: str, silent: bool = False) -> bool:
496
"""
497
Load config from Python file.
498
499
Args:
500
filename: Path to Python config file
501
silent: Don't raise error if file doesn't exist
502
503
Returns:
504
True if config was loaded successfully
505
"""
506
507
def from_object(self, obj):
508
"""
509
Load config from object (module, class, or object).
510
511
Args:
512
obj: Object containing configuration variables
513
"""
514
515
def from_prefixed_env(
516
self,
517
prefix: str = "QUART",
518
*,
519
loads: Callable = json.loads
520
):
521
"""
522
Load config from prefixed environment variables.
523
524
Args:
525
prefix: Environment variable prefix
526
loads: Function to parse variable values
527
"""
528
```
529
530
### Usage Examples
531
532
#### Basic Application Setup
533
534
```python
535
from quart import Quart
536
537
app = Quart(__name__)
538
539
@app.route('/')
540
async def hello():
541
return 'Hello, World!'
542
543
@app.route('/api/<int:id>')
544
async def get_item(id):
545
return {'id': id, 'name': f'Item {id}'}
546
547
if __name__ == '__main__':
548
app.run(debug=True)
549
```
550
551
#### Blueprint Usage
552
553
```python
554
from quart import Quart, Blueprint
555
556
# Create blueprint
557
api = Blueprint('api', __name__, url_prefix='/api')
558
559
@api.route('/users')
560
async def list_users():
561
return {'users': []}
562
563
@api.route('/users/<int:user_id>')
564
async def get_user(user_id):
565
return {'id': user_id, 'name': f'User {user_id}'}
566
567
# Register with app
568
app = Quart(__name__)
569
app.register_blueprint(api)
570
```
571
572
#### Configuration Management
573
574
```python
575
from quart import Quart
576
577
app = Quart(__name__)
578
579
# Load from object
580
app.config.from_object('config.DevelopmentConfig')
581
582
# Load from environment variable
583
app.config.from_envvar('APP_CONFIG')
584
585
# Load from prefixed environment variables
586
app.config.from_prefixed_env('MYAPP')
587
588
# Access configuration
589
if app.config['DEBUG']:
590
print("Debug mode enabled")
591
```