The ultra-reliable, fast ASGI+WSGI framework for building data plane APIs at scale.
—
Advanced routing capabilities with URI templates, path converters, static file serving, and high-performance compiled routing for building scalable web APIs.
Core routing functionality for mapping URI patterns to resource handlers.
# Route registration methods (part of App class)
def add_route(self, uri_template: str, resource: object, **kwargs):
"""
Add a route to the application.
Args:
uri_template: URI template with optional parameters (e.g., '/users/{user_id}')
resource: Resource object with HTTP method handlers
suffix: Optional route suffix for method-based routing
"""
def add_static_route(self, prefix: str, directory: str, **kwargs):
"""
Add a route for serving static files.
Args:
prefix: URI prefix for static files
directory: Directory path containing static files
downloadable: Set Content-Disposition header for downloads
fallback_filename: Fallback file for missing resources
"""
def add_sink(self, sink: callable, prefix: str = '/'):
"""
Add a sink function to handle unmatched routes.
Args:
sink: Callable that accepts (req, resp) parameters
prefix: URI prefix to match against
"""import falcon
class UsersResource:
def on_get(self, req, resp, user_id=None):
if user_id:
resp.media = {'user_id': user_id}
else:
resp.media = {'users': []}
def on_post(self, req, resp):
resp.status = falcon.HTTP_201
resp.media = {'created': True}
class UserProfileResource:
def on_get(self, req, resp, user_id, profile_type='basic'):
resp.media = {
'user_id': user_id,
'profile_type': profile_type
}
app = falcon.App()
# Simple routes
app.add_route('/users', UsersResource())
app.add_route('/users/{user_id}', UsersResource())
# Route with optional parameter
app.add_route('/users/{user_id}/profile', UserProfileResource())
app.add_route('/users/{user_id}/profile/{profile_type}', UserProfileResource())
# Static file serving
app.add_static_route('/static', './public')
app.add_static_route('/downloads', './files', downloadable=True)Built-in converters for typed path parameters with automatic validation and conversion.
class BaseConverter:
def convert(self, value: str) -> object:
"""
Convert string path segment to typed value.
Args:
value: Path segment string
Returns:
Converted value
Raises:
ValueError: If conversion fails
"""
class IntConverter(BaseConverter):
"""Convert path segments to integers"""
def convert(self, value: str) -> int: ...
class FloatConverter(BaseConverter):
"""Convert path segments to floats"""
def convert(self, value: str) -> float: ...
class DateTimeConverter(BaseConverter):
"""Convert path segments to datetime objects"""
def __init__(self, format_string: str = '%Y-%m-%dT%H:%M:%SZ'):
"""
Args:
format_string: strptime format string
"""
def convert(self, value: str) -> datetime: ...
class UUIDConverter(BaseConverter):
"""Convert path segments to UUID objects"""
def convert(self, value: str) -> UUID: ...
class PathConverter(BaseConverter):
"""Pass-through converter for path segments"""
def convert(self, value: str) -> str: ...from uuid import UUID
from datetime import datetime
class OrderResource:
def on_get(self, req, resp, order_id: int, created_date: datetime):
# order_id is automatically converted to int
# created_date is automatically converted to datetime
order = get_order(order_id, created_date)
resp.media = order
class FileResource:
def on_get(self, req, resp, file_uuid: UUID):
# file_uuid is automatically converted to UUID
file_data = get_file(file_uuid)
resp.stream = file_data
# Route templates with converters
app.add_route('/orders/{order_id:int}', OrderResource())
app.add_route('/orders/{order_id:int}/date/{created_date:dt}', OrderResource())
app.add_route('/files/{file_uuid:uuid}', FileResource())Built-in static file serving for both WSGI and ASGI applications.
class StaticRoute:
def __init__(
self,
prefix: str,
directory: str,
downloadable: bool = False,
fallback_filename: str = None
):
"""
WSGI static file route.
Args:
prefix: URI prefix for static files
directory: Directory containing static files
downloadable: Set Content-Disposition header
fallback_filename: Fallback file for missing resources
"""
def __call__(self, req: Request, resp: Response): ...
class StaticRouteAsync:
def __init__(
self,
prefix: str,
directory: str,
downloadable: bool = False,
fallback_filename: str = None
):
"""
ASGI static file route.
Args: Same as StaticRoute
"""
async def __call__(self, req: Request, resp: Response): ...# Basic static file serving
app.add_static_route('/static', './public')
# Downloadable files with Content-Disposition
app.add_static_route('/downloads', './files', downloadable=True)
# SPA fallback to index.html
app.add_static_route('/app', './dist', fallback_filename='index.html')
# Multiple static directories
app.add_static_route('/css', './assets/css')
app.add_static_route('/js', './assets/js')
app.add_static_route('/images', './assets/images')Sink functions and advanced routing patterns for complex applications.
# Sink function signature
def sink_function(req: Request, resp: Response):
"""
Sink function for handling unmatched routes.
Args:
req: Request object
resp: Response object
"""def api_version_sink(req, resp):
"""Handle API versioning for unmatched routes"""
path_parts = req.path.strip('/').split('/')
if len(path_parts) >= 2 and path_parts[0] == 'api':
version = path_parts[1]
if version not in ['v1', 'v2']:
raise falcon.HTTPNotFound(
title='API version not supported',
description=f'Version {version} is not available'
)
# Continue processing
raise falcon.HTTPNotFound()
def catch_all_sink(req, resp):
"""Catch-all handler for unmatched routes"""
resp.status = falcon.HTTP_404
resp.media = {
'error': 'Not Found',
'path': req.path,
'method': req.method
}
# Register sinks
app.add_sink(api_version_sink, '/api')
app.add_sink(catch_all_sink) # Catch everythingUtility functions for advanced routing scenarios.
def map_http_methods(resource: object, **kwargs) -> dict:
"""
Map HTTP methods to resource responder methods.
Args:
resource: Resource object
**kwargs: Additional mapping options
Returns:
Dictionary mapping methods to responders
"""
def set_default_responders(resource: object, **kwargs):
"""
Set default responder methods on resource.
Args:
resource: Resource object to modify
**kwargs: Default responder options
"""High-performance routing engine with compilation optimizations.
class CompiledRouter:
def __init__(self, options: CompiledRouterOptions = None):
"""
High-performance compiled router.
Args:
options: Router configuration options
"""
def add_route(self, uri_template: str, method_map: dict, resource: object): ...
def find(self, uri: str, req: Request = None) -> tuple: ...
class CompiledRouterOptions:
def __init__(
self,
converters: dict = None,
strip_url_path_trailing_slash: bool = True
):
"""
Router configuration options.
Args:
converters: Custom path converters
strip_url_path_trailing_slash: Strip trailing slashes
"""from falcon.routing.converters import UUIDConverter, DateTimeConverter
# Custom router with specific converters
router_options = falcon.routing.CompiledRouterOptions(
converters={
'uuid': UUIDConverter(),
'timestamp': DateTimeConverter('%Y-%m-%d_%H:%M:%S')
}
)
router = falcon.routing.CompiledRouter(router_options)
# Create app with custom router
app = falcon.App(router=router)# Router types
CompiledRouter: type # High-performance router
CompiledRouterOptions: type # Router configuration
# Static route types
StaticRoute: type # WSGI static route
StaticRouteAsync: type # ASGI static route
# Converter types
BaseConverter: type # Base converter class
IntConverter: type # Integer converter
FloatConverter: type # Float converter
DateTimeConverter: type # DateTime converter
UUIDConverter: type # UUID converter
PathConverter: type # Path converterInstall with Tessl CLI
npx tessl i tessl/pypi-falcon