Unfazed Routing¶
Unfazed's routing system maps URL paths to endpoint functions. Routes are defined using the path() helper, organized into patterns lists, and composed with include() for multi-app projects. The framework also supports static file serving via static(), mounting external ASGI apps via mount(), and per-route middleware.
Quick Start¶
1. Define routes in your app¶
# myapp/routes.py
from unfazed.route import path
from myapp.endpoints import list_users, get_user, create_user
patterns = [
path("/users", endpoint=list_users),
path("/users/{user_id:int}", endpoint=get_user),
path("/users", endpoint=create_user, methods=["POST"]),
]
2. Wire them into the root URL config¶
# routes.py (project root)
from unfazed.route import path, include
patterns = [
path("/api", routes=include("myapp.routes")),
]
3. Set ROOT_URLCONF in settings¶
The routes module must define a patterns list at module level.
Defining Routes¶
Basic route¶
When no methods are specified, the route defaults to GET and HEAD.
Specifying HTTP methods¶
path("/users", endpoint=create_user, methods=["POST"])
path("/users/{user_id}", endpoint=update_user, methods=["PUT", "PATCH"])
HEAD is automatically added when GET is specified.
Path parameters¶
Use {name} or {name:type} placeholders in the path:
Built-in convertors: str (default), int, float, path. You can register custom convertors:
from unfazed.route import Convertor, register_url_convertor
class LangConvertor(Convertor):
regex = r"[-_a-zA-Z]+"
def convert(self, value: str) -> str:
return value
def to_string(self, value: str) -> str:
return value
register_url_convertor("lang", LangConvertor())
# Now use it:
path("/docs/{lang:lang}", endpoint=get_docs)
OpenAPI metadata¶
Routes accept metadata fields that appear in the generated OpenAPI spec:
path(
"/users",
endpoint=list_users,
tags=["users"],
summary="List all users",
description="Returns a paginated list of users",
deprecated=False,
operation_id="listUsers",
externalDocs={"url": "https://docs.example.com/users"},
include_in_schema=True,
)
Set include_in_schema=False to hide a route from the OpenAPI spec.
Composing Routes¶
Nesting with routes¶
Use the routes parameter to prefix a group of routes:
user_routes = [
path("/", endpoint=list_users),
path("/{user_id}", endpoint=get_user),
]
patterns = [
path("/api/users", routes=user_routes),
]
# Results in: /api/users/ and /api/users/{user_id}
Including from another module with include()¶
include() imports a module's patterns list and automatically sets the app_label:
from unfazed.route import path, include
patterns = [
path("/api/blog", routes=include("blog.routes")),
path("/api/auth", routes=include("unfazed.contrib.auth.routes")),
]
The target module must define a patterns list:
# blog/routes.py
from unfazed.route import path
from blog.endpoints import list_posts, get_post
patterns = [
path("/posts", endpoint=list_posts),
path("/posts/{post_id}", endpoint=get_post),
]
Per-route middleware¶
Apply middleware to specific routes or route groups:
path(
"/admin",
routes=include("admin.routes"),
middlewares=["myapp.middleware.AdminAuthMiddleware"],
)
# Or on a single route:
path(
"/secret",
endpoint=secret_endpoint,
middlewares=["myapp.middleware.RateLimitMiddleware"],
)
Middleware is applied in reverse list order (same as the global MIDDLEWARE setting).
Static Files¶
Serve static files from a directory:
from unfazed.route import static
patterns = [
static("/static", "/path/to/staticfiles"),
static("/media", "/path/to/media", html=True),
]
| Parameter | Description |
|---|---|
path |
URL prefix (e.g. "/static"). |
directory |
Absolute path to the files directory. |
html |
If True, serve index.html for directory requests. |
Static routes are excluded from the OpenAPI schema.
Mounting External Apps¶
Mount any ASGI application under a path prefix:
from starlette.applications import Starlette
from unfazed.route import mount
other_app = Starlette(...)
patterns = [
mount("/legacy", app=other_app),
]
You can also mount a sub-group of routes:
Mount routes are excluded from the OpenAPI schema.
API Reference¶
path()¶
def path(
path: str,
*,
endpoint: Callable = None,
routes: List[Route] = None,
methods: List[str] = None,
name: str = None,
app_label: str = None,
middlewares: List[str] = None,
include_in_schema: bool = True,
tags: List[str] = None,
summary: str = None,
description: str = None,
externalDocs: Dict = None,
deprecated: bool = False,
operation_id: str = None,
) -> Route | List[Route]
Create a Route (when endpoint is given) or a list of prefixed routes (when routes is given). Exactly one of endpoint or routes must be provided.
include()¶
Import a module's patterns list. The module must define patterns at module level.
static()¶
def static(path: str, directory: str, *, name: str = None, app_label: str = None, html: bool = False) -> Static
Create a static file serving route.
mount()¶
def mount(path: str, app: ASGIApp = None, routes: List[Route] = None, *, name: str = None, app_label: str = None, middlewares: List[str] = None) -> Mount
Mount an ASGI app or route group under a path prefix.
Route¶
class Route(starlette.routing.Route):
def __init__(self, path, endpoint, *, methods=None, name=None, middlewares=None, app_label=None, tags=None, include_in_schema=True, summary=None, description=None, externalDocs=None, deprecated=None, operation_id=None, response_models=None)
A single URL-to-endpoint mapping. Paths must start with /.
register_url_convertor()¶
Register a custom URL path convertor for use in {name:type} path parameters.