Как начать работать с FastAPI на Python

Когда веб-фреймворки Python, такие как Flask и Django, впервые появились и начали приобретать популярность и известность, Python был несколько другим языком, чем сегодня. Многие элементы современного Python, такие как асинхронное выполнение и стандарт ASGI (Asynchronous Server Gateway Interface), на тот момент либо находились в зачаточном состоянии, либо еще не существовали. Поэтому не удивительно, что сейчас возникают новые фреймворки. Один из них — FastAPI. В этой статье мы разберем, как начать работать с FastAPI на Python.

FastAPI – это веб-фреймворк Python, который изначально создавался для использования современных функций Python. Он использует стандарт ASGI для асинхронного, конкурентного соединения с клиентами. При необходимости также может работать с WSGI. Асинхронные функции могут использоваться для маршрутов и конечных точек. Кроме того, FastAPI позволяет быстро и эффективно создавать веб-приложения с чистым, современным Python-кодом, с подсказками типов.

Как следует из названия, основным вариантом использования FastAPI является создание конечных точек API. Для этого нужно просто вернуть данные словаря Python в формате JSON или использовать стандарт OpenAPI, включая интерактивный Swagger UI.

Но FastAPI никоим образом не ограничивается API. С его помощью можно сделать практически все, что делают с использованием веб-фреймворков. От доставки простеньких старых веб-страниц с применением движка шаблонов Jinja2 до обслуживания приложений на базе WebSockets.

Установка FastAPI

FastAPI может устанавливать довольно много компонентов самостоятельно. Поэтому лучше начинать любой проект на FastAPI в новой чистой виртуальной среде.

Основные компоненты FastAPI можно установить с помощью команды pip install fastapi.

Вам также потребуется установить сервер ASGI для локального тестирования.

FastAPI хорошо работает с Uvicorn, поэтому мы будем использовать его в наших примерах. Для установки Uvicorn с оптимальным набором компонентов с библиотеками введите команду pip install uvicorn [standard]. А чтобы установить минимальную версию на чистом Python, используйте команду pip install uvicorn.

Простой пример использования FastAPI

Простое приложение на FastAPI выглядит следующим образом:

from fastapi import FastAPI
app = FastAPI()

@app.get("/")
async def root():
    return {"greeting":"Hello world"}

Сохраните этот код в файле main.py, затем запустите из своего виртуального окружения с помощью команды uvicorn main: app. Объект app – это то, что вы будете использовать для своего сервера ASGI. Обратите внимание, что вы также можете использовать WSGI с адаптером ASGI-to-WSGI. Однако лучше всего использовать ASGI.

Когда все заработает, перейдите по ссылке http:\\localhost:8000 (дефолтный адрес для тестового сервера Uvicorn на вашей локальной машине). В браузере вы увидите {"greeting": "Hello world"} – валидный ответ JSON, сгенерированный из словаря.

Надеемся, этот пример даст вам представление о том, насколько легко FastAPI позволяет передавать JSON. Все, что нужно сделать, это создать маршрут и вернуть словарь Python, который будет автоматически сериализован в JSON.

Для сериализации сложных типов данных нужно предпринять дополнительные шаги, но о них мы поговорим позже.

python logo

Марк Лутц «Изучаем Python»

Скачивайте книгу у нас в телеграм

×

Общие принципы приложения FastAPI должны быть знакомы любому, кто работал с таким фреймворком, как Flask:

  • Объект app импортируется на сервер ASGI или WSGI и используется для запуска приложения
  • Добавление маршрутов в приложение можно выполнить с помощью декоратора. Например, @app.get ("/") создает маршрут метода GET в корне сайта с результатами, возвращаемыми обернутой функцией.

Но всё же у FastAPI есть свои особенности. Во-первых, функции маршрутизации могут быть асинхронными. Поэтому любые развертываемые асинхронные компоненты – например, соединение промежуточного программного обеспечения асинхронной базы данных – также могут работать в этих функциях.

Обратите внимание, что ничто не мешает вам использовать обычные функции синхронизации, если они нужны. Допустим, у вас есть операция, требующая больших вычислительных ресурсов (в отличие от операции, ожидающей ввода-вывода — что является лучшим вариантом использования асинхронного режима). В таком случае будет лучше использовать функцию синхронизации и позволить FastAPI разобраться с ней. В остальных случаях используйте асинхронность.

Типы маршрутов в FastAPI

Декоратор @app позволяет устанавливать метод, используемый для маршрута, например, @app.get или @app.post. Таким образом поддерживаются методы GET, POST, PUT, DELETE и менее используемые OPTIONS, HEAD, PATCH, TRACE.

Вы также можете поддерживать несколько методов на заданном маршруте. Для этого нужно просто обернуть несколько функций маршрутизации, например @app.get ("/") для одной функции и @app.post ("/") для другой.

Параметры путей, запросов и форм

Если вы хотите извлечь переменные из пути маршрута, это можно сделать, определив их при объявлении маршрута, а затем передав их в функцию маршрута.

@app.get("/users/{user_id}")
async def user(user_id: str):
    return {"user_id":user_id}

Чтобы извлечь параметры запроса из URL-адреса, можно использовать типизированные объявления в функции маршрутизации, которые FastAPI обнаружит автоматически:

userlist = ["Spike","Jet","Ed","Faye","Ein"]

@app.get("/userlist")
async def userlist_(start: int = 0, limit: int = 10):
    return userlist[start:start+limit]

Обработка данных формы происходит немного сложнее. Во-первых, вам нужно установить дополнительную библиотеку python-multipart для анализа данных формы (pip install python-multipart). Затем вы сможете использовать синтаксис, аналогичный синтаксису параметров запроса, но с некоторыми изменениями:

from fastapi import Form

@app.post("/lookup")
async def userlookup(username: str = Form(...), user_id: str = Form("")):
    return {"username": username, "user_id":user_id}

Объект Form извлекает именованный параметр (username, user_id) из отправленной формы и передает его. Обратите внимание: если вы используете Form(...) при объявлении, это намек на то, что рассматриваемый параметр является обязательным, как username в данном примере. Для необязательного элемента Form() можно передать значение по умолчанию, как в случае с user_id.

Типы ответов в FastAPI

Типом ответа по умолчанию для FastAPI является JSON. Все примеры, которые мы видели до сих пор, возвращают данные, которые автоматически сериализуются как JSON. Но вы можете возвращать данные и в другом формате.

Например:

from fastapi.responses import HTMLResponse

@app.get("/")
def root():
    return HTMLResponse("<b>Hello world</b>")

Модуль fastapi.responses поддерживает множество распространенных типов ответов:

  • HTMLResponse или PlainTextResponse – возвращает текст как HTML или обычный текст
  • RedirectResponse – перенаправляет на указанный URL
  • FileResponse – возвращает файл по указанному пути в асинхронной потоковой передаче
  • StreamingResponse – принимает генератор и передает результаты клиенту

Кроме того, вы можете использовать общий объект Response и предоставить собственный настраиваемый код состояния, заголовки, контент и тип мультимедиа.

Объект Response в FastAPI

Обратите внимание: если вы хотите работать с Response, например, путем установки файлов cookie или заголовков, вы можете сделать это, приняв объект Response в качестве параметра в своей функции маршрутизации.

from fastapi import Response

@app.get("/")
def modify_header(response:Response):
    response.headers["X-New-Header"] = "Hi, I'm a new header!
    return {"msg":"Headers modified in response"}

Файлы cookie в FastAPI

Получение файлов cookie от клиента работает примерно так же, как обработка параметров запроса или формы:

from fastapi import Cookie

@app.get("/")
async def main(user_nonce: Optional[str]=Cookie(none)):
    return {"user_nonce": user_nonce}

Установка файлов cookie выполняется с помощью метода .set_cookie() объекта Response:

from fastapi import Response

@app.post("/")
async def main(response: Response):
    response.set_cookie(key="user_nonce", value="")
    return {"msg":"User nonce cookie cleared"}

Использование моделей Pydantic с FastAPI

Типы в Python, как правило, необязательны. Однако FastAPI больший «приверженец» использования типов, чем многие другие фреймворки Python. Для декларативной проверки отправленных данных он использует библиотеку Pydantic, так что вам не придется прописывать эту логику самостоятельно.

Вот пример того, как с помощью Pydantic можно проверить входящий JSON:

from typing import List, Optional
from fastapi import FastAPI
from pydantic import BaseModel, EmailStr

app = FastAPI()

class Movie(BaseModel):
    name: str
    year: int
    rating: Optional[int] = None
    tags: List[str] = []

@app.post("/movies/", response_model=Movie)
async def create_movie(movie: Movie):
    return movie

Этот фрагмент будет принимать данные JSON через POST (не HTML-форму!) с полями name, year, rating, и tags. Затем типы каждого из этих полей будут проверены. Например, эти данные будут действительными:

{
    "name":"Blade Runner 2049",
    "year": 2018,
    "rating": 5,
    "tags": ["science fiction","dystopia"]
}

Если бы year был строкой, которую можно интерпретировать как целое число (например, «2018»), он был бы автоматически преобразован в правильный тип данных. Но значение year, которое нельзя интерпретировать как целое число (к примеру, «год 21»), было бы отклонено.

Использование Swagger/OpenAPI в FastAPI

OpenAPI (ранее известный как Swagger) представляет собой стандарт в формате JSON для описания конечных точек API. Клиент может прочитать определение OpenAPI для конечной точки и автоматически определить схемы для данных, отправляемых и получаемых API веб-сайта.

FastAPI автоматически генерирует определения OpenAPI для всех конечных точек вашего сайта. Если вы посетите /openapi.json в корне сайта FastAPI, вы получите файл JSON, описывающий каждую конечную точку и данные, которые она может получать и возвращать.

Еще одно удобство, предоставляемое FastAPI, – это автоматически генерируемые интерфейсы документации для ваших API, с которыми вы можете взаимодействовать через веб-интерфейс.

Если вы перейдете в /redoc, вы увидите страницу для ваших API, созданную ReDoc. Перейдите в /docs, и вы увидите файл, созданный пользовательским интерфейсом Swagger (более старый, менее продвинутый). Оба пользовательских интерфейса документации можно настраивать.

FastAPI также предоставляет хуки для расширения или изменения автоматически сгенерированной схемы, а также для ее условного создания или даже отключения.

Заключение

Итак, мы рассмотрели особенности фреймворка FastAPI и разобрали, как начать с ним работать на Python. Также мы привели несколько примеров использования FastAPI. Надеемся, теперь у вас есть понимание основ работы с данным фреймворком. Успехов в написании кода!

Перевод статьи «Get started with FastAPI».