For more complex routing, use APIView to group related endpoints under a common url_prefix and view_tags.
- Create an
APIView instance. - Define classes for your logic.
- Use
@api_view.route("/path") to register the class. - Use
@api_view.doc(...) on methods within the class to provide OpenAPI metadata (like summary or deprecated status). - Register the view with the app using
app.register_api_view(api_view).
This approach allows for shared state within the view class and cleaner organization of RESTful resources.
from pydantic import BaseModel, Field
from flask_openapi import OpenAPI, Tag, Info, APIView
info = Info(title="book API", version="1.0.0")
app = OpenAPI(__name__, info=info)
api_view = APIView(url_prefix="/api/v1", view_tags=[Tag(name="book")])
class BookPath(BaseModel):
id: int = Field(..., description="book ID")
class BookQuery(BaseModel):
age: int | None = Field(None, description="Age")
class BookBody(BaseModel):
age: int | None = Field(..., ge=2, le=4, description="Age")
author: str = Field(None, min_length=2, max_length=4, description="Author")
@api_view.route("/book")
class BookListAPIView:
a = 1
@api_view.doc(summary="get book list")
def get(self, query: BookQuery):
return query.model_dump_json()
@api_view.doc(summary="create book")
def post(self, body: BookBody):
return body.model_dump_json()
@api_view.route("/book/<id>")
class BookAPIView:
@api_view.doc(summary="get book")
def get(self, path: BookPath):
return "get"
@api_view.doc(summary="update book")
def put(self, path: BookPath):
return "put"
@api_view.doc(summary="delete book", deprecated=True)
def delete(self, path: BookPath):
return "delete"
app.register_api_view(api_view)
if __name__ == "__main__":
app.run(debug=True)