FastAPI: подробное руководство по основным сущностям
FastAPI — это мощный и интуитивно понятный фреймворк для создания современных веб-API на Python, который завоевал популярность среди разработчиков благодаря своей скорости, удобству и гибкости. Он позволяет легко создавать надёжные и масштабируемые API, автоматически проверять данные и генерировать удобную документацию. Одним из ключевых преимуществ FastAPI является простота работы с различными типами данных и параметрами, что делает фреймворк подходящим как для небольших, так и для крупных проектов.
Мы уже ознакомились с базовыми принципами FastAPI тут: FastAPI для начинающих: простое руководство по созданию быстрых API, а в этом руководстве мы подробно разберём основные сущности FastAPI, которые делают разработку API удобной и предсказуемой. Мы охватим:
- Path Parameters (Параметры пути): доступ к ресурсам через значения, передаваемые в URL.
- Query Parameters (Параметры запроса): фильтрация и обработка данных через параметры, передаваемые после
?
. - Request Body (Тело запроса): передача данных в формате JSON для взаимодействия с API.
- Validation (Валидация): использование встроенной валидации для строковых и числовых параметров.
- Nested Models (Вложенные модели): создание сложных JSON-структур с помощью вложенных моделей.
- Header Parameters и Cookie Parameters (Параметры заголовков и cookies): извлечение и использование данных из заголовков и cookies для настройки запросов.
- Response Models (Модели ответа): использование моделей для структурирования и проверки ответа.
- Form Data и File Uploads (Данные форм и загрузка файлов): работа с формами и обработка загружаемых файлов.
- Handling Errors (Обработка ошибок): создание кастомных ошибок для более информативных ответов.
- Path Operation Configuration (Конфигурация операций маршрута): добавление тегов, описаний и статусов ответов для улучшения документации и структуры API.
Каждая из этих сущностей позволяет FastAPI упрощать и автоматизировать задачи, которые раньше требовали бы более сложных решений. В этом руководстве вы узнаете, как использовать эти возможности для создания API, которые легко масштабировать, поддерживать и тестировать. Мы будем использовать простые примеры и рассматривать наиболее распространённые задачи, чтобы максимально упростить ваш путь к освоению FastAPI.
Присоединяйтесь к нам в этом путешествии по FastAPI и убедитесь, что создание API может быть лёгким и увлекательным! 🐱
Часть 1: Параметры пути и запроса в FastAPI
FastAPI делает работу с параметрами API удобной и безопасной. Вы можете передавать данные через URL, используя параметры пути или параметры запроса, и получать доступ к этим данным в обработчиках. В этой части мы разберём, как использовать Path Parameters и Query Parameters в FastAPI.
1. Path Parameters (Параметры пути)
Path Parameters (Параметры пути) — это значения, которые передаются непосредственно в URL. Они используются для доступа к конкретным ресурсам и обычно являются обязательными. FastAPI позволяет удобно и безопасно получать значения этих параметров и автоматически проводить валидацию типов данных.
Пример
В следующем примере мы создадим маршрут /items/{item_id}
, где item_id
— это параметр пути, представляющий идентификатор элемента.
from fastapi import FastAPI app = FastAPI() @app.get("/items/{item_id}") def read_item(item_id: int): return {"item_id": item_id}
Объяснение кода
- В функции
read_item
параметрitem_id
автоматически извлекается из URL и приводится к целому числу (int
). - Если клиент отправляет запрос
GET /items/5
, FastAPI интерпретирует5
как значение дляitem_id
и возвращает его в виде JSON.
Преимущества Path Parameters
- Простота доступа: вы можете получать данные непосредственно из URL.
- Валидация типов данных: FastAPI автоматически проверит, что
item_id
является числом, и вернёт ошибку, если это не так.
Path Parameters особенно полезны для доступа к отдельным ресурсам, например, к товарам по их ID или пользователям по их уникальному идентификатору.
2. Query Parameters (Параметры запроса)
Query Parameters (Параметры запроса) передаются после символа ?
в URL. Они обычно используются для передачи дополнительных параметров, которые могут быть необязательными, и их можно комбинировать для настройки вывода, фильтрации или пагинации.
Пример
В следующем примере мы добавим маршрут /items/
, который принимает параметры skip
и limit
. Эти параметры полезны для реализации пагинации (например, пропуска первых элементов и ограничения количества).
@app.get("/items/") def read_items(skip: int = 0, limit: int = 10): return {"skip": skip, "limit": limit}
Объяснение кода
skip
иlimit
— это необязательные параметры запроса с заданными значениями по умолчанию (0
и10
соответственно).- При отправке запроса
GET /items?skip=5&limit=20
FastAPI автоматически присвоитskip=5
иlimit=20
.
Преимущества Query Parameters
- Гибкость: параметры запроса можно легко настраивать, что упрощает добавление фильтрации и сортировки данных.
- Необязательные параметры: задав значения по умолчанию, можно сделать параметры необязательными.
Query Parameters позволяют создавать более гибкие маршруты, добавляя возможности фильтрации, сортировки и настройки запроса.
Часть 2: Работа с телом запроса и валидацией в FastAPI
В этой части мы рассмотрим, как передавать данные через Request Body (Тело запроса) и использовать встроенные возможности валидации FastAPI для работы со строками и числами. Мы также разберём, как использовать модели данных, чтобы сделать код более структурированным и безопасным.
3. Request Body (Тело запроса)
Request Body — это основная часть запроса, которая используется для передачи данных в формате JSON. В FastAPI для описания и валидации структуры данных, отправляемых в теле запроса, удобно использовать модели данных Pydantic. Это позволяет автоматически проверять данные и создавать документацию API.
Пример
Допустим, мы создаём API для управления товарами. Мы определим модель Item
, которая описывает структуру товара, и будем использовать её для получения данных в теле запроса.
from fastapi import FastAPI from pydantic import BaseModel app = FastAPI() class Item(BaseModel): name: str price: float @app.post("/items/") def create_item(item: Item): return {"name": item.name, "price": item.price}
Объяснение кода
- Модель
Item
, унаследованная отBaseModel
, содержит два поля:name
иprice
. - Когда клиент отправляет запрос
POST /items/
с JSON-данными, FastAPI автоматически преобразует их в объектItem
. - Данные проверяются на соответствие типам (
name
— строка,price
— число с плавающей точкой), и в случае несоответствия клиенту будет возвращена ошибка.
Преимущества использования Request Body и моделей
- Автоматическая валидация данных: FastAPI проверит соответствие типов данных, определённых в модели.
- Чистый и понятный код: модели помогают структурировать код и избегать ошибок при обработке данных.
4. Query Parameters and String Validations (Параметры запроса и валидация строк)
В FastAPI можно уточнять требования к значениям Query Parameters с помощью дополнительных параметров валидации. Например, можно указать минимальную и максимальную длину строки, задать регулярные выражения или обозначить значение по умолчанию.
Пример
В следующем примере мы добавим параметр запроса q
, который должен быть строкой с минимальной длиной 3 символа и максимальной длиной 50 символов.
from fastapi import Query @app.get("/items/") def read_items(q: str = Query(..., min_length=3, max_length=50)): return {"q": q}
Объяснение кода
- Параметр
q
передаётся через запрос, и с помощьюQuery
мы указываем минимальную и максимальную длину строки. - Значение
...
указывает, что параметрq
является обязательным. - Если длина строки не соответствует требованиям, FastAPI вернёт сообщение об ошибке.
Дополнительные возможности валидации строк
Кроме длины строки, Query
позволяет задать регулярные выражения для валидации:
@app.get("/items/") def read_items(q: str = Query(..., regex="^fixed_")): return {"q": q}
Здесь q
должно начинаться с префикса "fixed_"
, и запросы, которые не соответствуют этому шаблону, вызовут ошибку.
5. Path Parameters and Numeric Validations (Параметры пути и числовая валидация)
FastAPI также поддерживает валидацию числовых значений для Path Parameters. Это полезно для ограничения допустимых значений и обеспечения корректности данных.
Пример
В следующем примере мы зададим ограничение для параметра item_id
, который должен быть числом от 1 до 100.
from fastapi import Path @app.get("/items/{item_id}") def read_item(item_id: int = Path(..., ge=1, le=100)): return {"item_id": item_id}
Объяснение кода
item_id
— это числовой параметр пути, который должен быть не меньше 1 (ge=1
) и не больше 100 (le=100
).- FastAPI проверит, что значение находится в допустимом диапазоне, и вернёт ошибку, если это не так.
Преимущества числовой валидации Path Parameters
- Контроль над значениями: можно предотвратить передачу некорректных значений, которые могли бы вызвать ошибки.
- Улучшение безопасности: позволяет избегать неожиданных значений, которые могут вызвать проблемы при обработке.
Часть 3: Модели параметров запроса и тела запроса
В этой части мы разберём более сложные возможности FastAPI, такие как использование Query Parameter Models (Модели параметров запроса) и Body - Multiple Parameters (Тело запроса - Несколько параметров). Эти инструменты позволяют структурировать код и управлять данными запросов более гибко.
6. Query Parameter Models (Модели параметров запроса)
Для сложных запросов, которые содержат несколько параметров, FastAPI позволяет использовать модели Pydantic, чтобы сделать код более структурированным и удобным для поддержки. Модель параметров запроса упрощает передачу нескольких параметров и позволяет добавлять валидацию.
Пример
В этом примере мы создадим модель FilterParams
, которая включает параметры q
и limit
. Эта модель будет использоваться как зависимость в маршруте.
from fastapi import Depends from pydantic import BaseModel class FilterParams(BaseModel): q: str limit: int = 10 @app.get("/items/") def read_items(filters: FilterParams = Depends()): return filters
Объяснение кода
FilterParams
— это модель Pydantic, описывающая структуру параметров запроса с полямиq
иlimit
.Depends()
позволяет передать объектFilterParams
как зависимость. FastAPI автоматически создаст экземпляр этой модели и проверит параметры запроса, если они присутствуют.
Преимущества использования моделей параметров запроса
- Чистота кода: использование модели помогает избежать большого количества параметров в функции.
- Автоматическая валидация: параметры будут автоматически проверены на соответствие типам.
- Удобство использования в документации: FastAPI автоматически генерирует документацию для модели.
Модели параметров запроса идеально подходят для ситуаций, когда нужно передать и валидировать несколько параметров, таких как фильтры и настройки.
7. Body - Multiple Parameters (Тело запроса - Несколько параметров)
FastAPI позволяет передавать несколько параметров через тело запроса и объединять их с параметрами пути и запроса. Это полезно для обработки сложных запросов, в которых сочетаются разные типы данных.
Пример
В этом примере мы создаём маршрут, который принимает item_id
как Path Parameter, а также name
и price
как параметры тела запроса.
from fastapi import Body @app.put("/items/{item_id}") def update_item(item_id: int, name: str = Body(...), price: float = Body(...)): return {"item_id": item_id, "name": name, "price": price}
Объяснение кода
- Параметр
item_id
передаётся через путь, аname
иprice
— через тело запроса. Body(...)
указывает FastAPI, что эти параметры находятся в теле запроса и являются обязательными.
Преимущества использования нескольких параметров тела
- Гибкость: можно комбинировать данные из разных источников (путь, тело, параметры запроса).
- Чистота кода: параметры, определённые через
Body
, остаются структурированными и удобными для чтения.
8. Body - Fields (Поля тела запроса)
В FastAPI вы можете использовать Field
, чтобы уточнить настройки и описание каждого поля в модели Pydantic. Это помогает добавлять дополнительные условия, такие как диапазон значений, и улучшать документацию.
Пример
В следующем примере мы определим модель Item
, добавив к полям name
и price
условия валидации и описание.
from pydantic import BaseModel, Field class Item(BaseModel): name: str = Field(..., title="Name of the item", min_length=3, max_length=50) price: float = Field(..., gt=0, description="Price must be greater than zero") @app.post("/items/") def create_item(item: Item): return item
Объяснение кода
- Поле
name
имеет ограничения по длине строки (от 3 до 50 символов), а также заголовок (title
) для улучшения документации. - Поле
price
проверяется на положительное значение (должно быть больше 0) и снабжено описанием (description
).
Преимущества использования Field
- Дополнительная валидация: позволяет задать более точные условия для каждого поля.
- Документация: FastAPI автоматически добавляет описания и ограничения в документацию API.
9. Body - Nested Models (Вложенные модели в теле запроса)
FastAPI поддерживает вложенные структуры данных, что удобно для создания сложных JSON-объектов. Вложенные модели помогают организовать данные и повысить читаемость кода.
Пример
В этом примере мы создадим модель Owner
, которая будет вложена в модель Item
, чтобы описать структуру владельца товара.
class Owner(BaseModel): name: str age: int class Item(BaseModel): name: str price: float owner: Owner @app.post("/items/") def create_item(item: Item): return item
Объяснение кода
Owner
— это отдельная модель, описывающая владельца товара.Item
включает полеowner
, которое является экземпляром моделиOwner
.
Преимущества использования вложенных моделей
- Организация данных: позволяет создавать сложные JSON-структуры с вложенными объектами.
- Автоматическая валидация всех уровней: FastAPI проверяет как основную модель, так и вложенные модели.
- Удобная работа с данными: вложенные модели делают код более читаемым и логичным.
Часть 4: Примеры данных, дополнительные типы данных и работа с cookies и заголовками
FastAPI предоставляет богатые возможности для улучшения документации и работы с различными типами данных, а также для использования cookies и заголовков в запросах. В этой части мы разберёмся, как задавать примеры данных, использовать дополнительные типы данных и работать с cookies и заголовками HTTP.
10. Declare Request Example Data (Объявление примеров данных запроса)
FastAPI позволяет добавлять примеры данных к моделям, что делает документацию более наглядной. Примеры данных помогают разработчикам API понять, какой формат данных ожидается при использовании эндпоинта.
Пример
В этом примере мы добавим пример данных к модели Item
. Эти данные будут отображаться в документации FastAPI, и разработчики смогут легко понять структуру ожидаемого запроса.
from pydantic import BaseModel class Item(BaseModel): name: str price: float class Config: schema_extra = { "example": { "name": "Sample Item", "price": 19.99 } }
Объяснение кода
schema_extra
вConfig
позволяет задать пример данных.- Этот пример отображается в документации
/docs
и показывает ожидаемую структуру и значения.
Преимущества объявления примеров данных
- Улучшение документации: примеры делают документацию более наглядной.
- Удобство для разработчиков: показывает формат и структуру данных, упрощая использование API.
11. Extra Data Types (Дополнительные типы данных)
FastAPI поддерживает дополнительные типы данных, такие как datetime
, UUID
, Decimal
и другие, что позволяет более точно описывать данные и автоматизировать их проверку.
Пример
В этом примере мы добавим параметры типа datetime
и UUID
к модели Event
, чтобы описать событие с точной датой и уникальным идентификатором.
from datetime import datetime from uuid import UUID from pydantic import BaseModel class Event(BaseModel): id: UUID timestamp: datetime name: str
Объяснение кода
UUID
используется для создания уникальных идентификаторов.datetime
позволяет задавать временные метки.
Преимущества использования дополнительных типов данных
- Точность данных: позволяет точнее описывать структуры и уменьшает вероятность ошибок.
- Автоматическая валидация: FastAPI автоматически проверяет формат данных, таких как
datetime
иUUID
.
12. Cookie Parameters (Параметры cookies)
Cookies часто используются для хранения данных на стороне клиента, таких как сессии и настройки пользователя. FastAPI позволяет получать значения cookies в эндпоинтах с помощью Cookie
.
Пример использования
В этом примере мы используем параметр session_id
, чтобы прочитать его из cookies.
from fastapi import Cookie @app.get("/items/") def read_items(session_id: str = Cookie(None)): return {"session_id": session_id}
Объяснение кода
session_id
извлекается из cookies.- Значение cookies доступно в обработчике, и вы можете использовать его для проверки состояния сессии или настройки пользователя.
Преимущества использования Cookie Parameters
- Работа с сессиями: удобный способ отслеживать пользователей и их состояние.
- Простота валидации: FastAPI автоматически обрабатывает и проверяет cookies.
13. Header Parameters (Параметры заголовка)
Заголовки HTTP часто содержат полезную информацию, такую как User-Agent
, токены аутентификации и другую служебную информацию. FastAPI позволяет получать значения заголовков с помощью Header
.
Пример использования
В этом примере мы извлекаем значение заголовка User-Agent
для анализа информации о клиенте.
from fastapi import Header @app.get("/items/") def read_items(user_agent: str = Header(None)): return {"User-Agent": user_agent}
Объяснение кода
user_agent
передаётся в обработчик как параметрHeader
.- FastAPI автоматически извлекает заголовок
User-Agent
и передаёт его в функцию.
Преимущества использования Header Parameters
- Получение информации о клиенте: помогает анализировать тип устройства или браузера пользователя.
- Работа с аутентификацией: заголовки могут содержать токены или ключи для авторизации запросов.
Часть 5: Модели ответа, статусные коды, данные форм и загрузка файлов
В этой части мы рассмотрим, как структурировать ответы API, использовать модели для описания возвращаемых данных, управлять статусными кодами и работать с данными форм и загрузкой файлов. Эти функции позволяют сделать API более информативным, надёжным и удобным для использования.
14. Response Model - Return Type (Модель ответа - Тип возвращаемого значения)
FastAPI позволяет описывать структуру ответа с помощью моделей Pydantic, что помогает явно указать, какие данные возвращаются из эндпоинта. Модели ответа также позволяют автоматически валидировать и форматировать данные перед отправкой клиенту.
Пример
В этом примере мы создадим модель Item
, которая будет использоваться как ответ на запрос.
from fastapi import FastAPI from pydantic import BaseModel app = FastAPI() class Item(BaseModel): name: str price: float @app.get("/items/{item_id}", response_model=Item) def read_item(item_id: int): return Item(name="Sample Item", price=20.0)
Объяснение кода
- Модель
Item
описывает структуру данных, возвращаемую из эндпоинта. - Параметр
response_model=Item
указывает FastAPI использовать эту модель для валидации и форматирования ответа.
Преимущества использования моделей ответа
- Единая структура ответов: позволяет клиентам легко понять формат данных.
- Автоматическая валидация: FastAPI проверяет соответствие возвращаемых данных модели, предотвращая непредвиденные ошибки.
15. Response Status Code (Код состояния ответа)
FastAPI позволяет указывать статусные коды HTTP для эндпоинтов. Это полезно для обозначения успешности или ошибки запроса. Например, для создания ресурса можно использовать код 201 Created
.
Пример
В следующем примере мы укажем статусный код 201
для эндпоинта, который создаёт элемент.
from fastapi import status @app.post("/items/", response_model=Item, status_code=status.HTTP_201_CREATED) def create_item(item: Item): return item
Объяснение кода
status_code=status.HTTP_201_CREATED
указывает, что запрос завершился успешно и новый ресурс был создан.- FastAPI автоматически добавит этот статусный код в ответ.
Преимущества использования статусных кодов
- Информативность: клиенты получают точные статусы ответов и могут обрабатывать их соответствующим образом.
- Лучшая совместимость с REST: использование правильных кодов делает API более предсказуемым и стандартизированным.
16. Form Data (Формы с данными)
FastAPI позволяет передавать данные в формате форм, что полезно для работы с HTML-формами или другими клиентами, которые используют кодировку application/x-www-form-urlencoded
. Для работы с данными формы используется класс Form
.
Пример использования
В этом примере мы создадим эндпоинт для обработки формы входа с полями username
и password
.
from fastapi import Form @app.post("/login/") def login(username: str = Form(...), password: str = Form(...)): return {"username": username}
Объяснение кода
Form(...)
указывает, что данные будут получены из формы.- Поля
username
иpassword
обязательны, так как...
(три точки) обозначают отсутствие значения по умолчанию.
Преимущества использования Form Data
- Поддержка HTML-форм: можно легко работать с формами, отправленными из веб-интерфейса.
- Простота настройки: FastAPI автоматически обрабатывает данные формы и проверяет их.
17. Form Models (Модели форм)
Для более сложных форм можно создать отдельные модели Pydantic, которые будут описывать структуру данных формы. Это помогает сделать код более чистым и поддерживаемым.
Пример использования
В этом примере мы создаём модель LoginForm
, чтобы описать структуру данных для формы входа.
from pydantic import BaseModel class LoginForm(BaseModel): username: str password: str @app.post("/login/") def login(form_data: LoginForm = Depends()): return {"username": form_data.username}
18. Request Files (Файлы в запросаз)
FastAPI поддерживает загрузку файлов с помощью File
. Это позволяет принимать файлы в запросах и обрабатывать их в API. Загрузка файлов может использоваться для различных целей, таких как отправка изображений, документов и других данных.
Пример использования
В этом примере мы создаём эндпоинт, который принимает файл и возвращает его имя.
from fastapi import File, UploadFile @app.post("/upload/") def upload_file(file: UploadFile = File(...)): return {"filename": file.filename}
Объяснение кода
UploadFile
— это класс, который позволяет получать информацию о файле и его содержимое.File(...)
указывает, что параметр будет получен из файла запроса.
Преимущества использования Request Files
- Удобная работа с файлами: можно легко загружать и обрабатывать файлы в API.
- Асинхронная обработка:
UploadFile
поддерживает асинхронные операции, что повышает производительность при работе с большими файлами.
19. Request Forms and Files (Запросы с формами и файлами)
FastAPI позволяет одновременно обрабатывать данные формы и файлы в одном запросе. Это полезно для работы с формами, которые содержат как текстовые поля, так и файлы.
Пример использования
В этом примере мы создаём эндпоинт для загрузки файла с описанием, передаваемым через поле формы.
from fastapi import Form @app.post("/upload/") def upload_file(file: UploadFile = File(...), description: str = Form(...)): return {"filename": file.filename, "description": description}
Объяснение кода
File(...)
указывает FastAPI, что параметрfile
передаётся как файл.Form(...)
указывает, что параметрdescription
передаётся как текстовое поле формы.