A Python ASGI web framework with the same API as Flask
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Central application management, modular blueprint system, and configuration handling for building scalable async web applications with Flask-compatible APIs.
The central Quart class handles HTTP and WebSocket requests, manages routing, and provides the foundation for async web applications.
import asyncio
from typing import Any, Callable, Iterable
from quart.blueprints import Blueprint
from quart.wrappers import Response
class Quart:
def __init__(
self,
import_name: str,
static_url_path: str | None = None,
static_folder: str | None = "static",
static_host: str | None = None,
host_matching: bool = False,
subdomain_matching: bool = False,
template_folder: str | None = "templates",
instance_path: str | None = None,
instance_relative_config: bool = False,
root_path: str | None = None
):
"""
Initialize a Quart application.
Args:
import_name: The name of the application package
static_url_path: URL path for static files
static_folder: Folder containing static files
static_host: Host for static files
host_matching: Enable host matching for routes
subdomain_matching: Enable subdomain matching
template_folder: Folder containing templates
instance_path: Alternative instance path
instance_relative_config: Load config relative to instance path
root_path: Application root path
"""
def route(
self,
rule: str,
*,
methods: Iterable[str] | None = None,
host: str | None = None,
subdomain: str | None = None,
strict_slashes: bool | None = None,
merge_slashes: bool | None = None,
redirect_to: str | Callable[..., str] | None = None,
alias: bool = False,
endpoint: str | None = None,
defaults: dict[str, Any] | None = None,
**options: Any
) -> Callable[[Callable], Callable]:
"""
Decorator to register HTTP route handlers.
This is the most fundamental Flask method for defining HTTP routes.
The decorated function will be called when a request matches the route pattern.
Args:
rule: URL rule pattern (e.g., '/users/<int:id>')
methods: HTTP methods this route accepts (defaults to ['GET'])
host: Full host name for this route (cannot be used with subdomain)
subdomain: Subdomain for this specific route
strict_slashes: Strictly match trailing slashes in the path
merge_slashes: Merge consecutive slashes in the path
redirect_to: Redirect rule for this endpoint
alias: Whether this is an alias for another endpoint
endpoint: Custom endpoint name (defaults to function name)
defaults: Default values for URL variables
**options: Additional route options
Returns:
Decorated function that handles the route
Example:
@app.route('/users/<int:user_id>', methods=['GET', 'POST'])
async def user_profile(user_id):
return f'User {user_id}'
"""
def websocket(self, rule: str, **options):
"""
Decorator to register WebSocket handlers.
Args:
rule: WebSocket URL rule pattern
**options: Additional WebSocket options
"""
def add_url_rule(
self,
rule: str,
endpoint: str | None = None,
view_func: Callable | None = None,
*,
methods: Iterable[str] | None = None,
host: str | None = None,
subdomain: str | None = None,
strict_slashes: bool | None = None,
merge_slashes: bool | None = None,
redirect_to: str | Callable[..., str] | None = None,
alias: bool = False,
defaults: dict[str, Any] | None = None,
websocket: bool = False,
**options: Any
) -> None:
"""
Core method for programmatically adding routes.
This is the underlying method used by the @route decorator and other routing
utilities. It provides the most control over route registration.
Args:
rule: URL rule pattern (e.g., '/api/users/<int:id>')
endpoint: Endpoint name for URL generation (defaults to view_func.__name__)
view_func: Function to call for this route
methods: HTTP methods this route accepts
host: Full host name for this route (cannot be used with subdomain)
subdomain: Subdomain for this specific route
strict_slashes: Strictly match trailing slashes in the path
merge_slashes: Merge consecutive slashes in the path
redirect_to: Redirect rule for this endpoint
alias: Whether this is an alias for another endpoint
defaults: Default values for URL variables
websocket: Whether this is a WebSocket route
**options: Additional route configuration options
Example:
app.add_url_rule('/api/health', 'health_check', health_handler, methods=['GET'])
"""
def add_websocket(
self,
rule: str,
endpoint: str | None = None,
view_func: Callable | None = None,
**options
):
"""Add WebSocket route programmatically."""
def before_serving(self, func: Callable):
"""Decorator for functions to run before serving starts."""
def after_serving(self, func: Callable):
"""Decorator for functions to run after serving ends."""
def while_serving(self, func: Callable):
"""Decorator for startup/shutdown generator functions."""
def register_blueprint(
self,
blueprint: Blueprint,
*,
url_prefix: str | None = None,
subdomain: str | None = None,
url_defaults: dict[str, Any] | None = None,
**options: Any
) -> None:
"""
Register a Blueprint with the application.
Essential for modular app organization. Blueprints allow you to organize
your application into reusable components with their own routes, templates,
and static files.
Args:
blueprint: The Blueprint instance to register
url_prefix: URL prefix for all blueprint routes (overrides blueprint default)
subdomain: Subdomain for all blueprint routes (overrides blueprint default)
url_defaults: Default values for URL variables in blueprint routes
**options: Additional registration options
Example:
from myapp.auth import auth_bp
app.register_blueprint(auth_bp, url_prefix='/auth')
"""
def before_request(
self,
func: Callable[[], Any | Awaitable[Any]]
) -> Callable[[], Any | Awaitable[Any]]:
"""
Decorator for pre-request hooks.
Functions decorated with this will be called before processing each HTTP request.
If a before_request function returns a non-None value, it will be used as the
response instead of calling the view function.
Args:
func: Function to call before each request
Returns:
The decorated function
Example:
@app.before_request
async def load_user():
g.user = await get_current_user()
@app.before_request
async def check_auth():
if not session.get('authenticated'):
return redirect('/login')
"""
def after_request(
self,
func: Callable[[Response], Response | Awaitable[Response]]
) -> Callable[[Response], Response | Awaitable[Response]]:
"""
Decorator for post-request hooks.
Functions decorated with this will be called after each HTTP request is processed.
The function receives the response object and must return a (possibly modified)
response object.
Args:
func: Function to call after each request, receives response object
Returns:
The decorated function
Example:
@app.after_request
async def add_security_headers(response):
response.headers['X-Content-Type-Options'] = 'nosniff'
return response
@app.after_request
async def log_response(response):
app.logger.info(f'Response status: {response.status_code}')
return response
"""
def before_websocket(self, func: Callable):
"""Decorator for functions to run before WebSocket connections."""
def after_websocket(self, func: Callable):
"""Decorator for functions to run after WebSocket connections."""
def teardown_request(self, func: Callable):
"""Decorator for request teardown functions."""
def teardown_websocket(self, func: Callable):
"""Decorator for WebSocket teardown functions."""
def teardown_appcontext(self, func: Callable):
"""Decorator for app context teardown functions."""
def errorhandler(
self,
code_or_exception: int | type[Exception] | Exception
) -> Callable[[Callable], Callable]:
"""
Decorator for handling HTTP errors and exceptions.
Register functions to handle specific HTTP error codes or exception types.
Error handlers can return custom responses for different error conditions.
Args:
code_or_exception: HTTP status code (e.g., 404, 500) or exception class/instance
Returns:
Decorated function that handles the error
Example:
@app.errorhandler(404)
async def not_found(error):
return 'Page not found', 404
@app.errorhandler(ValueError)
async def handle_value_error(error):
return f'Invalid value: {error}', 400
"""
def url_for(
self,
endpoint: str,
*,
_anchor: str | None = None,
_external: bool | None = None,
_method: str | None = None,
_scheme: str | None = None,
**values: Any,
) -> str:
"""
Generate URLs for endpoints.
This is most useful in templates and redirects to create a URL
that can be used in the browser.
Args:
endpoint: The endpoint to build a url for, if prefixed with
'.' it targets endpoint's in the current blueprint.
_anchor: Additional anchor text to append (i.e. #text).
_external: Return an absolute url for external (to app) usage.
_method: The method to consider alongside the endpoint.
_scheme: A specific scheme to use.
**values: The values to build into the URL, as specified in
the endpoint rule.
Returns:
Generated URL string
Example:
url_for('user_profile', user_id=123)
url_for('api.get_user', user_id=123, _external=True)
"""
def run(
self,
host: str | None = None,
port: int | None = None,
debug: bool | None = None,
use_reloader: bool = True,
loop: asyncio.AbstractEventLoop | None = None,
ca_certs: str | None = None,
certfile: str | None = None,
keyfile: str | None = None,
**kwargs: Any,
) -> None:
"""
Run this application.
This is best used for development only, see Hypercorn for
production servers.
Args:
host: Hostname to listen on. By default this is loopback
only, use 0.0.0.0 to have the server listen externally.
port: Port number to listen on.
debug: If set enable (or disable) debug mode and debug output.
use_reloader: Automatically reload on code changes.
loop: Asyncio loop to create the server in, if None, take default one.
ca_certs: Path to the SSL CA certificate file.
certfile: Path to the SSL certificate file.
keyfile: Path to the SSL key file.
**kwargs: Additional arguments
"""
async def run_task(
self,
host: str = "127.0.0.1",
port: int = 5000,
debug: bool | None = None,
**kwargs
):
"""Return coroutine for running the application."""
def test_client(self, **kwargs):
"""Create test client instance."""
def test_cli_runner(self, **kwargs):
"""Create CLI test runner."""
def app_context(self):
"""Create application context."""
def request_context(self, request):
"""Create request context."""
def websocket_context(self, websocket):
"""Create WebSocket context."""
def test_request_context(self, path: str = "/", **kwargs):
"""Create test request context."""
def add_background_task(self, func: Callable, *args, **kwargs):
"""Add background task to be executed."""
async def make_response(self, result):
"""Create response from various inputs."""
def ensure_async(self, func: Callable):
"""Ensure function is async."""
def sync_to_async(self, func: Callable):
"""Convert sync function to async."""
# Key attributes
config: Config
debug: bool
testing: bool
secret_key: str | bytes | None
permanent_session_lifetime: timedelta
jinja_env: Environment
url_map: Map
view_functions: dict[str, Callable]Modular application organization with Flask-compatible blueprint API for creating reusable application components.
class Blueprint:
def __init__(
self,
name: str,
import_name: str,
static_folder: str | None = None,
static_url_path: str | None = None,
template_folder: str | None = None,
url_prefix: str | None = None,
subdomain: str | None = None,
url_defaults: dict | None = None,
root_path: str | None = None,
cli_group: str | None = None
):
"""
Initialize a blueprint for modular application organization.
Args:
name: Blueprint name
import_name: Blueprint package name
static_folder: Static files folder
static_url_path: URL path for static files
template_folder: Template folder
url_prefix: URL prefix for all routes
subdomain: Subdomain for all routes
url_defaults: Default values for URL variables
root_path: Blueprint root path
cli_group: CLI command group name
"""
def route(self, rule: str, **options):
"""Register routes on blueprint."""
def websocket(self, rule: str, **options):
"""Register WebSocket handlers on blueprint."""
def before_request(self, func: Callable):
"""Pre-request functions for blueprint."""
def after_request(self, func: Callable):
"""Post-request functions for blueprint."""
def before_websocket(self, func: Callable):
"""Pre-WebSocket functions for blueprint."""
def after_websocket(self, func: Callable):
"""Post-WebSocket functions for blueprint."""
def before_app_request(self, func: Callable):
"""Add pre-request function to app."""
def after_app_request(self, func: Callable):
"""Add post-request function to app."""
def before_app_serving(self, func: Callable):
"""Add pre-serving function to app."""
def after_app_serving(self, func: Callable):
"""Add post-serving function to app."""
def teardown_request(self, func: Callable):
"""Blueprint-specific teardown."""
def teardown_websocket(self, func: Callable):
"""WebSocket-specific teardown."""
def errorhandler(self, code_or_exception):
"""Blueprint error handlers."""
def register(self, app: Quart, options: dict):
"""Register blueprint with app."""Flask-compatible configuration system with Quart-specific enhancements for environment variables and structured configuration.
class Config(dict):
def from_envvar(self, variable_name: str, silent: bool = False) -> bool:
"""
Load config from environment variable pointing to config file.
Args:
variable_name: Environment variable name
silent: Don't raise error if variable doesn't exist
Returns:
True if config was loaded successfully
"""
def from_pyfile(self, filename: str, silent: bool = False) -> bool:
"""
Load config from Python file.
Args:
filename: Path to Python config file
silent: Don't raise error if file doesn't exist
Returns:
True if config was loaded successfully
"""
def from_object(self, obj):
"""
Load config from object (module, class, or object).
Args:
obj: Object containing configuration variables
"""
def from_prefixed_env(
self,
prefix: str = "QUART",
*,
loads: Callable = json.loads
):
"""
Load config from prefixed environment variables.
Args:
prefix: Environment variable prefix
loads: Function to parse variable values
"""from quart import Quart
app = Quart(__name__)
@app.route('/')
async def hello():
return 'Hello, World!'
@app.route('/api/<int:id>')
async def get_item(id):
return {'id': id, 'name': f'Item {id}'}
if __name__ == '__main__':
app.run(debug=True)from quart import Quart, Blueprint
# Create blueprint
api = Blueprint('api', __name__, url_prefix='/api')
@api.route('/users')
async def list_users():
return {'users': []}
@api.route('/users/<int:user_id>')
async def get_user(user_id):
return {'id': user_id, 'name': f'User {user_id}'}
# Register with app
app = Quart(__name__)
app.register_blueprint(api)from quart import Quart
app = Quart(__name__)
# Load from object
app.config.from_object('config.DevelopmentConfig')
# Load from environment variable
app.config.from_envvar('APP_CONFIG')
# Load from prefixed environment variables
app.config.from_prefixed_env('MYAPP')
# Access configuration
if app.config['DEBUG']:
print("Debug mode enabled")Install with Tessl CLI
npx tessl i tessl/pypi-quart