You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

29 KiB

FastAPI

FastAPI

Фреймворк FastAPI: высокая производительность, прост в изучении, быстрый в разработке, готов к продакшн

Тест Покрытие Версия пакета Поддерживаемые версии Python


Документация: 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."

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. Это так весело!"

Brian Okken - Ведущий подкаста Python Bytes (ref)

"Честно говоря, то, что вы создали, выглядит очень солидно и отполировано. Во многих смыслах это то, чем я хотел видеть Hug — очень вдохновляет видеть, как кто-то это создал."

Timothy Crosley - Создатель Hug (ref)

"Если вы хотите изучить один современный фреймворк для создания REST API, посмотрите FastAPI [...] Он быстрый, простой в использовании и лёгкий в изучении [...]"

"Мы переключились на FastAPI для наших API [...] Думаю, вам тоже понравится [...]"

Ines Montani - Matthew Honnibal - Основатели Explosion AI — создатели spaCy (ref) - (ref)

"Если кто-то собирается делать продакшн-API на Python, я настоятельно рекомендую FastAPI. Он прекрасно спроектирован, прост в использовании и отлично масштабируется, стал ключевым компонентом нашей стратегии API-first и приводит в действие множество автоматизаций и сервисов, таких как наш Virtual TAC Engineer."

Deon Pillsbury - Cisco (ref)

Typer, FastAPI для CLI

Если вы создаёте приложение CLI для использования в терминале вместо веб-API, посмотрите Typer.

Typer — младший брат FastAPI. И он задуман как FastAPI для CLI. ⌨️ 🚀

Зависимости

FastAPI стоит на плечах гигантов:

  • Starlette для части, связанной с вебом.
  • Pydantic для части, связанной с данными.

Установка

Создайте и активируйте виртуальное окружение, затем установите 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):

Swagger UI

Альтернативная документация API

Теперь откройте http://127.0.0.1:8000/redoc.

Вы увидите альтернативную автоматическую документацию (предоставлена 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 будет автоматически обновлена, включая новое тело:

Swagger UI

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

Swagger UI interaction

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

Swagger UI interaction

Обновление альтернативной документации API

Теперь откройте http://127.0.0.1:8000/redoc.

  • Альтернативная документация также отразит новый параметр запроса и тело:

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.
    • Модели баз данных.
    • ...и многое другое.
  • Автоматическую интерактивную документацию 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 ...

...и посмотрите, как ваш редактор кода будет автоматически дополнять атрибуты и знать их типы:

editor support

Более полный пример с дополнительными возможностями см. в Учебник - Руководство пользователя.

Осторожно, спойлер: учебник - руководство включает:

  • Объявление параметров из других источников: 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.