NEW: Fenrir v4.1.2 — 56 Bug Fixes, Performance Optimizations, 1331 Tests, 5-Framework Benchmark! Read the changelog
blueprints.md
docs blueprints.md

Blueprints

Blueprints provide a way to organize your application into modular components. Each blueprint can have its own routes, middleware, and error handlers, which are registered with the main application when ready.

Creating Blueprints

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
from fenrir import Blueprint

api_bp = Blueprint("api", url_prefix="/api")

@api_bp.get("/items")
async def list_items():
    return [{"id": 1, "name": "Item 1"}]

@api_bp.get("/items/<item_id:int>")
async def get_item(item_id: int):
    return {"id": item_id, "name": f"Item {item_id}"}

@api_bp.post("/items")
async def create_item(data: dict):
    return {"id": 2, "name": data.get("name", "New Item"), "created": True}

Registering Blueprints

1
2
3
4
from fenrir import Fenrir

app = Fenrir()
app.register_blueprint(api_bp)

Blueprint with Middleware

Apply middleware to all routes within a blueprint:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
from fenrir import Blueprint, HTTPUnauthorized, request

api_bp = Blueprint("api", url_prefix="/api")

@api_bp.before_request
async def check_api_key():
    api_key = request.headers.get("X-API-Key")
    if not api_key:
        raise HTTPUnauthorized(detail="Missing API key")

@api_bp.get("/data")
async def get_data():
    return {"data": "protected"}

app.register_blueprint(api_bp)

Multiple Blueprints

Organize your application into multiple modules:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
from fenrir import Fenrir, Blueprint

# users_bp.py
users_bp = Blueprint("users", url_prefix="/users")

@users_bp.get("")
async def list_users():
    return [{"id": 1, "name": "User 1"}]

@users_bp.get("/<user_id:int>")
async def get_user(user_id: int):
    return {"id": user_id, "name": f"User {user_id}"}

# products_bp.py
products_bp = Blueprint("products", url_prefix="/products")

@products_bp.get("")
async def list_products():
    return [{"id": 1, "name": "Product 1"}]

@products_bp.post("")
async def create_product(data: dict):
    return {"id": 2, **data, "created": True}

# app.py
app = Fenrir()
app.register_blueprint(users_bp)
app.register_blueprint(products_bp)

Blueprint with Error Handlers

Register error handlers that apply only to routes within a blueprint:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
from fenrir import Blueprint, JSONResponse

api_bp = Blueprint("api", url_prefix="/api")

@api_bp.errorhandler(404)
async def api_not_found(req, exc):
    return JSONResponse({"error": "API resource not found"}, status_code=404)

@api_bp.get("/items")
async def list_items():
    return [{"id": 1}]

Blueprint with Teardown

Register cleanup functions that run after each request within the blueprint:

1
2
3
4
5
6
7
api_bp = Blueprint("api", url_prefix="/api")

@api_bp.teardown_request
async def cleanup(exc):
    if exc:
        print(f"Request ended with error: {exc}")
    # Release resources, close connections, etc.

Nested Blueprint Organization

Organize large applications with domain-specific blueprints:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
from fenrir import Fenrir, Blueprint

# Auth module
auth_bp = Blueprint("auth", url_prefix="/auth")

@auth_bp.post("/login")
async def login(credentials: dict):
    return {"token": "abc123"}

@auth_bp.post("/register")
async def register(user_data: dict):
    return {"id": 1, "created": True}

# API module
api_bp = Blueprint("api", url_prefix="/api")

@api_bp.get("/users")
async def list_users():
    return [{"id": 1, "name": "Alice"}]

# Admin module
admin_bp = Blueprint("admin", url_prefix="/admin")

@admin_bp.get("/stats")
async def get_stats():
    return {"total_users": 100}

# Register all blueprints
app = Fenrir()
app.register_blueprint(auth_bp)
app.register_blueprint(api_bp)
app.register_blueprint(admin_bp)

Blueprint URL Prefix

The url_prefix is prepended to all routes in the blueprint:

1
2
3
4
5
6
# All routes will be under /api/v1
api_v1 = Blueprint("api_v1", url_prefix="/api/v1")

@api_v1.get("/users")  # Becomes /api/v1/users
async def list_users():
    return []

Best Practices

  • One blueprint per domain: Group related routes (users, products, auth) into separate blueprints.
  • Use descriptive names: Blueprint names appear in error messages and logs.
  • Keep blueprints focused: Avoid creating monolithic blueprints with unrelated routes.
  • Use url_prefix: Always set a prefix to avoid route collisions between blueprints.
Edit on GitHub Last Updated: Oct 20, 2018
© 2026 Fenrir Project.
main*
v4.1.2
Ln 1, Col 1
UTF-8
Prettier
Light Mode
Markdown