Skip to content
Guide

Blueprints and URL Generation

Compose HTTP route groups with inherited policies and generate validated application URLs.

from flasgo import Blueprint, Flasgo, HasScope, IsAuthenticated
app = Flasgo()
api = Blueprint("api", url_prefix="/api", permissions=[IsAuthenticated()])
reports = Blueprint("reports", url_prefix="/reports", permissions=[HasScope("reports:read")])
@reports.get("/<int:report_id>", name="detail")
def report(report_id: int) -> dict[str, int]:
return {"id": report_id}
api.register_blueprint(reports)
app.register_blueprint(api)
# Register an application-owned authentication backend before serving requests.
assert app.url_for("api.reports.detail", report_id=42) == "/api/reports/42"

Blueprint groups HTTP routes. Its get, post, put, patch, delete, route, and add_route APIs match the application. WebSockets continue to use app.websocket. Nested prefixes and names compose. Group permissions, dependencies, and rate_limits are additive. Protected parents and protected children must use the same backend; a route cannot declare itself public inside a protected group. Public routes belong in a separate group. CORS inherits when omitted and can be explicitly replaced with a route/group CORSConfig or disabled with cors=False.

Registration takes a snapshot: subsequent changes to a blueprint or its original endpoint decorators do not modify an already registered application. Each registration uses separate endpoint metadata. Cycles and duplicate names or HTTP registrations reject the whole registration without retaining partially registered routes.

Blueprint routes follow the application’s registration rules: methods must be a collection such as ["POST"] rather than a bare string, and malformed placeholders or unknown converters raise ValueError when the route is declared. Explicit route names must be unique across the application’s HTTP and WebSocket routes; a duplicate is rejected when it is added instead of breaking a later, unrelated blueprint registration.

Use name= for stable URL names. app.url_for(name, **values) works outside a request; flasgo.url_for uses the active request’s application. app.configure_templates() supplies url_for to Jinja by default. Converters are validated, parameters, literal path text, and query values are percent-encoded, query values of None are omitted, ambiguous names raise an error, and traversal/authority forms are rejected. For example, a route at /café/<int:item_id> named item gives app.url_for("item", item_id=3, q=None, sort="a b") == "/caf%C3%A9/3?sort=a+b". The active request’s ASGI root_path is included when generating URLs inside a mounted application. Outside a request, URLs are relative to the application’s root. URL generation does not accept an external host or scheme.

When an ASGI server mounts the application under a root_path, such as Uvicorn’s --root-path /api, Flasgo strips that prefix from the request path before routing. request.path is relative to the mount point, and url_for() adds the prefix back. A path that does not start with the root path, as sent by servers that already strip it, is left unchanged. Exact-path settings such as DOCS_PATH, OPENAPI_PATH, METRICS_PATH, and OTEL_EXCLUDED_PATHS are matched against the mount-relative path, so do not include the root path in them. Swagger UI requests the OpenAPI document through the mount prefix, for example /api/openapi.json. Before 0.11.0, requests whose path included the prefix did not match their routes.

Blueprint names must be Python identifiers without dots. Prefixes are literal absolute paths without a trailing slash, query, fragment, or path converter. Put converters on the route itself.

For example, after registering the routes above, a template can link with {{ url_for("api.reports.detail", report_id=42) }}. Extra keyword arguments become encoded query parameters. The underlying helper is flasgo.routing.build_url; it remains importable from flasgo.blueprints for existing code. Missing converter values and ambiguous endpoint names raise errors instead of generating an uncertain destination.

Blueprints group HTTP routes and metadata; they do not provide Flask extension compatibility or blueprint-specific template and static folders. Configure templates and static assets on the application.

Continue with Request Data and Dependencies and Policy and Deployment Checks.