Автоматическая генерация OpenAPI-схемы, кастомизация документации, Swagger UI, Redoc, аннотации для API
Автоматическая генерация OpenAPI-схемы, Swagger UI, Redoc, кастомизация документации
Starlite автоматически генерирует OpenAPI-схему на основе:
По умолчанию доступны следующие эндпоинты:
GET /schema/openapi.json # JSON-схема OpenAPI
GET /schema/openapi.yaml # YAML-схема OpenAPI
GET /schema/swagger # Swagger UI интерфейс
GET /schema/redoc # Redoc интерфейс
GET /schema/rapidoc # RapiDoc интерфейс
GET /schema/oauth2-redirect.html # OAuth2 redirect
from starlite import Starlite, get, post
from pydantic import BaseModel
class User(BaseModel):
id: int
name: str
email: str
class UserCreate(BaseModel):
name: str
email: str
@get("/users/{user_id:int}")
def get_user(user_id: int) -> User:
"""Get user by ID"""
...
@post("/users")
def create_user(data: UserCreate) -> User:
"""Create a new user"""
...
app = Starlite(route_handlers=[get_user, create_user])from starlite import get
@get(
"/users/{user_id:int}",
summary="Get user by ID",
description="Retrieves a single user by their unique identifier",
tags=["users"],
operation_id="getUserById",
deprecated=False,
)
def get_user(user_id: int) -> User:
...| Параметр | Описание |
|---|---|
summary | Краткое описание (одна строка) |
description | Подробное описание (поддерживает Markdown) |
tags | Теги для группировки операций |
operation_id | Уникальный ID операции |
deprecated | Пометить как устаревший |
@get(
"/users",
summary="List all users",
description="""
Returns a paginated list of users.
**Permissions:**
- Admin: full access
- User: own data only
**Response format:**
- `items`: array of users
- `total`: total count
- `page`: current page
""",
)
def list_users() -> list[User]:
...from starlite import get, Query
@get("/items")
def list_items(
page: int = Query(
ge=1,
le=1000,
default=1,
description="Page number",
),
page_size: int = Query(
ge=1,
le=100,
default=20,
description="Items per page",
),
search: str | None = Query(
default=None,
description="Search query",
),
) -> list[Item]:
"""
List items with pagination and search.
"""
...from starlite import get
@get("/users/{user_id:int}")
def get_user(
user_id: int, # Автоматически добавляется в схему
) -> User:
"""
Get user by ID.
Args:
user_id: Unique user identifier
"""
...from starlite import get, Header
@get("/protected")
def protected_route(
x_api_key: str = Header(
header="X-API-Key",
description="API key for authentication",
),
) -> dict:
...from starlite import get, ResponseSpec
@get(
"/users/{user_id:int}",
responses={
200: ResponseSpec(User, description="User found"),
404: ResponseSpec(description="User not found"),
},
)
def get_user(user_id: int) -> User:
...from starlite import get, ResponseSpec
@get(
"/search",
responses={
200: ResponseSpec(list[User], description="Search results"),
400: ResponseSpec(description="Invalid query"),
403: ResponseSpec(description="Access denied"),
},
)
def search_users(q: str) -> list[User]:
...from starlite import OpenAPIConfig, Starlite
openapi_config = OpenAPIConfig(
title="My API",
version="1.0.0",
description="API documentation for My Application",
contact={
"name": "Support",
"email": "support@example.com",
"url": "https://example.com/support",
},
license={
"name": "MIT",
"url": "https://opensource.org/licenses/MIT",
},
)
app = Starlite(
route_handlers=[...],
openapi_config=openapi_config,
)from starlite import OpenAPIConfig
openapi_config = OpenAPIConfig(
title="My API",
version="1.0.0",
description="Comprehensive API documentation",
contact={"email": "support@example.com"},
license={"name": "MIT"},
terms_of_service="https://example.com/terms",
external_docs={
"description": "Full documentation",
"url": "https://docs.example.com",
},
security=[{"BearerAuth": []}],
)from starlite import OpenAPIConfig, SecurityScheme
openapi_config = OpenAPIConfig(
title="My API",
version="1.0.0",
security=[{"BearerAuth": []}],
components={
"securitySchemes": {
"BearerAuth": SecurityScheme(
type="http",
scheme="bearer",
bearerFormat="JWT",
description="Enter your JWT token",
),
},
},
)from starlite import OpenAPIConfig, SecurityScheme
openapi_config = OpenAPIConfig(
title="My API",
version="1.0.0",
security=[{"ApiKeyAuth": []}],
components={
"securitySchemes": {
"ApiKeyAuth": SecurityScheme(
type="apiKey",
name="X-API-Key",
in_="header",
description="API key passed in X-API-Key header",
),
},
},
)from starlite import OpenAPIConfig, SecurityScheme, OAuth2Config
oauth2_config = OAuth2Config(
authorizationUrl="https://auth.example.com/oauth/authorize",
tokenUrl="https://auth.example.com/oauth/token",
scopes={
"read": "Read access",
"write": "Write access",
"admin": "Admin access",
},
)
openapi_config = OpenAPIConfig(
title="My API",
version="1.0.0",
security=[{"OAuth2": ["read"]}],
components={
"securitySchemes": {
"OAuth2": SecurityScheme(
type="oauth2",
description="OAuth2 authentication",
flows=oauth2_config,
),
},
},
)from starlite import OpenAPIConfig, SwaggerUIConfig
openapi_config = OpenAPIConfig(
title="My API",
version="1.0.0",
swagger_ui_config=SwaggerUIConfig(
doc_expansion="none",
display_operation_id=True,
filter=True,
show_common_extensions=True,
oauth2_redirect_url="/schema/oauth2-redirect.html",
),
)from starlite import OpenAPIConfig
openapi_config = OpenAPIConfig(
title="My API",
version="1.0.0",
swagger_ui=None, # Отключить Swagger UI
redoc_ui=None, # Отключить Redoc
)from starlite import OpenAPIConfig
openapi_config = OpenAPIConfig(
title="My API",
version="1.0.0",
path="/docs", # Вместо /schema
)
# Доступно по:
# GET /docs/openapi.json
# GET /docs/swagger
# GET /docs/redocfrom starlite import get, RequestEncoding
@get(
"/users",
examples=[
{
"summary": "Default pagination",
"value": {"page": 1, "page_size": 20},
},
{
"summary": "Search query",
"value": {"page": 1, "page_size": 50, "search": "john"},
},
],
)
def list_users(
page: int = 1,
page_size: int = 20,
search: str | None = None,
) -> list[User]:
...from starlite import get, ResponseSpec, Example
@get(
"/users/{user_id:int}",
responses={
200: ResponseSpec(
User,
examples=[
Example(
summary="Standard user",
value={
"id": 1,
"name": "John Doe",
"email": "john@example.com",
},
),
Example(
summary="Admin user",
value={
"id": 2,
"name": "Admin",
"email": "admin@example.com",
},
),
],
),
},
)
def get_user(user_id: int) -> User:
...@get("/users", tags=["users"])
def list_users() -> list[User]:
...
@post("/users", tags=["users"])
def create_user(data: UserCreate) -> User:
...
@get("/items", tags=["items"])
def list_items() -> list[Item]:
...
@get("/orders", tags=["orders"])
def list_orders() -> list[Order]:
...from starlite import OpenAPIConfig, Tag
openapi_config = OpenAPIConfig(
title="My API",
version="1.0.0",
tags=[
Tag(name="users", description="User management endpoints"),
Tag(name="items", description="Item catalog endpoints"),
Tag(name="orders", description="Order processing endpoints"),
],
)# ✅ Хорошо
@get(
"/users/{user_id:int}",
summary="Get user by ID",
description="Retrieves a single user by their unique identifier",
)
def get_user(user_id: int) -> User:
...
# ❌ Плохо — нет описания
@get("/users/{user_id:int}")
def get_user(user_id: int) -> User:
...# ✅ Хорошо
@get("/users", tags=["users"])
@post("/users", tags=["users"])
@get("/items", tags=["items"])
# ❌ Плохо — нет тегов
@get("/users")
@post("/users")# ✅ Хорошо
@get("/users/{user_id:int}", operation_id="getUserById")
def get_user(user_id: int) -> User:
...
# ❌ Плохо — автогенерируемый ID
@get("/users/{user_id:int}")
def get_user(user_id: int) -> User:
...# ✅ Хорошо
@get(
"/users/{user_id:int}",
responses={
200: ResponseSpec(User, description="User found"),
404: ResponseSpec(description="User not found"),
},
)
def get_user(user_id: int) -> User:
...
# ❌ Плохо — только успешный ответ
@get("/users/{user_id:int}")
def get_user(user_id: int) -> User:
...# ✅ Хорошо — с примерами
@get(
"/items",
examples=[
{"summary": "Default", "value": {"page": 1, "page_size": 20}},
],
)
def list_items(page: int = 1, page_size: int = 20) -> list[Item]:
...
# ❌ Плохо — без примеров
@get("/items")
def list_items(page: int = 1, page_size: int = 20) -> list[Item]:
...OpenAPI возможности Starlite включают:
В следующей теме мы изучим тестирование приложений.
Вопросы ещё не добавлены
Вопросы для этой подтемы ещё не добавлены.