Router¶
The Router class provides a way to organize and group routes separately from the main Wiverno application. Routes defined in a router can be included in the main application using include_router().
Module: wiverno.core.routing.router¶
Overview¶
Routers are useful for organizing your application into logical modules:
- API routes - Group API endpoints
- Admin routes - Separate admin functionality
- Feature modules - Organize routes by feature
Routes from a router are included in the main application with an optional URL prefix.
Basic Usage¶
from wiverno.core.routing.router import Router
# Create a router
api_router = Router()
# Define routes
@api_router.get("/users")
def list_users(request):
return "Users list"
@api_router.post("/users")
def create_user(request):
return 201, "User created"
# Include in main app
from wiverno.main import Wiverno
app = Wiverno()
app.include_router(api_router, prefix="/api")
# Routes become:
# GET /api/users
# POST /api/users
Constructor¶
Router()¶
Creates a new empty router with no routes.
Methods¶
Decorator Methods¶
@router.route(path, methods=None)¶
Generic route decorator for specifying custom HTTP methods.
Parameters:
path(str): URL path for the routemethods(list[str], optional): List of allowed HTTP methods. IfNone, all methods are allowed.
@router.get(path), @router.post(path), @router.put(path), @router.patch(path), @router.delete(path)¶
HTTP method-specific decorators.
@router.get("/items")
def list_items(request):
return "Items"
@router.post("/items")
def create_item(request):
return 201, "Item created"
@router.put("/items/1")
def update_item(request):
return "Item updated"
@router.delete("/items/1")
def delete_item(request):
return 204, ""
@router.connect(path), @router.head(path), @router.options(path), @router.trace(path)¶
Additional HTTP method decorators for CONNECT, HEAD, OPTIONS, and TRACE.
Programmatic Route Addition¶
router.add_route(path, handler, methods=None)¶
Programmatically add a route to the router without using decorators.
Parameters:
path(str): URL path for the routehandler(Callable): Function to handle the routemethods(list[str], optional): Allowed HTTP methods. IfNone, no method restriction.
Returns: None
def api_status(request):
return '{"status": "ok"}'
router.add_route("/status", api_status, methods=["GET"])
Route Retrieval¶
router.get_routes() -> list[dict]¶
Returns all registered routes in the router.
Returns: List of route dictionaries with keys:
path(str): Route pathhandler(Callable): Handler functionmethods(list[str] | None): Allowed HTTP methods
router = Router()
@router.get("/data")
def get_data(request):
return "Data"
routes = router.get_routes()
print(routes)
# Output: [{'path': '/data', 'handler': <function>, 'methods': ['GET']}]
Integration with Wiverno¶
Including Routers¶
Use app.include_router() to add router routes to your Wiverno application.
from wiverno.main import Wiverno
from wiverno.core.routing.router import Router
# Create routers
api_router = Router()
admin_router = Router()
# Define routes in routers
@api_router.get("/users")
def api_users(request):
return "API Users"
@admin_router.get("/dashboard")
def admin_dashboard(request):
return "Admin Dashboard"
# Create main app and include routers
app = Wiverno()
app.include_router(api_router, prefix="/api")
app.include_router(admin_router, prefix="/admin")
# Final routes:
# GET /api/users
# GET /admin/dashboard
Path Normalization¶
Paths in routers follow the same normalization rules as the main application:
- Trailing slashes are removed except for
/ /users/becomes/users/stays/
@router.get("/users") # Accessible at /users
@router.get("/users/") # Also accessible at /users (slash removed)
@router.get("/") # Root route, stays as /
Method Restrictions¶
If no methods are specified in the router, no method restriction is applied when the route is included in the application.
@router.route("/data") # No methods specified
def handle_data(request):
return "Data"
# This route accepts ALL HTTP methods
If methods are specified in the router, they are preserved when included in the application.
Examples¶
API Router¶
from wiverno.core.routing.router import Router
from wiverno.core.requests import Request
api_router = Router()
@api_router.get("/posts")
def list_posts(request: Request):
return '[{"id": 1, "title": "First"}]'
@api_router.post("/posts")
def create_post(request: Request):
data = request.data
title = data.get('title')
return 201, f'{{"title": "{title}"}}'
@api_router.get("/posts/1")
def get_post(request: Request):
return '{"id": 1, "title": "First"}'
Nested Router Prefixes¶
from wiverno.core.routing.router import Router
from wiverno.main import Wiverno
# V1 API routes
v1_router = Router()
@v1_router.get("/users")
def v1_users(request):
return "V1 Users"
# V2 API routes
v2_router = Router()
@v2_router.get("/users")
def v2_users(request):
return "V2 Users"
# Include with nested prefixes
app = Wiverno()
app.include_router(v1_router, prefix="/api/v1")
app.include_router(v2_router, prefix="/api/v2")
# Routes:
# GET /api/v1/users
# GET /api/v2/users
Admin Routes¶
admin_router = Router()
@admin_router.get("/users")
def admin_users(request):
return "Admin User List"
@admin_router.post("/users")
def admin_create_user(request):
return 201, "User created"
@admin_router.get("/settings")
def admin_settings(request):
return "Admin Settings"
# Include with /admin prefix
app.include_router(admin_router, prefix="/admin")
See Also¶
- Application - Main Wiverno application class
- Request - Request handling
- Base Views - Class-based views