Перейти к содержимому

FastAPI: современный фреймворк для создания высокопроизводительных API

FastAPI: современный фреймворк для создания высокопроизводительных API

FastAPI — это современный, быстрый (высокопроизводительный) веб-фреймворк для создания API с использованием Python 3.7+ на основе стандартов OpenAPI и JSON Schema. Он сочетает в себе скорость разработки, типизацию и автоматическую документацию, что делает его идеальным инструментом для создания надежных API.

В этой статье вы научитесь:

  • Создавать API с помощью FastAPI и Pydantic
  • Обрабатывать различные типы параметров (query, path, body)
  • Работать с автоматической документацией Swagger UI
  • Использовать типизированные модели данных для валидации
  • Создавать виртуальные окружения с помощью Poetry
  • Структурировать проекты FastAPI

Почему FastAPI?

FastAPI быстро набирает популярность в Python-сообществе благодаря своим преимуществам:

  • Высокая производительность — один из самых быстрых Python-фреймворков, сравнимый с Node.js и Go
  • Автоматическая документация — генерирует интерактивную документацию Swagger UI и ReDoc
  • Типизация Python 3.7+ — использует аннотации типов для валидации данных
  • Простота и интуитивность — минималистичный синтаксис с максимальной функциональностью
  • Асинхронная поддержка — встроенная поддержка async/await для высоконагруженных приложений

FastAPI идеально подходит для:

  • Создания RESTful API и микросервисов
  • Быстрой разработки прототипов и MVP
  • Интеграции с машинным обучением и Data Science
  • Создания внутренних инструментов и админ-панелей

Установка и настройка виртуального окружения с Poetry

Для управления зависимостями и изоляции проектов в Python рекомендуется использовать виртуальные окружения. Вместо встроенного инструмента venv или pip, современные проекты часто используют Poetry — мощный менеджер зависимостей и виртуальных окружений.

Установка Poetry

pip install poetry
  

Результат выполнения в терминале:

Collecting poetry
  Downloading poetry-1.7.1-py3-none-any.whl (184 kB)
Collecting poetry-core>=1.8.0
  Downloading poetry_core-1.8.1-py3-none-any.whl (431 kB)
Installing collected packages: poetry-core, poetry
Successfully installed poetry-1.7.1 poetry-core-1.8.1
  

Создание проекта с Poetry

Инициализация нового проекта:

poetry init
  

После выполнения этой команды будет задан ряд вопросов для настройки проекта:

This command will guide you through creating your pyproject.toml config.

Package name [fastapi-project]: fastapi-app
Version [0.1.0]:
Description: Блог API на FastAPI
Author [Alex Smith <Адрес электронной почты защищен от спам-ботов. Для просмотра адреса в браузере должен быть включен Javascript.>, n to skip]: n
License [MIT]:
Compatible Python versions [^3.8]:

Would you like to define your main dependencies interactively? (yes/no) no
Would you like to define your development dependencies interactively? (yes/no) no

Do you confirm generation? (yes/no) yes
  

В результате будет создан файл pyproject.toml с базовой конфигурацией:

[tool.poetry]
name = "fastapi-app"
version = "0.1.0"
description = "Блог API на FastAPI"
authors = ["Alex Smith <Адрес электронной почты защищен от спам-ботов. Для просмотра адреса в браузере должен быть включен Javascript.>"]
license = "MIT"
readme = "README.md"
packages = [{include = "fastapi_app"}]

[tool.poetry.dependencies]
python = "^3.8"

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
  

Установка зависимостей FastAPI

Установка основных зависимостей для работы с FastAPI:

poetry add fastapi
poetry add "uvicorn[standard]"
  

Результат выполнения в терминале:

Using version ^0.103.2 for fastapi
Using version ^0.23.2 for uvicorn

Updating dependencies
Resolving dependencies... (1.2s)

Writing lock file

Package operations: 7 installs, 0 updates, 0 removals

  • Installing typing-extensions (4.8.0)
  • Installing annotated-types (0.6.0)
  • Installing pydantic-core (2.10.1)
  • Installing pydantic (2.4.2)
  • Installing starlette (0.27.0)
  • Installing fastapi (0.103.2)
  • Installing uvicorn (0.23.2)
  

После установки файл pyproject.toml будет обновлен:

[tool.poetry]
name = "fastapi-app"
version = "0.1.0"
description = "Блог API на FastAPI"
authors = ["Alex Smith <Адрес электронной почты защищен от спам-ботов. Для просмотра адреса в браузере должен быть включен Javascript.>"]
license = "MIT"
readme = "README.md"
packages = [{include = "fastapi_app"}]

[tool.poetry.dependencies]
python = "^3.8"
fastapi = "^0.103.2"
uvicorn = {extras = ["standard"], version = "^0.23.2"}

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
  

Активация виртуального окружения

Для работы с зависимостями внутри виртуального окружения Poetry:

poetry shell
  

Или выполнение команд без активации оболочки:

poetry run uvicorn main:app --reload
  

Первое приложение на FastAPI

Создадим базовое приложение FastAPI. Создайте файл main.py:

from fastapi import FastAPI
import uvicorn

app = FastAPI()

@app.get("/")
def index():
    return {"message": "Hello Index"}

if __name__ == '__main__':
    uvicorn.run("main:app", reload=True)
  

Результат выполнения в терминале:

INFO:     Will watch for changes in these directories: ['D:\\projects\\fastapi-app']
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO:     Started reloader process [12345] using StatReload
INFO:     Started server process [12346]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
  

Приложение будет доступно по адресу http://localhost:8000,

technobee_2025-12-14_15-18-52-776_12f17.jpg

а документация — по http://localhost:8000/docs:

technobee_2025-12-14_15-39-04-847_c44d0.jpg

Работа с параметрами в FastAPI

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

  1. через параметры пути (path)
  2. через строку запроса (query)
  3. из тела запроса (body).

1. Параметры пути (Path Parameters)

Параметры пути указываются непосредственно в пути URL и используются для идентификации конкретных ресурсов.

from fastapi import FastAPI

app = FastAPI()

@app.get("/items/{item_id}/") # вносим данные непосредственно в командную строку
def get_item(item_id: int):
    return {
        "data": {
            "id": item_id,
            "name": f"item-{item_id}"
        }
    }

if __name__ == '__main__':
    uvicorn.run("main:app", reload=True)
 

Пример запроса и ответа:

  1. в строке браузера набираем http://127.0.0.1:8000/items/42/
  2. браузер возвращает следующее:

technobee_2025-12-14_16-02-04-214_85d7b.jpg

GET /items/42/
Response: {
    "data": {
        "id": 42,
        "name": "item-42"
    }
}  

2. Параметры строки запроса (Query Parameters)

Параметры строки запроса передаются после знака вопроса в URL и используются для фильтрации, пагинации и других операций.

from fastapi import FastAPI

app = FastAPI()

@app.get("/hello/")
def hello(name: str = "World"):
    return {"message": f"Hello {name}"}

if __name__ == '__main__':
    uvicorn.run("main:app", reload=True)
  

Пример запроса и ответа:

GET /hello/?name=Alex
Response: {"message": "Hello Alex"}
  

3. Параметры тела запроса (Request Body)

Для передачи сложных данных используется тело запроса в формате JSON. FastAPI автоматически парсит и валидирует эти данные.

from fastapi import FastAPI

app = FastAPI()

@app.post("/items/")
def create_item(data: dict, name: str):
    return {
        "data": data,
        "name": name
    }

if __name__ == '__main__':
    uvicorn.run("main:app", reload=True)
  

Пример запроса с помощью curl:

curl -X 'POST' \
  'http://127.0.0.1:8000/items/?name=Alex' \
  -H 'Content-Type: application/json' \
  -d '{"foo":"bar"}'

Response: {
    "data": {"foo": "bar"},
    "name": "Alex"
}
  

Структурирование проекта с помощью APIRouter

Для больших проектов рекомендуется организовывать маршруты по разным файлам с использованием APIRouter.

Создание маршрутов в отдельном файле

Создайте файл items_views.py:

from fastapi import APIRouter

router = APIRouter(tags=['items'])

# Получение списка товаров
@router.get('/')
def items_list():
    return {
        "items": [
            {"id": 1, "name": "foobar"},
            {"id": 2, "name": "spam-and-eggs"},
        ]
    }

# Создание нового товара
@router.post('/')
def create_item(name: str, data: dict):
    return {
        "data": data,
        "name": name
    }

# Получение товара по ID
@router.get('/{item_id}/')
def get_item(item_id: int):
    return {
        "data": {
            "id": item_id,
            "name": f"item-{item_id}"
        }
    }
  

Подключение маршрутов в основном файле

Обновите файл main.py для подключения маршрутов:

from fastapi import FastAPI
import uvicorn
from items_views import router as items_router

app = FastAPI()

# Подключение маршрутов с префиксом "/items"
app.include_router(items_router, prefix="/items")

@app.get("/")
def index():
    return {"message": "Hello Index!"}

@app.get("/hello/")
def hello(name: str = "World"):
    return {"message": f"Hello {name}"}

if __name__ == '__main__':
    uvicorn.run("main:app", reload=True)
  

Структура проекта:

fastapi-app/
├── main.py
├── items_views.py
├── pyproject.toml
└── README.md
  

Результат выполнения в терминале:

INFO:     Will watch for changes in these directories: ['D:\\projects\\fastapi-app']
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO:     Started reloader process [12345] using StatReload
INFO:     Started server process [12346]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
  

Pydantic модели: User, Author, Post

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

Определение моделей

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

app = FastAPI()

class User(BaseModel):
    id: int
    username: str = Field(..., min_length=3, max_length=50)
    email: EmailStr
    is_active: bool = True

class Author(BaseModel):
    id: int
    name: str
    bio: Optional[str] = None
    user_id: int

class Post(BaseModel):
    id: Optional[int] = None
    title: str = Field(..., min_length=5, max_length=200)
    content: str = Field(..., min_length=10)
    author: Author
    created_at: datetime = Field(default_factory=datetime.now)
    tags: List[str] = []

    class Config:
        schema_extra = {
            "example": {
                "title": "Мой первый пост",
                "content": "Это содержимое моего первого поста в блоге",
                "author": {
                    "id": 1,
                    "name": "Иван Иванов",
                    "bio": "Профессиональный разработчик",
                    "user_id": 1
                },
                "tags": ["python", "fastapi", "web"]
            }
        }

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)
  

Особенности моделей:

  • Field(..., min_length=3) — задаёт ограничения на поля
  • EmailStr — специальный тип для валидации email
  • default_factory=datetime.now — динамическое значение по умолчанию
  • schema_extra — примеры для документации Swagger
  • Config — настройки модели

Создание API с моделями User, Author, Post

Теперь создадим полноценное API для управления пользователями, авторами и постами с использованием определённых ранее моделей.

Базовое CRUD API

from fastapi import FastAPI, HTTPException
from pydantic import BaseModel, EmailStr, Field
from typing import List, Optional, Dict
from datetime import datetime
import uvicorn

app = FastAPI(title="Blog API", version="1.0.0")

# Модели данных
class User(BaseModel):
    id: int
    username: str = Field(..., min_length=3, max_length=50)
    email: EmailStr
    is_active: bool = True

class Author(BaseModel):
    id: int
    name: str
    bio: Optional[str] = None
    user_id: int

class Post(BaseModel):
    id: Optional[int] = None
    title: str = Field(..., min_length=5, max_length=200)
    content: str = Field(..., min_length=10)
    author_id: int
    created_at: datetime = Field(default_factory=datetime.now)
    tags: List[str] = []

# Имитация базы данных
users_db: Dict[int, User] = {}
authors_db: Dict[int, Author] = {}
posts_db: Dict[int, Post] = {}
user_counter = 1
author_counter = 1
post_counter = 1

# Эндпоинты для пользователей
@app.post("/users/", response_model=User)
async def create_user(user: User):
    global user_counter
    user.id = user_counter
    users_db[user_counter] = user
    user_counter += 1
    return user

@app.get("/users/{user_id}", response_model=User)
async def get_user(user_id: int):
    if user_id not in users_db:
        raise HTTPException(status_code=404, detail="Пользователь не найден")
    return users_db[user_id]

# Эндпоинты для авторов
@app.post("/authors/", response_model=Author)
async def create_author(author: Author):
    global author_counter
    author.id = author_counter
    authors_db[author_counter] = author
    author_counter += 1
    return author

@app.get("/authors/{author_id}", response_model=Author)
async def get_author(author_id: int):
    if author_id not in authors_db:
        raise HTTPException(status_code=404, detail="Автор не найден")
    return authors_db[author_id]

# Эндпоинты для постов
@app.post("/posts/", response_model=Post)
async def create_post(post: Post):
    global post_counter
    post.id = post_counter
    posts_db[post_counter] = post
    post_counter += 1
    return post

@app.get("/posts/{post_id}", response_model=Post)
async def get_post(post_id: int):
    if post_id not in posts_db:
        raise HTTPException(status_code=404, detail="Пост не найден")
    return posts_db[post_id]

@app.get("/posts/", response_model=List[Post])
async def list_posts(skip: int = 0, limit: int = 10):
    return list(posts_db.values())[skip:skip + limit]

if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8000)
  

Результат выполнения в терминале при запуске:

INFO:     Started server process [12345]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
  

Swagger UI: автоматическая документация API

Одной из самых мощных особенностей FastAPI является автоматическая генерация интерактивной документации с помощью Swagger UI.

Доступ к документации

После запуска приложения документация доступна по адресу:

  • http://localhost:8000/docs — интерактивная документация Swagger UI
  • http://localhost:8000/redoc — альтернативная документация ReDoc

Пример использования Swagger UI

В Swagger UI вы можете:

  • Просматривать все эндпоинты API
  • Видеть параметры запросов и примеры тела запроса
  • Выполнять тестовые запросы прямо из браузера
  • Просматривать схемы данных (Pydantic модели)
  • Экспортировать спецификацию OpenAPI в формате JSON/YAML

Пример интерфейса Swagger UI для нашего API:

{
  "openapi": "3.1.0",
  "info": {
    "title": "Blog API",
    "version": "1.0.0"
  },
  "paths": {
    "/users/": {
      "post": {
        "summary": "Create User",
        "operationId": "create_user_users__post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {"$ref": "#/components/schemas/User"}
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {"$ref": "#/components/schemas/User"}
              }
            }
          }
        }
      }
    },
    "/posts/": {
      "get": {
        "summary": "List Posts",
        "operationId": "list_posts_posts__get",
        "parameters": [
          {
            "name": "skip",
            "in": "query",
            "schema": {"type": "integer", "default": 0}
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {"type": "integer", "default": 10}
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {"$ref": "#/components/schemas/Post"}
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Create Post",
        "operationId": "create_post_posts__post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {"$ref": "#/components/schemas/Post"}
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {"$ref": "#/components/schemas/Post"}
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "User": {
        "properties": {
          "id": {"type": "integer"},
          "username": {"type": "string", "minLength": 3, "maxLength": 50},
          "email": {"type": "string", "format": "email"},
          "is_active": {"type": "boolean", "default": true}
        },
        "required": ["id", "username", "email"],
        "type": "object"
      },
      "Post": {
        "properties": {
          "id": {"type": "integer"},
          "title": {"type": "string", "minLength": 5, "maxLength": 200},
          "content": {"type": "string", "minLength": 10},
          "author_id": {"type": "integer"},
          "created_at": {"type": "string", "format": "date-time"},
          "tags": {
            "items": {"type": "string"},
            "type": "array",
            "default": []
          }
        },
        "required": ["title", "content", "author_id"],
        "type": "object"
      }
    }
  }
}
  

Тестирование API через Swagger UI

В Swagger UI можно протестировать любой эндпоинт:

  1. Выберите эндпоинт (например, POST /users/)
  2. Нажмите кнопку "Try it out"
  3. Введите пример данных в поле "Request body":
{
  "username": "ivan_ivanov",
  "email": "Адрес электронной почты защищен от спам-ботов. Для просмотра адреса в браузере должен быть включен Javascript.",
  "is_active": true
}
  
  1. Нажмите "Execute"
  2. Посмотрите результат в разделе "Response body"

Чек-лист для проверки усвоения материала

Проверяемый навык / знаниеСтатус
1 Я понимаю, что такое FastAPI и какие преимущества он предоставляет.
Я могу установить FastAPI и запустить базовое приложение.
Я знаю, как получить доступ к автоматической документации Swagger UI.
2 Я понимаю, что такое Poetry и зачем он нужен.
Я умею инициализировать проект с помощью poetry init.
Я умею устанавливать зависимости с помощью poetry add.
3 Я умею работать с параметрами пути (path parameters).
Я умею работать с параметрами строки запроса (query parameters).
Я умею работать с параметрами тела запроса (request body) с помощью Pydantic.
4 Я понимаю назначение Pydantic и аннотаций типов в FastAPI.
Я могу создавать и использовать Pydantic модели для валидации данных.
Я умею задавать ограничения на поля моделей (min_length, max_length, etc).
Я понимаю, как использовать вложенные модели и списки в Pydantic.
5 Я умею использовать APIRouter для организации маршрутов по модулям.
Я понимаю, как структурировать большие проекты FastAPI.
6 Я могу просматривать и тестировать API через Swagger UI.
Я понимаю структуру OpenAPI спецификации, генерируемой FastAPI.
Я умею настраивать метаданные API (title, version, description).
7 Я могу создать CRUD API для работы с моделями данных.
Я умею обрабатывать ошибки и возвращать соответствующие HTTP статусы.

Практическое задание для закрепления

  1. Создайте виртуальное окружение с помощью Poetry для нового проекта:
    • Инициализируйте проект с помощью poetry init
    • Установите зависимости fastapi и uvicorn
    • Активируйте виртуальное окружение
  2. Создайте базовое FastAPI приложение с эндпоинтом /health, который возвращает статус "ok".
  3. Реализуйте CRUD API для управления товарами (Product) с полями:
    • id (int)
    • name (str, min_length=2)
    • price (float, > 0)
    • description (optional str)
    • in_stock (bool, default=True)
  4. Организуйте структуру проекта:
    • Создайте отдельный файл для маршрутов товаров
    • Используйте APIRouter для организации маршрутов
    • Подключите маршруты в основном файле с префиксом /products
  5. Настройте документацию:
    • Добавьте заголовок и описание для API
    • Настройте примеры для эндпоинтов в Swagger UI

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

Совет: Начинайте с простого — создайте базовое API и постепенно добавляйте сложные функции. Используйте Swagger UI для тестирования и отладки, это значительно ускорит процесс разработки.

Удачной разработки!

Конспект:
Пятница, 12 декабря 2025
FastAPI: современный фреймворк для создания высокопроизводительных API