OpenAPI & Swagger UI
The openviper.openapi package auto-generates an OpenAPI 3.1.0 schema from
registered routes and their Python type hints, and serves interactive
Swagger UI and ReDoc documentation pages.
Overview
The framework inspects every registered route’s handler signature and, where
present, its serializer_class attribute to build a complete OpenAPI schema.
The schema is served as JSON at /open-api/schema.json and two interactive
UI pages are mounted at /open-api/docs (Swagger UI) and
/open-api/redoc (ReDoc) by default.
No extra code or decorator is required — the schema is generated automatically from route registration and type annotations.
Key Functions
openviper.openapi.schema
- generate_openapi_schema(routes, title, version, description='') dict
Generate an OpenAPI 3.1.0 schema dict from a list of
Routeobjects.Path parameters (e.g.
{id:int}) are included asparameters.Return type annotations that are Pydantic models are reflected into
responses["200"]["content"].When a
serializer_classis set on a class-based view, it is used to produce therequestBodyschema.Python built-in types are mapped to JSON Schema types automatically.
openviper.openapi.ui
Example Usage
Automatic Schema (Zero Configuration)
from openviper import OpenViper
app = OpenViper(
title="Blog API",
version="1.0.0",
)
# Schema available at /open-api/schema.json
# Swagger UI at /open-api/docs
# ReDoc at /open-api/redoc
Richer Schema via Pydantic Serializers
Attach a serializer_class to a class-based view to give Swagger UI an
input form for the request body:
from openviper.http.views import View
from openviper.serializers import Serializer
from openviper.http.response import JSONResponse
class CreatePostSerializer(Serializer):
title: str
body: str
tags: list[str] = []
class PostCreateView(View):
serializer_class = CreatePostSerializer
async def post(self, request) -> JSONResponse:
data = CreatePostSerializer.validate(await request.json())
post = await Post.objects.create(**data.model_dump())
return JSONResponse(post._to_dict(), status_code=201)
PostCreateView.register(router, "/posts")
Return Type Annotation for Response Schema
from pydantic import BaseModel
class PostOut(BaseModel):
id: int
title: str
body: str
@router.get("/posts/{post_id:int}")
async def get_post(request, post_id: int) -> PostOut:
post = await Post.objects.get(id=post_id)
return JSONResponse(post._to_dict())
The PostOut model is reflected into the OpenAPI responses section for
this endpoint.
Accessing the Raw Schema
from openviper.openapi.schema import generate_openapi_schema
from openviper.routing.router import Router
import json
router = Router()
# ... register routes ...
schema = generate_openapi_schema(
routes=router.routes,
title="My API",
version="2.0.0",
)
print(json.dumps(schema, indent=2))
OpenAPI Exclusion
The OPENAPI_EXCLUDE setting lets you disable the OpenAPI router entirely
or remove specific base routes from the generated schema without changing your
routing registration.
Value |
Effect |
|---|---|
|
All routes appear in the schema; docs endpoints are active. |
|
The OpenAPI router is not registered. |
|
Routes whose path starts with |
|
Routes under |
Disable OpenAPI
Set OPENAPI_EXCLUDE = "__ALL__" to prevent the docs and schema endpoints
from being registered. This is recommended for production deployments where
you do not want to expose API documentation.
# settings.py
OPENAPI_EXCLUDE = "__ALL__"
After applying this setting, any request to /open-api/openapi.json,
/open-api/docs, or /open-api/redoc will receive a 404 response.
Exclude Routes by Prefix
Pass a list of route-path prefixes (without the leading /) to remove
matching paths from the generated schema. The docs endpoint itself remains
accessible; only the schema content is filtered.
# Remove all /admin/* routes from the schema
OPENAPI_EXCLUDE = ["admin"]
# Remove /admin/* and /blogs/* routes
OPENAPI_EXCLUDE = ["admin", "blogs"]
# Remove /admin/*, /blogs/*, and /internal/* routes
OPENAPI_EXCLUDE = ["admin", "blogs", "internal"]
Prefix Matching Rules
Matching is case-insensitive:
"Admin"and"admin"produce the same result.Leading slashes in a prefix are normalised:
"/admin"is treated identically to"admin".Only complete path segments are matched. A prefix of
"blogs"will exclude/blogsand/blogs/postsbut not/blogsearchor/blog.
Security Benefits
Using OPENAPI_EXCLUDE reduces the attack surface of your API:
Hide internal admin endpoints from the public schema.
Prevent automated scanners from discovering route structures.
Disable the schema entirely in production to avoid information leakage.
See also
OpenAPI & Swagger UI — main OpenAPI reference page.
API Reference — Exclusion Helpers
openviper.openapi.schema
- filter_openapi_routes(routes: list[Route]) list[Route]
Filter a list of
Routeobjects according tosettings.OPENAPI_EXCLUDE."__ALL__"→ returns[].A
list[str]of prefixes → drops routes whose path starts with any of the given prefixes (case-insensitive, leading/normalised).Empty list or missing setting → returns all routes unchanged.
Any other value triggers a warning and returns all routes unchanged.
openviper.openapi.router
Configuration Reference
OPENAPI_EXCLUDE
Type: str | list[str]
Default: []
Controls OpenAPI access and route exclusion.
Value |
Behaviour |
|---|---|
|
No routes excluded; docs endpoints active. |
|
Docs router not registered; all docs URLs return 404. |
|
Routes whose path starts with any listed prefix are removed from the generated schema. Docs endpoints remain accessible. |
Prefix matching rules:
Case-insensitive:
"Admin"and"admin"are equivalent.Leading slashes normalised:
"/admin"and"admin"are identical.Whole-segment matching:
"blogs"excludes/blogsand/blogs/postsbut not/blogsearchor/blog.
All OpenAPI Settings
Setting |
Default |
Description |
|---|---|---|
|
|
Master switch. |
|
|
Title shown in Swagger UI and ReDoc. |
|
|
API version string in the schema |
|
|
URL at which the raw JSON schema is served. |
|
|
URL for the Swagger UI page. |
|
|
URL for the ReDoc page. |
|
|
Route exclusion list (see above). |
Configuration Examples
Disable OpenAPI entirely in production:
# settings.py
OPENAPI_EXCLUDE = "__ALL__"
Remove admin routes from the public schema:
OPENAPI_EXCLUDE = ["admin"]
Remove multiple path prefixes:
OPENAPI_EXCLUDE = ["admin", "blogs", "internal", "health"]
Security Considerations
Disable the schema entirely (
OPENAPI_EXCLUDE = "__ALL__") in production to prevent automated scanners from discovering your API surface.Use prefix exclusion to hide
/adminand other sensitive sub-trees from publicly served documentation.Schema exposure is listed as a risk in OWASP API Security Top 10 (API7: Security Misconfiguration).
OPENAPI_EXCLUDEdirectly mitigates this risk.