# FastAPI { #fastapi }
Фреймворк FastAPI: высокая производительность, прост в изучении, быстрый в разработке, готов к продакшн
---
**Документация**: https://fastapi.tiangolo.com
**Исходный код**: https://github.com/fastapi/fastapi
---
FastAPI — это современный, быстрый (высокопроизводительный) веб-фреймворк для создания API на Python, основанный на стандартных аннотациях типов Python.
Ключевые особенности:
* **Скорость**: Очень высокая производительность, на уровне **NodeJS** и **Go** (благодаря Starlette и Pydantic). [Один из самых быстрых доступных фреймворков Python](#performance).
* **Быстрота разработки**: Увеличьте скорость разработки фич примерно на 200–300%. *
* **Меньше ошибок**: Сократите примерно на 40% количество ошибок, вызванных человеком (разработчиком). *
* **Интуитивность**: Отличная поддержка редактора кода. Автозавершение везде. Меньше времени на отладку.
* **Простота**: Разработан так, чтобы его было легко использовать и осваивать. Меньше времени на чтение документации.
* **Краткость**: Минимизируйте дублирование кода. Несколько возможностей из каждого объявления параметров. Меньше ошибок.
* **Надежность**: Получите код, готовый к продакшн. С автоматической интерактивной документацией.
* **На основе стандартов**: Основан на открытых стандартах API и полностью совместим с ними: OpenAPI (ранее известный как Swagger) и JSON Schema.
* оценка на основе тестов внутренней команды разработчиков, создающих продакшн-приложения.
## Спонсоры { #sponsors }
{% if sponsors %}
{% for sponsor in sponsors.gold -%}
{% endfor -%}
{%- for sponsor in sponsors.silver -%}
{% endfor %}
{% endif %}
Другие спонсоры
## Мнения { #opinions }
"_[...] В последнее время я много где использую **FastAPI**. [...] На самом деле я планирую использовать его для всех **ML-сервисов моей команды в Microsoft**. Некоторые из них интегрируются в основной продукт **Windows**, а некоторые — в продукты **Office**._"
Kabir Khan -
Microsoft (ref)
---
"_Мы начали использовать библиотеку **FastAPI**, чтобы поднять **REST**-сервер, к которому можно обращаться за **предсказаниями**. [для Ludwig]_"
Piero Molino, Yaroslav Dudin, and Sai Sumanth Miryala -
Uber (ref)
---
"_**Netflix** рада объявить об открытом релизе нашего фреймворка оркестрации **антикризисного управления**: **Dispatch**! [создан с помощью **FastAPI**]_"
Kevin Glisson, Marc Vilanova, Forest Monsen -
Netflix (ref)
---
"_Я в полном восторге от **FastAPI**. Это так весело!_"
---
"_Честно говоря, то, что вы создали, выглядит очень солидно и отполировано. Во многих смыслах это то, чем я хотел видеть **Hug** — очень вдохновляет видеть, как кто-то это создал._"
---
"_Если вы хотите изучить один **современный фреймворк** для создания REST API, посмотрите **FastAPI** [...] Он быстрый, простой в использовании и лёгкий в изучении [...]_"
"_Мы переключились на **FastAPI** для наших **API** [...] Думаю, вам тоже понравится [...]_"
---
"_Если кто-то собирается делать продакшн-API на Python, я настоятельно рекомендую **FastAPI**. Он **прекрасно спроектирован**, **прост в использовании** и **отлично масштабируется**, стал **ключевым компонентом** нашей стратегии API-first и приводит в действие множество автоматизаций и сервисов, таких как наш Virtual TAC Engineer._"
Deon Pillsbury -
Cisco (ref)
---
## **Typer**, FastAPI для CLI { #typer-the-fastapi-of-clis }
Если вы создаёте приложение CLI для использования в терминале вместо веб-API, посмотрите **Typer**.
**Typer** — младший брат FastAPI. И он задуман как **FastAPI для CLI**. ⌨️ 🚀
## Зависимости { #requirements }
FastAPI стоит на плечах гигантов:
* Starlette для части, связанной с вебом.
* Pydantic для части, связанной с данными.
## Установка { #installation }
Создайте и активируйте виртуальное окружение, затем установите FastAPI:
```console
$ pip install "fastapi[standard]"
---> 100%
```
**Примечание**: Обязательно заключите `"fastapi[standard]"` в кавычки, чтобы это работало во всех терминалах.
## Пример { #example }
### Создание { #create-it }
Создайте файл `main.py` со следующим содержимым:
```Python
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`:
```Python hl_lines="9 14"
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` в документации.
### Запуск { #run-it }
Запустите сервер командой:
```console
$ 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.
### Проверка { #check-it }
Откройте браузер на http://127.0.0.1:8000/items/5?q=somequery.
Вы увидите JSON-ответ:
```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 { #interactive-api-docs }
Перейдите на http://127.0.0.1:8000/docs.
Вы увидите автоматическую интерактивную документацию API (предоставлена Swagger UI):

### Альтернативная документация API { #alternative-api-docs }
Теперь откройте http://127.0.0.1:8000/redoc.
Вы увидите альтернативную автоматическую документацию (предоставлена ReDoc):

## Пример обновления { #example-upgrade }
Теперь измените файл `main.py`, чтобы принимать тело запроса из `PUT` запроса.
Объявите тело, используя стандартные типы Python, спасибо Pydantic.
```Python hl_lines="4 9-12 25-27"
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 { #interactive-api-docs-upgrade }
Перейдите на http://127.0.0.1:8000/docs.
* Интерактивная документация API будет автоматически обновлена, включая новое тело:

* Нажмите кнопку «Try it out», это позволит вам заполнить параметры и напрямую взаимодействовать с API:

* Затем нажмите кнопку «Execute», интерфейс свяжется с вашим API, отправит параметры, получит результаты и отобразит их на экране:

### Обновление альтернативной документации API { #alternative-api-docs-upgrade }
Теперь откройте http://127.0.0.1:8000/redoc.
* Альтернативная документация также отразит новый параметр запроса и тело:

### Подведём итоги { #recap }
Итак, вы объявляете **один раз** типы параметров, тела запроса и т.д. как параметры функции.
Вы делаете это с помощью стандартных современных типов Python.
Вам не нужно изучать новый синтаксис, методы или классы конкретной библиотеки и т.п.
Только стандартный **Python**.
Например, для `int`:
```Python
item_id: int
```
или для более сложной модели `Item`:
```Python
item: Item
```
...и с этим единственным объявлением вы получаете:
* Поддержку редактора кода, включая:
* Автозавершение.
* Проверку типов.
* Валидацию данных:
* Автоматические и понятные ошибки, когда данные некорректны.
* Валидацию даже для глубоко вложенных объектов JSON.
* Преобразование входных данных: из сети в данные и типы Python. Чтение из:
* JSON.
* Параметров пути.
* Параметров запроса.
* Cookies.
* HTTP-заголовков.
* Форм.
* Файлов.
* Преобразование выходных данных: из данных и типов Python в данные сети (например, JSON):
* Преобразование типов Python (`str`, `int`, `float`, `bool`, `list` и т.д.).
* Объекты `datetime`.
* Объекты `UUID`.
* Модели баз данных.
* ...и многое другое.
* Автоматическую интерактивную документацию 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 веб-интерфейса интерактивной документации напрямую.
---
Мы только поверхностно ознакомились, но вы уже понимаете, как всё это работает.
Попробуйте изменить строку:
```Python
return {"item_name": item.name, "item_id": item_id}
```
...из:
```Python
... "item_name": item.name ...
```
...на:
```Python
... "item_price": item.price ...
```
...и посмотрите, как ваш редактор кода будет автоматически дополнять атрибуты и знать их типы:

Более полный пример с дополнительными возможностями см. в Учебник - Руководство пользователя.
**Осторожно, спойлер**: учебник - руководство включает:
* Объявление **параметров** из других источников: **HTTP-заголовки**, **cookies**, **поля формы** и **файлы**.
* Как задать **ограничения валидации** вроде `maximum_length` или `regex`.
* Очень мощную и простую в использовании систему **внедрения зависимостей**.
* Безопасность и аутентификацию, включая поддержку **OAuth2** с **JWT токенами** и **HTTP Basic** аутентификацию.
* Более продвинутые (но столь же простые) приёмы объявления **глубоко вложенных JSON-моделей** (спасибо Pydantic).
* Интеграцию **GraphQL** с Strawberry и другими библиотеками.
* Множество дополнительных функций (благодаря Starlette), таких как:
* **WebSockets**
* чрезвычайно простые тесты на основе HTTPX и `pytest`
* **CORS**
* **сессии с использованием cookie**
* ...и многое другое.
## Производительность { #performance }
Независимые бенчмарки TechEmpower показывают приложения **FastAPI**, работающие под управлением Uvicorn, как один из самых быстрых доступных фреймворков Python, уступающий только самим Starlette и Uvicorn (используются внутри FastAPI). (*)
Чтобы узнать больше, см. раздел Бенчмарки.
## Зависимости { #dependencies }
FastAPI зависит от Pydantic и Starlette.
### Зависимости `standard` { #standard-dependencies }
Когда вы устанавливаете 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` { #without-standard-dependencies }
Если вы не хотите включать опциональные зависимости `standard`, можно установить `pip install fastapi` вместо `pip install "fastapi[standard]"`.
### Без `fastapi-cloud-cli` { #without-fastapi-cloud-cli }
Если вы хотите установить FastAPI со стандартными зависимостями, но без `fastapi-cloud-cli`, установите `pip install "fastapi[standard-no-fastapi-cloud-cli]"`.
### Дополнительные опциональные зависимости { #additional-optional-dependencies }
Есть дополнительные зависимости, которые вы можете установить.
Дополнительные опциональные зависимости Pydantic:
* pydantic-settings
— для управления настройками.
* pydantic-extra-types
— дополнительные типы для использования с Pydantic.
Дополнительные опциональные зависимости FastAPI:
* orjson
— обязателен, если вы хотите использовать `ORJSONResponse`.
* ujson
— обязателен, если вы хотите использовать `UJSONResponse`.
## Лицензия { #license }
Этот проект распространяется на условиях лицензии MIT.