29 KiB
FastAPI
Фреймворк FastAPI: высокая производительность, прост в изучении, быстрый в разработке, готов к продакшн
Документация: https://fastapi.tiangolo.com
Исходный код: https://github.com/fastapi/fastapi
FastAPI — это современный, быстрый (высокопроизводительный) веб-фреймворк для создания API на Python, основанный на стандартных аннотациях типов Python.
Ключевые особенности:
- Скорость: Очень высокая производительность, на уровне NodeJS и Go (благодаря Starlette и Pydantic). Один из самых быстрых доступных фреймворков Python.
- Быстрота разработки: Увеличьте скорость разработки фич примерно на 200–300%. *
- Меньше ошибок: Сократите примерно на 40% количество ошибок, вызванных человеком (разработчиком). *
- Интуитивность: Отличная поддержка редактора кода. Автозавершение везде. Меньше времени на отладку.
- Простота: Разработан так, чтобы его было легко использовать и осваивать. Меньше времени на чтение документации.
- Краткость: Минимизируйте дублирование кода. Несколько возможностей из каждого объявления параметров. Меньше ошибок.
- Надежность: Получите код, готовый к продакшн. С автоматической интерактивной документацией.
- На основе стандартов: Основан на открытых стандартах API и полностью совместим с ними: OpenAPI (ранее известный как Swagger) и JSON Schema.
* оценка на основе тестов внутренней команды разработчиков, создающих продакшн-приложения.
Спонсоры
{% if sponsors %} {% for sponsor in sponsors.gold -%} {% endfor -%} {%- for sponsor in sponsors.silver -%} {% endfor %} {% endif %}
Мнения
"[...] В последнее время я много где использую FastAPI. [...] На самом деле я планирую использовать его для всех ML-сервисов моей команды в Microsoft. Некоторые из них интегрируются в основной продукт Windows, а некоторые — в продукты Office."
"Мы начали использовать библиотеку FastAPI, чтобы поднять REST-сервер, к которому можно обращаться за предсказаниями. [для Ludwig]"
"Netflix рада объявить об открытом релизе нашего фреймворка оркестрации антикризисного управления: Dispatch! [создан с помощью FastAPI]"
"Я в полном восторге от FastAPI. Это так весело!"
"Честно говоря, то, что вы создали, выглядит очень солидно и отполировано. Во многих смыслах это то, чем я хотел видеть Hug — очень вдохновляет видеть, как кто-то это создал."
"Если вы хотите изучить один современный фреймворк для создания REST API, посмотрите FastAPI [...] Он быстрый, простой в использовании и лёгкий в изучении [...]"
"Мы переключились на FastAPI для наших API [...] Думаю, вам тоже понравится [...]"
"Если кто-то собирается делать продакшн-API на Python, я настоятельно рекомендую FastAPI. Он прекрасно спроектирован, прост в использовании и отлично масштабируется, стал ключевым компонентом нашей стратегии API-first и приводит в действие множество автоматизаций и сервисов, таких как наш Virtual TAC Engineer."
Typer, FastAPI для CLI
Если вы создаёте приложение CLI для использования в терминале вместо веб-API, посмотрите Typer.
Typer — младший брат FastAPI. И он задуман как FastAPI для CLI. ⌨️ 🚀
Зависимости
FastAPI стоит на плечах гигантов:
Установка
Создайте и активируйте виртуальное окружение, затем установите FastAPI:
$ pip install "fastapi[standard]"
---> 100%
Примечание: Обязательно заключите "fastapi[standard]"
в кавычки, чтобы это работало во всех терминалах.
Пример
Создание
Создайте файл main.py
со следующим содержимым:
from typing import Union
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello": "World"}
@app.get("/items/{item_id}")
def read_item(item_id: int, q: Union[str, None] = None):
return {"item_id": item_id, "q": q}
Или используйте async def
...
Если ваш код использует async
/ await
, используйте async def
:
from typing import Union
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def read_root():
return {"Hello": "World"}
@app.get("/items/{item_id}")
async def read_item(item_id: int, q: Union[str, None] = None):
return {"item_id": item_id, "q": q}
Примечание:
Если не уверены, посмотрите раздел «Нет времени?» о async
и await
в документации.
Запуск
Запустите сервер командой:
$ fastapi dev main.py
╭────────── FastAPI CLI - Development mode ───────────╮
│ │
│ Serving at: http://127.0.0.1:8000 │
│ │
│ API docs: http://127.0.0.1:8000/docs │
│ │
│ Running in development mode, for production use: │
│ │
│ fastapi run │
│ │
╰─────────────────────────────────────────────────────╯
INFO: Will watch for changes in these directories: ['/home/user/code/awesomeapp']
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO: Started reloader process [2248755] using WatchFiles
INFO: Started server process [2248757]
INFO: Waiting for application startup.
INFO: Application startup complete.
О команде fastapi dev main.py
...
Команда fastapi dev
читает ваш файл main.py
, находит в нём приложение FastAPI и запускает сервер с помощью Uvicorn.
По умолчанию fastapi dev
запускается с включённой авто-перезагрузкой для локальной разработки.
Подробнее в документации по FastAPI CLI.
Проверка
Откройте браузер на http://127.0.0.1:8000/items/5?q=somequery.
Вы увидите JSON-ответ:
{"item_id": 5, "q": "somequery"}
Вы уже создали API, который:
- Получает HTTP-запросы по путям
/
и/items/{item_id}
. - Оба пути используют
GET
операции (также известные как HTTP методы). - Путь
/items/{item_id}
имеет параметр путиitem_id
, который должен бытьint
. - Путь
/items/{item_id}
имеет необязательныйstr
параметр запросаq
.
Интерактивная документация API
Перейдите на http://127.0.0.1:8000/docs.
Вы увидите автоматическую интерактивную документацию API (предоставлена Swagger UI):
Альтернативная документация API
Теперь откройте http://127.0.0.1:8000/redoc.
Вы увидите альтернативную автоматическую документацию (предоставлена ReDoc):
Пример обновления
Теперь измените файл main.py
, чтобы принимать тело запроса из PUT
запроса.
Объявите тело, используя стандартные типы Python, спасибо Pydantic.
from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
price: float
is_offer: Union[bool, None] = None
@app.get("/")
def read_root():
return {"Hello": "World"}
@app.get("/items/{item_id}")
def read_item(item_id: int, q: Union[str, None] = None):
return {"item_id": item_id, "q": q}
@app.put("/items/{item_id}")
def update_item(item_id: int, item: Item):
return {"item_name": item.name, "item_id": item_id}
Сервер fastapi dev
должен перезагрузиться автоматически.
Обновление интерактивной документации API
Перейдите на http://127.0.0.1:8000/docs.
- Интерактивная документация API будет автоматически обновлена, включая новое тело:
- Нажмите кнопку «Try it out», это позволит вам заполнить параметры и напрямую взаимодействовать с API:
- Затем нажмите кнопку «Execute», интерфейс свяжется с вашим API, отправит параметры, получит результаты и отобразит их на экране:
Обновление альтернативной документации API
Теперь откройте http://127.0.0.1:8000/redoc.
- Альтернативная документация также отразит новый параметр запроса и тело:
Подведём итоги
Итак, вы объявляете один раз типы параметров, тела запроса и т.д. как параметры функции.
Вы делаете это с помощью стандартных современных типов Python.
Вам не нужно изучать новый синтаксис, методы или классы конкретной библиотеки и т.п.
Только стандартный Python.
Например, для int
:
item_id: int
или для более сложной модели Item
:
item: Item
...и с этим единственным объявлением вы получаете:
- Поддержку редактора кода, включая:
- Автозавершение.
- Проверку типов.
- Валидацию данных:
- Автоматические и понятные ошибки, когда данные некорректны.
- Валидацию даже для глубоко вложенных объектов JSON.
- Преобразование входных данных: из сети в данные и типы Python. Чтение из:
- JSON.
- Параметров пути.
- Параметров запроса.
- Cookies.
- HTTP-заголовков.
- Форм.
- Файлов.
- Преобразование выходных данных: из данных и типов Python в данные сети (например, JSON):
- Преобразование типов Python (
str
,int
,float
,bool
,list
и т.д.). - Объекты
datetime
. - Объекты
UUID
. - Модели баз данных.
- ...и многое другое.
- Преобразование типов Python (
- Автоматическую интерактивную документацию API, включая 2 альтернативных интерфейса:
- Swagger UI.
- ReDoc.
Возвращаясь к предыдущему примеру кода, FastAPI будет:
- Валидировать наличие
item_id
в пути дляGET
иPUT
запросов. - Валидировать, что
item_id
имеет типint
дляGET
иPUT
запросов.- Если это не так, клиент увидит полезную понятную ошибку.
- Проверять, есть ли необязательный параметр запроса с именем
q
(например,http://127.0.0.1:8000/items/foo?q=somequery
) дляGET
запросов.- Поскольку параметр
q
объявлен с= None
, он необязателен. - Без
None
он был бы обязательным (как тело запроса в случае сPUT
).
- Поскольку параметр
- Для
PUT
запросов к/items/{item_id}
читать тело запроса как JSON:- Проверять, что есть обязательный атрибут
name
, который должен бытьstr
. - Проверять, что есть обязательный атрибут
price
, который должен бытьfloat
. - Проверять, что есть необязательный атрибут
is_offer
, который должен бытьbool
, если он присутствует. - Всё это также будет работать для глубоко вложенных объектов JSON.
- Проверять, что есть обязательный атрибут
- Автоматически преобразовывать из и в JSON.
- Документировать всё с помощью OpenAPI, что может быть использовано:
- Системами интерактивной документации.
- Системами автоматической генерации клиентского кода для многих языков.
- Предоставлять 2 веб-интерфейса интерактивной документации напрямую.
Мы только поверхностно ознакомились, но вы уже понимаете, как всё это работает.
Попробуйте изменить строку:
return {"item_name": item.name, "item_id": item_id}
...из:
... "item_name": item.name ...
...на:
... "item_price": item.price ...
...и посмотрите, как ваш редактор кода будет автоматически дополнять атрибуты и знать их типы:
Более полный пример с дополнительными возможностями см. в Учебник - Руководство пользователя.
Осторожно, спойлер: учебник - руководство включает:
- Объявление параметров из других источников: HTTP-заголовки, cookies, поля формы и файлы.
- Как задать ограничения валидации вроде
maximum_length
илиregex
. - Очень мощную и простую в использовании систему внедрения зависимостей.
- Безопасность и аутентификацию, включая поддержку OAuth2 с JWT токенами и HTTP Basic аутентификацию.
- Более продвинутые (но столь же простые) приёмы объявления глубоко вложенных JSON-моделей (спасибо Pydantic).
- Интеграцию GraphQL с Strawberry и другими библиотеками.
- Множество дополнительных функций (благодаря Starlette), таких как:
- WebSockets
- чрезвычайно простые тесты на основе HTTPX и
pytest
- CORS
- сессии с использованием cookie
- ...и многое другое.
Производительность
Независимые бенчмарки TechEmpower показывают приложения FastAPI, работающие под управлением Uvicorn, как один из самых быстрых доступных фреймворков Python, уступающий только самим Starlette и Uvicorn (используются внутри FastAPI). (*)
Чтобы узнать больше, см. раздел Бенчмарки.
Зависимости
FastAPI зависит от Pydantic и Starlette.
Зависимости standard
Когда вы устанавливаете FastAPI с помощью pip install "fastapi[standard]"
, он идёт с группой опциональных зависимостей standard
:
Используется Pydantic:
email-validator
— для проверки адресов электронной почты.
Используется Starlette:
httpx
— обязателен, если вы хотите использоватьTestClient
.jinja2
— обязателен, если вы хотите использовать конфигурацию шаблонов по умолчанию.python-multipart
— обязателен, если вы хотите поддерживать «парсинг» форм черезrequest.form()
.
Используется FastAPI:
uvicorn
— сервер, который загружает и обслуживает ваше приложение. Включаетuvicorn[standard]
, содержащий некоторые зависимости (например,uvloop
), нужные для высокой производительности.fastapi-cli[standard]
— чтобы предоставить командуfastapi
.- Включает
fastapi-cloud-cli
, который позволяет развернуть ваше приложение FastAPI в FastAPI Cloud.
- Включает
Без зависимостей standard
Если вы не хотите включать опциональные зависимости standard
, можно установить pip install fastapi
вместо pip install "fastapi[standard]"
.
Без fastapi-cloud-cli
Если вы хотите установить FastAPI со стандартными зависимостями, но без fastapi-cloud-cli
, установите pip install "fastapi[standard-no-fastapi-cloud-cli]"
.
Дополнительные опциональные зависимости
Есть дополнительные зависимости, которые вы можете установить.
Дополнительные опциональные зависимости Pydantic:
pydantic-settings
— для управления настройками.pydantic-extra-types
— дополнительные типы для использования с Pydantic.
Дополнительные опциональные зависимости FastAPI:
orjson
— обязателен, если вы хотите использоватьORJSONResponse
.ujson
— обязателен, если вы хотите использоватьUJSONResponse
.
Лицензия
Этот проект распространяется на условиях лицензии MIT.