Тіло запиту¶
Коли вам потрібно надіслати дані з клієнта (скажімо, браузера) до вашого API, ви надсилаєте їх як тіло запиту.
Тіло запиту — це дані, надіслані клієнтом до вашого API. Тіло відповіді — це дані, які ваш API надсилає клієнту.
Ваш API майже завжди має надсилати тіло відповіді. Але клієнтам не обов’язково потрібно постійно надсилати тіла запитів.
Щоб оголосити тіло запиту, ви використовуєте Pydantic моделі з усією їх потужністю та перевагами.
Info
Щоб надіслати дані, ви повинні використовувати один із: POST
(більш поширений), PUT
, DELETE
або PATCH
.
Надсилання тіла із запитом GET
має невизначену поведінку в специфікаціях, проте воно підтримується FastAPI лише для дуже складних/екстремальних випадків використання.
Оскільки це не рекомендується, інтерактивна документація з Swagger UI не відображатиме документацію для тіла запиту під час використання GET
, і проксі-сервери в середині можуть не підтримувати її.
Імпортуйте BaseModel
від Pydantic¶
Спочатку вам потрібно імпортувати BaseModel
з pydantic
:
from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: Union[str, None] = None
price: float
tax: Union[float, None] = None
app = FastAPI()
@app.post("/items/")
async def create_item(item: Item):
return item
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
app = FastAPI()
@app.post("/items/")
async def create_item(item: Item):
return item
Створіть свою модель даних¶
Потім ви оголошуєте свою модель даних як клас, який успадковується від BaseModel
.
Використовуйте стандартні типи Python для всіх атрибутів:
from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: Union[str, None] = None
price: float
tax: Union[float, None] = None
app = FastAPI()
@app.post("/items/")
async def create_item(item: Item):
return item
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
app = FastAPI()
@app.post("/items/")
async def create_item(item: Item):
return item
Так само, як і при оголошенні параметрів запиту, коли атрибут моделі має значення за замовчуванням, він не є обов’язковим. В іншому випадку це потрібно. Використовуйте None
, щоб зробити його необов'язковим.
Наприклад, ця модель вище оголошує JSON "об'єкт
" (або Python dict
), як:
{
"name": "Foo",
"description": "An optional description",
"price": 45.2,
"tax": 3.5
}
...оскільки description
і tax
є необов'язковими (зі значенням за замовчуванням None
), цей JSON "об'єкт
" також буде дійсним:
{
"name": "Foo",
"price": 45.2
}
Оголоси її як параметр¶
Щоб додати модель даних до вашої операції шляху, оголосіть її так само, як ви оголосили параметри шляху та запиту:
from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: Union[str, None] = None
price: float
tax: Union[float, None] = None
app = FastAPI()
@app.post("/items/")
async def create_item(item: Item):
return item
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
app = FastAPI()
@app.post("/items/")
async def create_item(item: Item):
return item
...і вкажіть її тип як модель, яку ви створили, Item
.
Результати¶
Лише з цим оголошенням типу Python FastAPI буде:
- Читати тіло запиту як JSON.
- Перетворювати відповідні типи (якщо потрібно).
- Валідувати дані.
- Якщо дані недійсні, він поверне гарну та чітку помилку, вказуючи, де саме і які дані були неправильними.
- Надавати отримані дані у параметрі
item
.- Оскільки ви оголосили його у функції як тип
Item
, ви також матимете всю підтримку редактора (автозаповнення, тощо) для всіх атрибутів та їх типів.
- Оскільки ви оголосили його у функції як тип
- Генерувати JSON Schema визначення для вашої моделі, ви також можете використовувати їх де завгодно, якщо це має сенс для вашого проекту.
- Ці схеми будуть частиною згенерованої схеми OpenAPI і використовуватимуться автоматичною документацією інтерфейсу користувача.
Автоматична документація¶
Схеми JSON ваших моделей будуть частиною вашої схеми, згенерованої OpenAPI, і будуть показані в інтерактивній API документації:
А також використовуватимуться в API документації всередині кожної операції шляху, якій вони потрібні:
Підтримка редактора¶
У вашому редакторі, всередині вашої функції, ви будете отримувати підказки типу та завершення скрізь (це б не сталося, якби ви отримали dict
замість моделі Pydantic):
Ви також отримуєте перевірку помилок на наявність операцій з неправильним типом:
Це не випадково, весь каркас був побудований навколо цього дизайну.
І він був ретельно перевірений на етапі проектування, перед будь-яким впровадженням, щоб переконатися, що він працюватиме з усіма редакторами.
Були навіть деякі зміни в самому Pydantic, щоб підтримати це.
Попередні скріншоти були зроблені у Visual Studio Code.
Але ви отримаєте ту саму підтримку редактора у PyCharm та більшість інших редакторів Python:
Tip
Якщо ви використовуєте PyCharm як ваш редактор, ви можете використати Pydantic PyCharm Plugin.
Він покращує підтримку редакторів для моделей Pydantic за допомогою:
- автозаповнення
- перевірки типу
- рефакторингу
- пошуку
- інспекції
Використовуйте модель¶
Усередині функції ви можете отримати прямий доступ до всіх атрибутів об’єкта моделі:
from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: Union[str, None] = None
price: float
tax: Union[float, None] = None
app = FastAPI()
@app.post("/items/")
async def create_item(item: Item):
item_dict = item.dict()
if item.tax:
price_with_tax = item.price + item.tax
item_dict.update({"price_with_tax": price_with_tax})
return item_dict
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
app = FastAPI()
@app.post("/items/")
async def create_item(item: Item):
item_dict = item.dict()
if item.tax:
price_with_tax = item.price + item.tax
item_dict.update({"price_with_tax": price_with_tax})
return item_dict
Тіло запиту + параметри шляху¶
Ви можете одночасно оголошувати параметри шляху та тіло запиту.
FastAPI розпізнає, що параметри функції, які відповідають параметрам шляху, мають бути взяті з шляху, а параметри функції, які оголошуються як моделі Pydantic, взяті з тіла запиту.
from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: Union[str, None] = None
price: float
tax: Union[float, None] = None
app = FastAPI()
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item):
return {"item_id": item_id, **item.dict()}
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
app = FastAPI()
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item):
return {"item_id": item_id, **item.dict()}
Тіло запиту + шлях + параметри запиту¶
Ви також можете оголосити параметри тіло, шлях і запит одночасно.
FastAPI розпізнає кожен з них і візьме дані з потрібного місця.
from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: Union[str, None] = None
price: float
tax: Union[float, None] = None
app = FastAPI()
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item, q: Union[str, None] = None):
result = {"item_id": item_id, **item.dict()}
if q:
result.update({"q": q})
return result
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
app = FastAPI()
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item, q: str | None = None):
result = {"item_id": item_id, **item.dict()}
if q:
result.update({"q": q})
return result
Параметри функції будуть розпізнаватися наступним чином:
- Якщо параметр також оголошено в шляху, він використовуватиметься як параметр шляху.
- Якщо параметр має сингулярний тип (наприклад,
int
,float
,str
,bool
тощо), він буде інтерпретуватися як параметр запиту. - Якщо параметр оголошується як тип Pydantic моделі, він інтерпретується як тіло запиту.
Note
FastAPI буде знати, що значення "q" не є обов'язковим через значення за замовчуванням "= None".
Optional
у Optional[str]
не використовується FastAPI, але дозволить вашому редактору надати вам кращу підтримку та виявляти помилки.
Без Pydantic¶
Якщо ви не хочете використовувати моделі Pydantic, ви також можете використовувати параметри Body. Перегляньте документацію для Тіло – Кілька параметрів: сингулярні значення в тілі.