FastAPI Python — быстрый старт: создание REST API с нуля

19 июня 2026
Автор

Антон Ларичев

Введение

FastAPI — современный асинхронный веб-фреймворк для Python, созданный Себастьяном Рамиресом в 2018 году. Он сочетает высокую производительность (сравнимую с Node.js и Go), удобный синтаксис и автоматическую генерацию документации.

По данным репозитория на GitHub, FastAPI — один из самых быстрорастущих Python-фреймворков последних лет. Его используют Microsoft, Uber, Netflix и многие другие компании.

Ключевые преимущества:

  • Автоматическая валидация данных через Pydantic
  • Автогенерация Swagger UI и ReDoc документации
  • Поддержка async/await из коробки
  • Строгая типизация, которая помогает IDE и снижает количество ошибок
  • Высокая производительность на базе Starlette и Uvicorn

Установка

# Создаём виртуальное окружение
python -m venv venv
source venv/bin/activate  # Linux/Mac
# venv\Scripts\activate   # Windows

# Устанавливаем FastAPI и сервер Uvicorn
pip install fastapi uvicorn

Для полной установки с дополнительными зависимостями:

pip install "fastapi[all]"
# Включает uvicorn, python-multipart, Jinja2 и другие пакеты

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

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

from fastapi import FastAPI

# Создаём экземпляр приложения
app = FastAPI(title="Мой первый API", version="1.0.0")


@app.get("/")
def read_root():
    return {"message": "Привет, FastAPI!"}


@app.get("/items/{item_id}")
def read_item(item_id: int, q: str | None = None):
    return {"item_id": item_id, "q": q}

Запуск:

uvicorn main:app --reload

Флаг --reload перезапускает сервер при изменении файлов — удобно при разработке.

Перейдите на http://127.0.0.1:8000 и увидите {"message": "Привет, FastAPI!"}.

Автоматическая документация доступна по адресам:

  • http://127.0.0.1:8000/docs — Swagger UI (интерактивный)
  • http://127.0.0.1:8000/redoc — ReDoc

Если вы хотите глубоко изучить создание REST API на Python с FastAPI — приходите на наш курс Python с нуля. На курсе 200+ уроков, AI-тренажёры для практики 24/7, решение задач с живым ревью наставника, еженедельные встречи с менторами.

Маршруты и HTTP-методы

FastAPI поддерживает все HTTP-методы через декораторы:

from fastapi import FastAPI

app = FastAPI()

# GET — получение данных
@app.get("/users/{user_id}")
def get_user(user_id: int):
    return {"id": user_id, "name": "Иван"}

# POST — создание
@app.post("/users")
def create_user(name: str, email: str):
    return {"id": 1, "name": name, "email": email}

# PUT — полное обновление
@app.put("/users/{user_id}")
def update_user(user_id: int, name: str):
    return {"id": user_id, "name": name}

# DELETE — удаление
@app.delete("/users/{user_id}")
def delete_user(user_id: int):
    return {"message": f"Пользователь {user_id} удалён"}

# PATCH — частичное обновление
@app.patch("/users/{user_id}")
def partial_update(user_id: int, email: str | None = None):
    return {"id": user_id, "email": email}

Параметры пути и запроса

@app.get("/items/{item_id}")
def read_item(
    item_id: int,          # параметр пути (обязательный)
    skip: int = 0,         # параметр запроса со значением по умолчанию
    limit: int = 10,       # ?skip=0&limit=10
    q: str | None = None   # необязательный параметр запроса
):
    return {
        "item_id": item_id,
        "skip": skip,
        "limit": limit,
        "q": q
    }

Pydantic-модели для тела запроса

Для передачи данных в теле запроса используются Pydantic-модели:

from fastapi import FastAPI
from pydantic import BaseModel, EmailStr, Field

app = FastAPI()


class UserCreate(BaseModel):
    name: str = Field(min_length=2, max_length=50, description="Имя пользователя")
    email: str
    age: int = Field(ge=0, le=150, description="Возраст")
    role: str = "user"  # значение по умолчанию


class UserResponse(BaseModel):
    id: int
    name: str
    email: str
    role: str


@app.post("/users", response_model=UserResponse)
def create_user(user: UserCreate):
    # FastAPI автоматически:
    # 1. Парсит JSON из тела запроса
    # 2. Валидирует данные согласно модели
    # 3. Возвращает 422 Unprocessable Entity при ошибке валидации
    
    new_user = {
        "id": 1,
        "name": user.name,
        "email": user.email,
        "role": user.role
    }
    return new_user

response_model=UserResponse гарантирует, что в ответ вернутся только поля из UserResponse — это важно для безопасности (например, чтобы не вернуть пароль).

Валидация данных

FastAPI использует Pydantic для валидации. При ошибке автоматически возвращается 422 с деталями:

from pydantic import BaseModel, Field, validator

class Product(BaseModel):
    name: str = Field(min_length=1, max_length=100)
    price: float = Field(gt=0, description="Цена должна быть больше нуля")
    quantity: int = Field(ge=0, description="Количество не может быть отрицательным")
    category: str
    
    @validator('category')
    def category_must_be_valid(cls, v):
        valid = ['electronics', 'clothing', 'food']
        if v not in valid:
            raise ValueError(f'Категория должна быть одной из: {valid}')
        return v

При отправке невалидных данных FastAPI вернёт подробный ответ с указанием, какое поле не прошло валидацию.

Зависимости (Dependency Injection)

Система зависимостей FastAPI позволяет переиспользовать логику — например, проверку авторизации:

from fastapi import FastAPI, Depends, HTTPException, Header

app = FastAPI()


def verify_token(authorization: str = Header(...)):
    """Проверяем токен в заголовке Authorization"""
    if not authorization.startswith("Bearer "):
        raise HTTPException(status_code=401, detail="Неверный формат токена")
    token = authorization.replace("Bearer ", "")
    if token != "secret-token":
        raise HTTPException(status_code=401, detail="Неверный токен")
    return token


@app.get("/protected")
def protected_route(token: str = Depends(verify_token)):
    return {"message": "Доступ разрешён", "token": token}

Асинхронные обработчики

FastAPI отлично работает с async/await — это особенно важно для операций с базой данных и внешними API:

import asyncio
import httpx
from fastapi import FastAPI

app = FastAPI()


@app.get("/async-example")
async def async_example():
    # Асинхронный HTTP-запрос (не блокирует сервер)
    async with httpx.AsyncClient() as client:
        response = await client.get("https://jsonplaceholder.typicode.com/posts/1")
        return response.json()


@app.get("/concurrent")
async def concurrent_requests():
    # Параллельные запросы
    async with httpx.AsyncClient() as client:
        results = await asyncio.gather(
            client.get("https://jsonplaceholder.typicode.com/posts/1"),
            client.get("https://jsonplaceholder.typicode.com/posts/2"),
        )
    return [r.json() for r in results]

Обработка ошибок

from fastapi import FastAPI, HTTPException

app = FastAPI()

# Простая база данных в памяти
fake_db = {1: "Иван", 2: "Мария"}


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

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

Для реальных проектов рекомендуется следующая структура:

my_api/
├── main.py           # точка входа
├── routers/
│   ├── users.py      # маршруты пользователей
│   └── products.py   # маршруты продуктов
├── models/
│   └── schemas.py    # Pydantic-модели
└── dependencies.py   # общие зависимости

Пример роутера:

# routers/users.py
from fastapi import APIRouter

router = APIRouter(prefix="/users", tags=["users"])

@router.get("/{user_id}")
def get_user(user_id: int):
    return {"id": user_id}
# main.py
from fastapi import FastAPI
from routers import users

app = FastAPI()
app.include_router(users.router)

Частые ошибки

  • Смешение sync и async. Если используете async def, все блокирующие операции (синхронная работа с БД, time.sleep) нужно заменить асинхронными аналогами. Иначе теряется весь смысл асинхронности.

  • Отсутствие response_model. Без response_model FastAPI возвращает все поля объекта, включая пароли и внутренние данные.

  • Запуск с python main.py вместо uvicorn. FastAPI не запускается напрямую — нужен ASGI-сервер (uvicorn, hypercorn, gunicorn с uvicorn workers).

  • Использование глобального состояния. Не храните данные в глобальных переменных — это проблема при масштабировании. Используйте базу данных.

Часто задаваемые вопросы

FastAPI vs Flask — что выбрать?

Flask — простой синхронный фреймворк, подходит для простых приложений и прототипов. FastAPI — асинхронный, с валидацией и документацией из коробки. Для новых проектов, особенно с API, выбирайте FastAPI.

Как подключить базу данных?

FastAPI работает с любой ORM. Для SQLAlchemy используют async_sessionmaker, для PostgreSQL популярна связка FastAPI + SQLAlchemy 2.0 + asyncpg. Для MongoDB — Beanie (async ODM на базе Pydantic).

Как задеплоить FastAPI?

Стандартный способ: gunicorn -w 4 -k uvicorn.workers.UvicornWorker main:app. В Docker: образ tiangolo/uvicorn-gunicorn-fastapi содержит готовую конфигурацию.

Заключение

FastAPI — отличный выбор для создания REST API на Python: минимум boilerplate-кода, встроенная валидация, автоматическая документация и отличная производительность. За 30 минут можно создать рабочий API с документацией.

Для углублённого изучения Python и веб-разработки рекомендуем курс Python с нуля. В первых модулях доступно бесплатное содержание — познакомьтесь с форматом обучения до покупки.

Стрелочка влевоКак выполнять HTTPS-запросы в PythonКак работать с API в PythonСтрелочка вправо

Постройте личный план изучения Python до уровня Middle — бесплатно!

Python — часть карты развития Backend

  • step100+ шагов развития
  • lessons30 бесплатных лекций
  • lessons300 бонусных рублей на счет

Все гайды по Python

Как отправлять запросы с помощью requests в PythonПочему Python выводит значение без команды printКак работает команда print в PythonВозможности Python для автоматизации задачРабота с JSON в Python на примерахPython get — методы получения данныхКак находить и исправлять ошибки в PythonРабота с данными через API и внешние сервисыСтруктура и оформление кода PythonОсновы Django с PythonПолезные приёмы в Python для повседневной работыИспользование locals в Python для отладкиИнтеграция PHP и PythonКак выполнять HTTPS-запросы в PythonFastAPI Python — быстрый старт: создание REST API с нуляКак работать с API в Python
Ввод целого числа в PythonВедение логов в PythonУдаление данных в Python с помощью removeОбработка исключений с помощью try/except в PythonФункция super() в Python — как вызвать метод родителяСоздание собственных контекстных менеджеров в PythonРабота с символами программирования PythonРабота с переменной X в PythonРабота с классами в PythonКак скачать Python на компьютерПростая программа на Python для начинающихОсновы Python для тех, кто начинаетЧто нового в Python 3Поддерживается ли Python 2 и стоит ли его использоватьPython 1 — с чего начиналась история языкаКоманда python print - полное руководство по выводу данныхПравила именования переменных в PythonПользовательские исключения в PythonОсновы Python coreОписание объектов PythonНаследование классов в Python — основы и примерыМножественное наследование в Python — примеры и MROКонтекстный менеджер with в Python — как работает и зачем нуженКомментарии в Python — однострочные, многострочные и docstringКакой Python выбрать для установкиКак вывести целое число с помощью print в PythonКак установить Python на Windows macOS и LinuxКак пользоваться консолью PythonКак получить последний элемент в PythonКак найти значение в PythonКак настроить PythonКак использовать print для строк в PythonКак работает интерпретатор PythonИнструкция по работе с PythonБлок finally в обработке исключений PythonЦелые числа в PythonАбстрактные классы в Python — ABC и abstractmethod
Загрузка данных PythonУправление проектами на GitHub с PythonСоздание веб-приложений на Flask PythonСоздание бота на PythonСоздание интерфейсов Python QTСоздание игр с PygameСоздание GUI в PythonКак работать со словарями в PythonРабота с библиотеками через Python PackagingРабота со временем в Python при помощи модуля timePython name — особенности переменнойМатематические операции в Python с модулем mathPython listing — что это и как использоватьPytest — тестирование на Python: полное руководствоОбработка изображений с OpenCV PythonNumPy в Python — основы и применение в задачахМашинное обучение с PythonИспользование Anaconda с PythonМодуль contextlib в Python — утилиты для контекстных менеджеровБиблиотеки Python и их применение в проектах
Возврат значений из функции в PythonВложенные функции в PythonСоздание собственных декораторов в PythonРабота с функцией map в PythonЦикл while в Python и примеры использованияОбработка чисел, введённых через input в PythonОсновные операторы в Python с примерамиУсловные выражения if else в Python для начинающихКак выполняется вызов функций call в PythonПродвинутые генераторы в Python — send, throw, close и корутиныПозиционные и именованные аргументы в PythonОбъявление переменных и управление областью видимости в PythonПередача аргументов по ссылке и по значению в PythonПередача аргументов через args и kwargs в PythonОсновные методы Python и примеры их использованияОператор match/case в Python 3.10+ — основы структурного сопоставленияПаттерны match/case в Python — деструктуризация, guard и вложенные шаблоныПрактические примеры match/case в Python — реальные сценарии примененияЛокальные и глобальные переменные в PythonЧасто используемые команды PythonКлючевые слова global и nonlocal в PythonКак создавать функции в PythonКак работает сборщик мусора в PythonКак работает область видимости переменных в PythonКак работает функция callable в PythonКак работает функция any и all в PythonКак проверить тип переменной в PythonКак передать функцию как аргумент в PythonКак использовать функцию isinstance в PythonКак использовать функцию filter в PythonКак использовать функцию filter в PythonКак использовать функцию eval безопасно в PythonКак использовать декораторы в PythonИзменяемые и неизменяемые типы данных в PythonГенераторы и yield в Python — как создавать и использоватьГенераторные выражения в Python — синтаксис и примерыФункции в Python и способы их вызоваФункции как объекты в PythonЧто такое замыкания в PythonЧто делает функция reduce в PythonЧто делает функция id в PythonАргументы по умолчанию в PythonАнонимные функции и lambda в PythonАлгоритмы на Python — примеры и объяснение
Запись данных в PythonУстановка pip в PythonУправление зависимостями requirement в PythonУправление библиотеками с помощью Python PackagingУдаление пробелов с помощью strip в PythonСтруктурирование кода в PythonСоздание исполняемого файла Python в exeРазбор traceback в модуле PythonРазбор site-packages в PythonРазбор Program Files в PythonРабота с Unicode кодировками в PythonРабота с системными функциями Python sysРабота с папкой AppData в PythonРабота с модулем logging в PythonРабота с каталогами в PythonРабота с CSV в PythonВиртуальная среда venv в Python — создание и настройкаКак создать простое приложение на PythonИспользование pip в Python для установки пакетовМодули в Python и организация кода в проектеИмпорт модулей в Python и правила подключенияРабота с файлами в Python пошаговоЧто делает компилятор Python и как он работаетПолучение строки из модуля PythonПодключение файлов в Python с includeПеременные среды в PythonСборка проекта с помощью packaging в PythonНастройка Python сервераИспользование Python на UbuntuИспользование консоли PythonИспользование кодировок в PythonИнициализация пакетов PythonИмпорт модулей PythonИмпорт имен в PythonСреда IDLE Python и базовые возможностиЧтение и запись TXT в PythonЧтение файлов в Python с помощью open file
Удаление элементов из списка PythonТипы данных в Python — обзор и рекомендацииОсновные операции со строками в PythonМетоды str в Python и обработка текстаСписки в Python и их ключевые методыСоздание списков данных в PythonРабота со строками и символами в PythonРабота со столбцами в PythonРабота со списком значений в PythonРабота с таблицами в Python с помощью DataFrameРабота с RFR в PythonРабота с пробелами в PythonРабота с массивами в PythonРабота с кортежами tuple PythonРабота с координатами X и Y в PythonРабота с ключами в PythonРабота с элементами данных PythonРабота с двоичными числами PythonРабота с данными в PythonРабота с данными NumPy PythonРабота с большими числами в PythonРабота с битами в PythonРабота с байтами в PythonЧто такое значение в Python и как его определитьМножества в Python и операции с нимиИспользование range в Python для цикловПроверка на четность в PythonПроверка числа в PythonПреобразование типов в PythonПреобразование списка в строку PythonПреобразование числа в строку в PythonПостроение графиков в PythonОпределение индекса элемента в PythonОкругление чисел в PythonОбъединение списков в Python с помощью zipМножества в PythonМассивы в Python и отличие от списковМассив чисел в PythonКортежи данных в PythonКак вычислить сумму чисел в PythonКак получить остаток от деления в PythonКак найти следующее число в PythonИспользование Unicode в PythonТип int в Python и его особенностиИндекс списка в PythonФункции для работы со строками в PythonЭлементы Python и способы доступа к нимДоступ к элементам массива в PythonДеление чисел в PythonРабота с данными в Python на практикеКак работать с числами в Python
Открыть базу знаний

Лучшие курсы по теме

Иконка молнииНовый
изображение курса

Основы Python

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Nest.js с нуля

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.6
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Docker и Ansible

Антон Ларичев
AI-тренажерыAI-тренажеры
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее

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