# Структура документа
https://habr.com/ru/articles/776538/
# Как тестировать
https://editor.swagger.io/
# Пример формата openapi
```
{
"openapi": "3.0.0",
"info": {
"title": "Sample API with Pydantic",
"version": "1.0.0"
},
"paths": {
"/items": {
"post": {
"summary": "Create a new item",
"requestBody": {
"required": True,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ItemInputModel"
}
}
}
},
"responses": {
"201": {
"description": "Item created successfully"
},
"400": {
"description": "Invalid input data"
}
}
}
}
},
"components": {
"schemas": {
"ItemInputModel": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"description": {
"type": "string"
}
},
"required": ["name"]
}
}
}
}
```
Генерация json
```
def generate_openapi_spec():
spec = {
"openapi": "3.0.0",
"info": {
"title": "Sample API with Pydantic",
"version": "1.0.0"
},
"paths": {},
"components": {
"schemas": {}
}
}
for rule in app.url_map.iter_rules():
if rule.endpoint != 'static':
spec["paths"][rule.rule] = {}
for method in rule.methods - {'OPTIONS', 'HEAD'}:
view_function = app.view_functions[rule.endpoint]
spec["paths"][rule.rule][method.lower()] = {
"summary": view_function.__doc__,
"responses": {
"200": {
"description": "Successful operation"
}
}
}
# Добавляем параметры запроса, если они есть
parameters = []
for param in rule.arguments:
parameters.append({
"name": param,
"in": "path",
"required": True,
"schema": {
"type": "string"
}
})
if parameters:
spec["paths"][rule.rule][method.lower()]["parameters"] = parameters
```
```
class Item(BaseModel):
name: str
description: Union[str, None] = None
price: float
tax: Union[float, None] = None
class AnotherModel(BaseModel):
field1: str
field2: int
def extract_args(model_cls):
@wraps(func)
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
# Извлекаем аргументы из URL
args_dict = request.args.to_dict()
# Получаем параметры функции
func_params = list(func.__annotations__.keys())
# Извлекаем только те аргументы, которые принимает функция
extracted_args = {k: v for k, v in args_dict.items() if
k in func_params}
# Создаем экземпляр модели из данных JSON
json_data = request.json if request.is_json else None
model_instance = model_cls(**json_data) if json_data else None
# Передаем аргументы в функцию
return func(*args, **kwargs, **extracted_args,
model=model_instance)
return wrapper
return decorator
@app.route('/process', methods=['GET', 'POST'])
@extract_args(Item)
def process(arg1: int, arg2: int, model: Union[Item, AnotherModel] = None):
if isinstance(model, Item):
return jsonify({"arg1": arg1, "arg2": arg2, "item": model.dict()})
elif isinstance(model, AnotherModel):
return jsonify(
{"arg1": arg1, "arg2": arg2, "another_model": model.dict()})
else:
return jsonify({"arg1": arg1, "arg2": arg2})
```