Почему Вы должны попробовать FastAPI?

в 16:45, , рубрики: api, asyncio, fastapi, openapi, python, rest, swagger

image Лого взято из Github репозитория FastAPI

FastAPI — относительно новый веб-фреймворк, написанный на языке программирования Python для создания REST (а если сильно постараться то и GraphQL) API, основанный на новых возможностях Python 3.6+, таких как: подсказки типов (type-hints), нативная асинхронность (asyncio). Помимо всего прочего, FastAPI плотно интегрируется с OpenAPI-schema и автоматически генерирует документацию для вашего API посредством Swagger и ReDoc

FastAPI построен на базе Starlette и Pydantic.
StarletteASGI микро-фреймворк для написания веб-приложений.
Pydantic — библиотека для парсинга и валидации данных основанная на Python type-hints.

Что говорят о FastAPI?

"[...] Я использую FastAPI очень часто в последние дни. [...] Я однозначно планирую использовать его для всех ML сервисов моей команды в Microsoft. Некоторые из них интегрируются в Windows и некоторые продукты Office."

Kabir Khan — Microsoft (ref)

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

"Теперь мы используем FastAPI для наших API [...] Я думаю он вам понравится! [...]"

Ines Montani — Matthew Honnibal — Explosion AI founders — spaCy creators (ref) — (ref)

Минимальное API созданное с помощью FastAPI

Я постараюсь показать Вам как создать простое, но в то же время полезное API с документацией для разработчиков. Мы будем писать генератор случайных фраз!

Установка необходимых компонентов

pip install uvicorn fastapi pydantic

Новый модуль!
Uvicorn — это ASGI-совместимый веб-сервер, который мы будем использовать для запуска нашего приложения.

Для начала создадим основу нашего приложения.

from fastapi import FastAPI

app = FastAPI(title="Random phrase")

Это приложение уже работает и его можно запустить.
Пропишите данную команду в вашем терминале и откройте страничку в браузере по адресу http://127.0.0.1:8000/docs.

uvicorn <имя_вашего_файла>:app

Но пока в нашем приложении не обозначено ни одного эндпоинта — давайте это исправим!

База данных

Так как мы пишем генератор случайных фраз, мы очевидно должны их где-то хранить. Для этого я выбрал простой python-dict.

Создадим файл db.py и начнём писать код.

Импортируем необходимые модули:

import typing
import random
from pydantic import BaseModel
from pydantic import Field

После — обозначим две модели: входная фраза (та, которую нам будет отправлять пользователь) и "выходная" (та, которую мы будем отправлять пользователю).

class PhraseInput(BaseModel):
    """Phrase model"""

    author: str = "Anonymous"  # имя автора. Если не передано - используется стандартное значение.
    text: str = Field(..., title="Text", description="Text of phrase", max_length=200)  # Текст фразы. Максимальное значение - 200 символов.

class PhraseOutput(PhraseInput):
    id: typing.Optional[int] = None  # ID фразы в нашей базе данных.

После этого, создадим простой класс для работы с БД:


class Database:
    """
    Our **fake** database.
    """

    def __init__(self):
        self._items: typing.Dict[int, PhraseOutput] = {}  # id: model

    def get_random(self) -> int:
        # Получение случайной фразы
        return random.choice(self._items.keys())

    def get(self, id: int) -> typing.Optional[PhraseOutput]:
        # Получение фразы по ID
        return self._items.get(id)

    def add(self, phrase: PhraseInput) -> PhraseOutput:
        # Добавление фразы

        id = len(self._items) + 1
        phrase_out = PhraseOutput(id=id, **phrase.dict())
        self._items[phrase_out.id] = phrase_out
        return phrase_out

    def delete(self, id: int) -> typing.Union[typing.NoReturn, None]:
        # Удаление фразы

        if id in self._items:
            del self._items[id]
        else:
            raise ValueError("Phrase doesn't exist")

Теперь можно приступить к написанию самого API.

API

Создадим файл main.py и импортируем следующие модули:

from fastapi import FastAPI
from fastapi import HTTPException
from db import PhraseInput
from db import PhraseOutput
from db import Database

Инициализируем наше приложение и базу данных:

app = FastAPI(title="Random phrase")
db = Database()

И напишем простой метод получения случайной фразы!

@app.get(
    "/get",
    response_description="Random phrase",
    description="Get random phrase from database",
    response_model=PhraseOutput,
)
async def get():
    try:
        phrase = db.get(db.get_random())
    except IndexError:
        raise HTTPException(404, "Phrase list is empty")
    return phrase

Как Вы можете заметить, в декораторе я также указываю некоторые другие значения, нужные для генерации более красивой документации :) В официальной документации Вы можете посмотреть на все возможные параметры.

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

Аналогично пишем другие методы:

@app.post(
    "/add",
    response_description="Added phrase with *id* parameter",
    response_model=PhraseOutput,
)
async def add(phrase: PhraseInput):
    phrase_out = db.add(phrase)
    return phrase_out

@app.delete("/delete", response_description="Result of deleting")
async def delete(id: int):
    try:
        db.delete(id)
    except ValueError as e:
        raise HTTPException(404, str(e))

И всё! Наше маленькое, но полезное API — готово!

Теперь мы можем запустить приложение с помощью uvicorn, открыть интерактивную документацию (http://127.0.0.1/docs) и попробовать наше API!

Почему Вы должны попробовать FastAPI? - 2

Полезные материалы

Конечно, я не смог рассказать Вам о всех возможностях FastAPI, например таких как: умная DI система, middlewares, куки, стандартные методы аутентификация в API (jwt, oauth2, api-key) и многое другое!

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

Код из статьи на Github
Официальная документация
Репозиторий на Github

Автор: prostomarkeloff

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js