Начните работу с FastAPI

автор vadim


Когда веб-фреймворки Python, такие как Flask и Django, впервые приобрели известность, Python был несколько другим языком, чем сегодня. Многие элементы современного Python, такие как асинхронное выполнение и стандарт ASGI (интерфейс асинхронного серверного шлюза), либо находились в зачаточном состоянии, либо еще не существовали.

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

Как следует из названия, основной вариант использования FastAPI — быстрое создание конечных точек API. Этого можно добиться так же легко, как вернуть данные словаря Python в формате JSON или использовать стандарт OpenAPI, включая интерактивный пользовательский интерфейс Swagger. Но FastAPI ни в коем случае не ограничивается API. Вы можете использовать его практически для всего, что делает веб-фреймворк: от доставки простых старых веб-страниц с использованием механизма шаблонов Jinja2 до обслуживания приложений на базе WebSockets.

Установить ФастAPI

FastAPI может устанавливать довольно много компонентов самостоятельно, поэтому лучше всего начинать любой проект FastAPI в новой, чистой виртуальной среде. Основные компоненты FastAPI можно установить с помощью pip install fastapi.

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

Простой пример FastAPI

Вот простое приложение FastAPI:


from fastapi import FastAPI
app = FastAPI()

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

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

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

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

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

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

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

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

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

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

Вы также можете поддерживать несколько методов на данном маршруте, просто обернув несколько функций маршрута, например: @app.get("https://www.infoworld.com/") по одной функции и @app.post("https://www.infoworld.com/") на другом.

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

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


@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 = 3):
    return userlist[start:start+limit]

Таким образом, параметры запроса start и limit будет автоматически извлечен из URL-адреса и передан в этих именованных переменных. Если бы эти параметры не существовали, им были бы присвоены значения по умолчанию.

Обработка данных формы немного сложнее. Сначала вам придется установить дополнительную библиотеку, 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 здесь (Form("")).

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

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


from fastapi.responses import HTMLResponse

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

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

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

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

Если вы хотите программно сгенерировать HTML для HTMLResponseвы можете сделать это с помощью Jinja2 или другого шаблонизатора по вашему выбору.

Объект Response в FastAPI

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


from fastapi import Response

@app.get("https://www.infoworld.com/")
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("https://www.infoworld.com/")
async def main(user_nonce: Optional[str]=Cookie(none)):
    return {"user_nonce": user_nonce}

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


from fastapi import Response

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

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

Типы в Python, как правило, не являются обязательными, но FastAPI является более строгим в использовании типов, чем многие другие платформы Python. FastAPI использует библиотеку 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 значение, которое нельзя интерпретировать как целое число, оно будет отклонено.

Использование WebSockets в FastAPI

Конечные точки WebSocket в FastAPI также просты:


from fastapi import FastAPI, WebSocket

@app.websocket("/ws")
async def ws_connection(websocket: WebSocket):
    await websocket.accept()
    while True:
        data = await websocket.receive_text()
        await websocket.send_text(f"You said: {data}")

Этот пример получает соединение в конечной точке /wsобычно устанавливаемый в JavaScript с помощью WebSocket объект, затем ожидает ввода и повторяет ответ в цикле.

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

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

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

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

Еще одно удобство, которое предоставляет FastAPI, — это автоматически генерируемые интерфейсы документации для ваших API, с которыми вы можете взаимодействовать через веб-интерфейс. Если вы перейдете к /docs, вы увидите страницу с вашими API, созданную ReDoc; идти к /docs и вы увидите один, созданный пользовательским интерфейсом Swagger (более старый, менее продвинутый). Оба пользовательских интерфейса документации являются настраиваемыми.

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

фастапи ИДГ

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

Заключение

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

Дальше читайте это:

  • Облачные вычисления больше не являются пустяком
  • Что такое генеративный ИИ? Искусственный интеллект, который создает
  • Программирование с помощью ИИ: советы и лучшие практики от разработчиков
  • Python пытается удалить GIL и повысить параллелизм
  • 7 причин, по которым Java по-прежнему хороша
  • Война за лицензирование открытого исходного кода окончена

Related Posts

Оставить комментарий