Spectree
Spectree is a Python library that helps generate OpenAPI documents and validate requests and responses using Python type annotations. It leverages Pydantic for data model definitions and supports various web frameworks like Flask, Quart, Falcon, and Starlette. The library is actively maintained, with the current version being 2.0.1, and typically releases minor fixes after major version updates.
Common errors
-
ModuleNotFoundError: No module named 'pydantic.v1'
cause Your application is attempting to import `pydantic.v1.BaseModel` (or other v1 components) while `spectree` v2+ is installed, which expects Pydantic v2.fixUpgrade Pydantic to v2 (`pip install -U pydantic`) and update your Pydantic model imports from `pydantic.v1` to `pydantic`. If you need Pydantic v1, you must downgrade `spectree` to a version before 2.0.0 (e.g., `pip install 'spectree<2'`). -
TypeError: 'NoneType' object is not callable (or similar related to Optional fields in Pydantic v2)
cause In Pydantic v2, `Optional[Type]` fields without an explicit `None` default are treated as required fields that can accept `None`. If the input JSON omits this field, Pydantic raises an error.fixEnsure that any Pydantic fields you intend to be truly optional (i.e., not present in the input) are explicitly given a default value of `None`. Example: `my_field: Optional[str] = None`. -
spectree.exceptions.InvalidPathParameter: Parameter 'user_id' in path '/user/<user_id>' is not annotated in endpoint 'get_user'
cause You have defined a path parameter in your framework's route (e.g., Flask's `<user_id>`) but have not included it as a type-hinted parameter in your decorated endpoint function, or `spectree` could not correctly parse it.fixEnsure that all path parameters in your route string are present as annotated arguments in your function signature, e.g., `@app.route('/user/<int:user_id>') def get_user(user_id: int):`. Spectree uses these annotations to generate the OpenAPI path parameters.
Warnings
- breaking Spectree v2.0.0 introduced breaking changes by dropping support for Pydantic v1 and Python 3.9. Your application will fail to run if you upgrade spectree to v2+ while still using Pydantic v1 or Python 3.9.
- gotcha Mixing Pydantic v1 and v2 models in the same application, or passing a Pydantic v1 model as an attribute to a Pydantic v2 model, can lead to runtime `ValidationError`s that are difficult to debug.
- gotcha In Pydantic v2 (required by `spectree` v2+), fields annotated with `typing.Optional[Type]` are now 'required but can be `None`' unless a default value (e.g., `None`) is explicitly provided. This is a change from Pydantic v1 behavior.
Install
-
pip install spectree -
pip install spectree[email]
Imports
- SpecTree
from spectree.spec import SpecTree
from spectree import SpecTree
- Response
from flask import Response
from spectree import Response
- BaseModel
from pydantic.v1 import BaseModel
from pydantic import BaseModel
Quickstart
from flask import Flask, request
from pydantic import BaseModel, Field
from spectree import SpecTree, Response
app = Flask(__name__)
api = SpecTree('flask', app=app, title='User API', version='1.0.0')
class UserQuery(BaseModel):
name: str = Field(..., description='User name')
age: int = Field(..., gt=0, lt=150, description='User age')
class UserResponse(BaseModel):
message: str
user_id: int
@app.route('/user', methods=['POST'])
@api.validate(query=UserQuery, resp=Response(HTTP_200=UserResponse), tags=['User'])
def create_user():
# The validated 'query' data is available in request.context.query
user_data = request.context.query
user_id = 123 # Simulate user creation
return {'message': f'User {user_data.name} created', 'user_id': user_id}
# Access OpenAPI docs at /apidoc/redoc, /apidoc/swagger, or /apidoc/scalar
# To run: FLASK_APP=your_app_file.py flask run