FastAPI: Разработка современных веб-API

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

1. Основы FastAPI: установка, создание первого приложения и работа с параметрами запросов

Основы FastAPI: установка, создание первого приложения и работа с параметрами запросов

Добро пожаловать в курс FastAPI: Разработка современных веб-API. Это первая статья, с которой начнется ваше погружение в один из самых быстрых и удобных фреймворков для создания веб-сервисов на языке Python.

В последние годы Python укрепил свои позиции в веб-разработке, и FastAPI сыграл в этом ключевую роль. Если раньше стандартом считались Django или Flask, то сегодня для создания микросервисов и API разработчики всё чаще выбирают FastAPI. Почему? Ответ кроется в названии: он действительно быстрый, но не только в плане производительности кода, но и в скорости разработки.

В этой статье мы разберем фундамент: подготовим рабочее окружение, напишем наше первое приложение «Hello World», научимся запускать сервер и разберемся, как передавать данные через URL.

Что такое FastAPI и зачем он нужен?

FastAPI — это современный веб-фреймворк для создания API на Python 3.8+, основанный на стандартных подсказках типов (type hints).

Ключевые особенности, которые делают его уникальным:

* Скорость: Он сопоставим по производительности с NodeJS и Go (благодаря Starlette и Pydantic). * Простота: Интуитивно понятный синтаксис, снижающий вероятность ошибок. * Автоматическая документация: Одна из самых любимых функций разработчиков. Вы пишете код, а FastAPI сам генерирует интерактивную документацию (Swagger UI). * Асинхронность: Встроенная поддержка async и await.

!Схематичное изображение потока обработки запроса: от клиента через сервер Uvicorn к приложению FastAPI и обратно.

Установка и подготовка окружения

Прежде чем писать код, необходимо подготовить почву. Хорошей практикой в Python является использование виртуальных окружений. Это позволяет изолировать зависимости вашего проекта от системных библиотек.

Шаг 1. Создание виртуального окружения

Откройте терминал (командную строку) и выполните следующие команды:

Для Windows:

Для macOS и Linux:

После активации вы увидите префикс (venv) в командной строке.

Шаг 2. Установка библиотек

Нам понадобятся два основных компонента:

  • FastAPI — сам фреймворк.
  • Uvicorn — ASGI-сервер, который будет запускать наше приложение.
  • Выполните команду:

    > Мы устанавливаем uvicorn[standard], чтобы получить рекомендованные зависимости (включая uvloop для высокой производительности), которые используются в продакшене.

    Создание первого приложения

    Создайте файл с именем main.py. Это будет точка входа в наше приложение. Откройте его в любимом редакторе кода (VS Code, PyCharm или Sublime Text) и напишите следующий код:

    Давайте разберем этот код построчно:

  • from fastapi import FastAPI: Импортируем класс FastAPI.
  • app = FastAPI(): Создаем экземпляр этого класса. Переменная app будет основным объектом нашего приложения.
  • @app.get("/"): Это декоратор операции пути.
  • * @app обращается к нашему приложению. * .get говорит о том, что функция будет обрабатывать HTTP-запросы метода GET. * ("/") указывает путь (маршрут), по которому будет доступна функция. В данном случае это корень сайта.
  • async def root(): Асинхронная функция Python. FastAPI отлично работает и с обычными def, но использование async позволяет реализовать асинхронную обработку запросов.
  • return {"message": "Hello World"}: Мы возвращаем словарь (dict). FastAPI автоматически преобразует его в формат JSON.
  • Запуск сервера

    Теперь, когда код написан, нужно запустить сервер. Вернитесь в терминал и выполните команду:

    Разбор команды: * main: имя файла Python (модуля) без расширения .py. * app: имя переменной, в которой создан экземпляр FastAPI внутри файла main.py. * --reload: флаг, который заставляет сервер автоматически перезагружаться при изменении кода. Очень удобно при разработке, но не используйте его в продакшене.

    Если все прошло успешно, вы увидите вывод, похожий на этот:

    Откройте браузер и перейдите по адресу http://127.0.0.1:8000. Вы увидите JSON-ответ:

    Интерактивная документация

    Теперь перейдите по адресу http://127.0.0.1:8000/docs.

    Вы увидите Swagger UI — интерактивную документацию, которая позволяет тестировать ваши API прямо из браузера. Это одна из «киллер-фич» FastAPI. Вам не нужно писать документацию вручную; фреймворк делает это за вас, анализируя типы данных в функциях.

    Также доступна альтернативная документация по адресу /redoc.

    Работа с параметрами пути (Path Parameters)

    Часто нам нужно передавать данные прямо в URL, например, ID пользователя или название товара. В FastAPI это делается очень просто.

    Добавьте следующий код в main.py:

    Обратите внимание на фигурные скобки {item_id} в декораторе и аргумент item_id: int в функции.

    !Разбор структуры URL: отличие параметров пути от параметров запроса.

    Валидация типов

    В примере выше мы указали тип int. Что произойдет, если мы попробуем передать строку?

  • Откройте http://127.0.0.1:8000/items/5. Вы получите {"item_id": 5}. Обратите внимание, что число 5 в JSON не в кавычках — FastAPI автоматически преобразовал строку из URL в число int.
  • Откройте http://127.0.0.1:8000/items/foo. Вы увидите сообщение об ошибке:
  • FastAPI автоматически провел валидацию данных. Это избавляет вас от написания множества проверок if type(item_id) != int... внутри функции.

    Работа с параметрами запроса (Query Parameters)

    Параметры запроса — это пары ключ-значение, которые идут после знака ? в URL, разделенные амперсандом &. Например: /items/?skip=0&limit=10.

    В FastAPI параметры запроса объявляются как аргументы функции, которые не являются частью пути.

    Здесь skip и limit — это параметры запроса.

    * Поскольку мы задали им значения по умолчанию (= 0 и = 10), они являются необязательными. * Если вы перейдете на /items/, FastAPI использует значения по умолчанию. * Если вы перейдете на /items/?skip=1&limit=1, вы получите только второй элемент списка.

    Необязательные параметры

    Иногда параметр запроса должен быть необязательным, но при этом не иметь значения по умолчанию (быть None). Для этого используется Optional из модуля typing (или Union[str, None] в Python 3.10+).

    В этом примере мы объединили всё, что изучили:

  • user_id и item_idпараметры пути (они есть в строке URL декоратора).
  • q и shortпараметры запроса (их нет в строке URL декоратора).
  • q — необязательный строковый параметр (по умолчанию None).
  • short — булевый параметр. FastAPI умеет распознавать true, 1, yes, on как True и false, 0, no, off как False.
  • Попробуйте сделать запрос: /users/1/items/myitem?q=search&short=true.

    Заключение

    Поздравляю! Вы создали свое первое API на FastAPI. Мы научились: * Устанавливать и запускать FastAPI с Uvicorn. * Создавать простые GET-запросы. * Использовать автоматическую документацию. * Принимать данные через параметры пути и параметры запроса. * Использовать встроенную валидацию типов.

    В следующей статье мы углубимся в работу с телом запроса (Request Body) и моделями Pydantic, что позволит нам передавать на сервер сложные структуры данных, а не только строки и числа.

    2. Валидация данных с Pydantic: создание схем, типизация и обработка ошибок

    Валидация данных с Pydantic: создание схем, типизация и обработка ошибок

    В предыдущей статье мы научились создавать простые эндпоинты и принимать данные через параметры пути и запроса. Это отлично работает для передачи идентификаторов (id=5) или настроек фильтрации (limit=10). Но что делать, если нам нужно отправить на сервер сложные данные? Например, форму регистрации пользователя с именем, почтой, паролем и возрастом?

    Передавать такие данные через URL неудобно и небезопасно. Для этого используется тело запроса (Request Body). В экосистеме FastAPI стандартом де-факто для обработки таких данных является библиотека Pydantic.

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

    Что такое Pydantic?

    Pydantic — это библиотека для парсинга и валидации данных в Python. Она использует стандартные подсказки типов (type hints), которые появились в Python 3.6+.

    Главное отличие Pydantic от других библиотек валидации заключается в том, что Pydantic не просто проверяет типы, он пытается их привести (спарсить). Если вы ожидаете число int, а приходит строка "42", Pydantic автоматически преобразует её в число 42. Если же преобразование невозможно (например, пришла строка "hello"), будет вызвана ошибка валидации.

    !Визуализация процесса обработки данных: от сырого JSON через валидацию Pydantic к готовому объекту Python или ошибке.

    Создание первой модели данных

    Чтобы определить структуру тела запроса, нам нужно создать Pydantic-модель. Модель — это класс, который наследуется от BaseModel из библиотеки pydantic.

    Давайте создадим модель для товара в интернет-магазине.

    Разберем, что происходит в этом коде:

  • Импорт BaseModel: Это базовый класс для всех моделей данных.
  • Определение полей: Внутри класса Item мы объявляем поля с аннотацией типов:
  • * name: str — обязательное строковое поле. * description: Union[str, None] = None — необязательное поле. Если оно не передано, значением будет None. * price: float — обязательное числовое поле (с плавающей точкой). * tax: float = 10.5 — необязательное поле. Если не передано, значением будет 10.5.
  • Использование в эндпоинте: В функции create_item мы указываем аргумент item с типом Item.
  • Как это работает?

    Когда FastAPI получает POST-запрос на /items/, он выполняет следующие действия:

  • Считывает тело запроса как JSON.
  • Преобразует типы данных (если необходимо).
  • Валидирует данные. Если обязательное поле отсутствует или имеет неверный тип, возвращается ошибка.
  • Передает в функцию create_item готовый объект item. Это уже не просто словарь dict, а экземпляр класса Item. Вы можете обращаться к его полям через точку: item.name, item.price.
  • Расширенная валидация с помощью Field

    Иногда простой проверки типов недостаточно. Например, цена не может быть отрицательной, а название товара не должно превышать 50 символов. Для таких ограничений Pydantic предоставляет функцию Field.

    Основные параметры Field:

    * default: значение по умолчанию. * max_length / min_length: ограничение длины для строк. * gt (greater than): строго больше >. * ge (greater than or equal): больше или равно >=. * lt (less than): строго меньше <. * le (less than or equal): меньше или равно <=. * description: описание поля, которое попадет в автоматическую документацию Swagger UI.

    > Использование Field позволяет не писать лишние проверки if внутри функции-обработчика. Вся "грязная" работа по валидации происходит до того, как код функции начнет выполняться.

    Вложенные модели

    JSON-объекты часто имеют сложную структуру. Например, у товара может быть список тегов или вложенный объект с характеристиками. Pydantic позволяет использовать одни модели в качестве типов полей для других.

    В этом примере: * tags — это список строк. Pydantic ожидает JSON-массив: ["new", "sale"]. * image — это вложенная модель Image. Pydantic будет ожидать JSON-объект внутри поля image.

    Пример валидного JSON для такой модели:

    Обработка ошибок валидации

    Что произойдет, если клиент отправит некорректные данные? Например, забудет поле price или отправит строку "бесплатно" вместо числа?

    FastAPI автоматически перехватит исключение RequestValidationError и вернет клиенту HTTP-ответ со статусом 422 Unprocessable Entity.

    Тело ответа будет содержать детальную информацию о том, где именно произошла ошибка. Это невероятно удобно для фронтенд-разработчиков, которые интегрируются с вашим API.

    Пример ответа с ошибкой:

    * loc: местоположение ошибки. В данном случае: в теле запроса (body), поле price. * msg: сообщение об ошибке («поле обязательно»). * type: технический код ошибки.

    Pydantic v1 vs v2

    Стоит отметить, что в 2023 году вышла вторая версия Pydantic (v2), ядро которой переписано на языке Rust. Это дало огромный прирост производительности (в некоторых тестах до 20 раз быстрее).

    FastAPI поддерживает обе версии. Синтаксис, который мы рассматривали выше, является совместимым и стандартным. Однако, если вы используете новейшие версии библиотек, вы получаете прирост скорости "из коробки" без изменения кода.

    Заключение

    Использование Pydantic в связке с FastAPI дает разработчику мощный инструмент для работы с данными:

  • Декларативность: Вы описываете, как должны выглядеть данные, а не пишете код для их проверки.
  • Безопасность: Вы гарантированно получаете данные правильных типов внутри функции.
  • Документация: Все схемы моделей автоматически отображаются в Swagger UI.
  • Теперь, когда мы умеем принимать и валидировать данные, в следующей статье мы рассмотрим, как структурировать наше приложение, чтобы оно не превратилось в один огромный файл, и познакомимся с APIRouter.

    3. Работа с базами данных: интеграция SQLAlchemy, асинхронность и CRUD операции

    Работа с базами данных: интеграция SQLAlchemy, асинхронность и CRUD операции

    В предыдущих статьях мы научились создавать API, обрабатывать параметры запросов и валидировать входящие данные с помощью Pydantic. Однако, до сих пор наши данные жили только в оперативной памяти. Стоило перезапустить сервер, и все созданные «товары» исчезали. В реальных приложениях это недопустимо.

    В этой статье мы добавим нашему приложению долгосрочную память. Мы подключим реляционную базу данных, используя SQLAlchemy — самую популярную ORM (Object-Relational Mapping) в мире Python. Мы будем использовать современный асинхронный подход, чтобы наше приложение оставалось быстрым даже при высокой нагрузке.

    Зачем нам ORM и асинхронность?

    Работа с базой данных напрямую через SQL-запросы (например, SELECT * FROM users) эффективна, но утомительна и чревата ошибками. ORM позволяет нам работать с таблицами базы данных как с обычными классами Python, а со строками — как с объектами.

    !Поток данных: от HTTP-запроса до записи в базу данных через слои валидации и ORM

    Почему асинхронность важна именно здесь? Операции с базой данных — это операции ввода-вывода (I/O). Пока база данных ищет нужную информацию или записывает её на диск, процессор нашего сервера простаивает. Используя async и await, мы позволяем FastAPI обрабатывать другие запросы в то время, пока база данных занята работой.

    Подготовка окружения

    Для начала установим необходимые библиотеки. Мы будем использовать SQLAlchemy версии 2.0+ и драйвер aiosqlite для работы с базой данных SQLite асинхронно. SQLite идеально подходит для обучения, так как не требует установки отдельного сервера базы данных.

    Выполните команду в терминале:

    Настройка подключения к базе данных

    Хорошей практикой является вынесение настроек базы данных в отдельный файл. Создайте файл database.py в корне вашего проекта.

    Разберем ключевые моменты:

  • create_async_engine: Создает точку входа в базу данных. Мы используем драйвер aiosqlite.
  • SessionLocal: Это фабрика, которая будет создавать новые сессии для каждого запроса.
  • Base: От этого класса мы будем наследовать все наши модели таблиц.
  • Создание моделей SQLAlchemy

    Модель SQLAlchemy описывает структуру таблицы в базе данных. Не путайте её с Pydantic-моделью! Pydantic отвечает за валидацию данных API, а SQLAlchemy — за структуру данных в БД.

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

    Здесь мы определили таблицу items с полями id, title, description, price и is_active.

    Разделение схем: Pydantic vs SQLAlchemy

    Это один из самых важных моментов архитектуры FastAPI. Нам нужны разные схемы для разных целей:

  • ItemCreate: То, что пользователь отправляет нам (без ID, так как ID генерирует база).
  • ItemResponse: То, что мы отдаем пользователю (с ID и, возможно, другими системными полями).
  • Обновим наш файл schemas.py (или создадим его, если вы писали всё в main.py):

    Параметр from_attributes=True (в старых версиях orm_mode=True) говорит Pydantic, что данные могут прийти не только в виде словаря, но и в виде объекта класса (нашей модели SQLAlchemy).

    Внедрение зависимостей (Dependency Injection)

    Теперь нам нужно связать всё это в main.py. Нам понадобится функция, которая будет открывать сессию базы данных перед запросом и закрывать её после, даже если произошла ошибка.

    В FastAPI для этого используется механизм Depends и генераторы yield.

    Реализация CRUD операций

    CRUD расшифровывается как Create, Read, Update, Delete. Давайте реализуем эти операции.

    1. Create (Создание)

    Мы принимаем ItemCreate (Pydantic), создаем DBItem (SQLAlchemy), сохраняем и возвращаем результат.

    Обратите внимание на await db.commit() и await db.refresh(). Это асинхронные вызовы, которые реально обращаются к базе данных.

    2. Read (Чтение)

    Получение списка всех товаров и одного товара по ID.

    В SQLAlchemy 2.0 основной способ получения данных — это конструкция select. Метод scalars() извлекает объекты моделей из результатов запроса.

    3. Update (Обновление)

    Для обновления нам нужно сначала найти объект, изменить его поля и снова сохранить.

    4. Delete (Удаление)

    Заключение

    Мы проделали большую работу! Теперь ваше приложение на FastAPI обладает полноценным бэкендом с базой данных. Мы:

    * Настроили асинхронное подключение через SQLAlchemy и aiosqlite. * Разделили модели данных (БД) и схемы валидации (Pydantic). * Реализовали полный цикл CRUD операций.

    В следующей статье мы рассмотрим вопросы аутентификации и безопасности: как защитить наши эндпоинты и реализовать регистрацию пользователей.

    4. Безопасность и аутентификация: реализация OAuth2, JWT токены и защита маршрутов

    Безопасность и аутентификация: реализация OAuth2, JWT токены и защита маршрутов

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

    Сегодня мы займемся безопасностью. Мы внедрим систему регистрации и входа, научимся хешировать пароли и использовать JWT (JSON Web Tokens) для аутентификации пользователей. Мы будем использовать стандарт OAuth2, который встроен в FastAPI «из коробки».

    Основные концепции безопасности

    Прежде чем писать код, разберем три кита, на которых держится защита веб-приложений:

  • Аутентификация (Authentication): Проверка того, кем является пользователь (например, проверка логина и пароля). Ответ на вопрос: «Кто ты?».
  • Авторизация (Authorization): Проверка прав доступа. Ответ на вопрос: «Что тебе можно делать?».
  • Хеширование: Процесс преобразования пароля в необратимую строку символов для безопасного хранения.
  • !Визуализация различий между аутентификацией (проверка личности) и авторизацией (проверка прав доступа).

    Подготовка окружения

    Для работы с безопасностью нам понадобятся дополнительные библиотеки:

    * passlib[bcrypt]: Для надежного хеширования паролей. * python-jose[cryptography]: Для создания и проверки JWT токенов. * python-multipart: Для обработки данных формы (требуется для OAuth2 в FastAPI).

    Установите их командой:

    Хеширование паролей

    Никогда не храните пароли в открытом виде! Если злоумышленник получит доступ к вашей базе данных, он украдет аккаунты всех пользователей. Вместо пароля мы храним его хеш.

    Создайте файл security.py (или добавьте этот код в main.py для простоты, но лучше разделять логику):

    Теперь, когда пользователь регистрируется, мы сохраняем результат get_password_hash(password). Когда входит — проверяем через verify_password.

    Что такое JWT (JSON Web Token)?

    JWT — это стандарт для безопасной передачи информации между сторонами в виде JSON-объекта. В веб-разработке он используется как «пропуск». После успешного входа сервер выдает клиенту токен. Клиент прикрепляет этот токен к каждому следующему запросу.

    Токен состоит из трех частей, разделенных точками:

  • Header (Заголовок): Тип токена и алгоритм шифрования.
  • Payload (Полезная нагрузка): Данные пользователя (ID, имя, срок действия токена).
  • Signature (Подпись): Гарантия того, что токен не был изменен.
  • Математически подпись можно представить так:

    Где — итоговая подпись, — заголовок, — полезная нагрузка, а — секретный ключ, который знает только сервер.

    !Структура JWT токена: заголовок, полезная нагрузка и цифровая подпись.

    Реализация работы с токенами

    Добавим в security.py функции для создания токена:

    Интеграция OAuth2 в FastAPI

    FastAPI предоставляет класс OAuth2PasswordBearer, который автоматически извлекает токен из заголовка запроса Authorization.

    В файле main.py:

    Функция get_current_user — это наша главная зависимость. Она:

  • Ищет токен в заголовке.
  • Проверяет его подпись и срок действия.
  • Достает имя пользователя.
  • Если что-то не так — выбрасывает ошибку 401.
  • Создание эндпоинта для входа (Login)

    Теперь создадим маршрут, который будет принимать логин/пароль и выдавать токен. FastAPI имеет специальный класс OAuth2PasswordRequestForm для обработки таких форм.

    Защита маршрутов

    Теперь самое интересное. Как защитить наши эндпоинты создания или удаления товаров? Мы просто добавляем зависимость get_current_user.

    Если вы попробуете отправить запрос на /users/me без токена, вы получите ошибку:

    Как это выглядит в Swagger UI?

    Перейдите на /docs. Вы увидите кнопку Authorize (зеленый замок) справа сверху.

  • Нажмите на неё.
  • Введите username (любой) и password (в нашем примере "secret").
  • Нажмите Login.
  • Swagger автоматически сохранит токен и будет прикреплять его ко всем запросам с замком.
  • Это делает тестирование защищенного API невероятно удобным.

    Заключение

    Мы реализовали современную систему аутентификации на основе JWT.

    Что мы узнали: * Пароли нужно хешировать (библиотека passlib). * JWT токены позволяют серверу не хранить состояние сессии (python-jose). * OAuth2PasswordBearer в FastAPI связывает всё воедино, извлекая токены из заголовков. * Зависимость Depends(get_current_user) позволяет защитить любой маршрут одной строчкой кода.

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

    5. Тестирование и деплой: написание тестов на Pytest, контейнеризация в Docker и запуск

    Тестирование и деплой: написание тестов на Pytest, контейнеризация в Docker и запуск

    Мы прошли долгий путь. Мы создали быстрое API на FastAPI, подключили базу данных через SQLAlchemy, настроили асинхронность и защитили наше приложение с помощью JWT-токенов. Наше приложение работает на локальном компьютере разработчика. Но готово ли оно к реальному миру?

    В этой финальной статье курса мы займемся двумя критически важными аспектами профессиональной разработки:

  • Тестирование: Как убедиться, что новые изменения не сломали старый функционал?
  • Деплой (развертывание): Как упаковать приложение так, чтобы оно гарантированно запускалось на любом сервере?
  • Автоматическое тестирование с Pytest

    Ручное тестирование (отправка запросов через Swagger UI или Postman) — это хорошо для быстрой проверки, но плохо для долгосрочной поддержки. Представьте, что вы изменили логику регистрации. Вам придется вручную проверять не только регистрацию, но и вход, создание товаров и другие функции, чтобы убедиться, что ничего не сломалось. Это долго и ненадежно.

    Решение — автоматические тесты. В экосистеме Python стандартом де-факто является библиотека pytest.

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

    Нам понадобятся: * pytest: сам фреймворк для тестирования. * httpx: современный HTTP-клиент, который поддерживает асинхронные запросы (необходим для тестирования асинхронных эндпоинтов FastAPI). * pytest-asyncio: плагин для поддержки асинхронных тестов.

    Выполните команду:

    Настройка окружения: conftest.py

    В pytest есть специальный файл conftest.py. В нем определяются фикстуры (fixtures) — функции, которые подготавливают данные или настройки перед запуском тестов.

    Нам нужно решить сложную задачу: как тестировать приложение, использующее базу данных, не засоряя реальную БД? Обычно для тестов создают отдельную базу данных (например, test.db) или используют базу в оперативной памяти.

    Создайте файл conftest.py в корне проекта:

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

    Написание первого теста

    Создайте файл test_main.py. Pytest автоматически находит все файлы, начинающиеся на test_.

    Теперь запустите тесты командой:

    Вы увидите зеленый отчет, если все прошло успешно. Это дает уверенность, что ваш код работает так, как задумано.

    Контейнеризация с Docker

    Вы наверняка слышали фразу: «Но на моем компьютере это работает!». Это классическая проблема разработки. У вас Python 3.11, на сервере 3.9. У вас Windows, на сервере Linux. У вас одни версии библиотек, там — другие.

    Docker решает эту проблему. Он упаковывает ваше приложение и все его зависимости (включая саму ОС) в контейнер. Контейнер гарантированно работает одинаково везде.

    !Сравнение архитектуры: Виртуальные машины против Контейнеров

    Создание Dockerfile

    Dockerfile — это инструкция по сборке образа вашего приложения. Создайте файл с именем Dockerfile (без расширения) в корне проекта:

    Не забудьте создать файл requirements.txt, если его еще нет:

    Сборка и запуск

    Теперь соберем наш образ (image). Образ — это «слепок» приложения, из которого потом запускаются контейнеры.

    * -t my-fastapi-app: задает имя (тег) нашему образу. * .: указывает, что Dockerfile находится в текущей папке.

    После успешной сборки запустим контейнер:

    * -d: Detached mode (запуск в фоновом режиме). * -p 8000:8000: Проброс портов. Порт 8000 на вашем компьютере будет перенаправлять запросы на порт 8000 внутри контейнера.

    Теперь ваше приложение доступно по адресу http://localhost:8000, но работает оно внутри изолированного Linux-окружения.

    Оркестрация с Docker Compose

    В реальном приложении у вас будет не только FastAPI, но и база данных (PostgreSQL), кэш (Redis), веб-сервер (Nginx). Запускать их все отдельными командами docker run неудобно.

    Docker Compose позволяет описать все сервисы в одном файле docker-compose.yml и запускать их одной командой.

    Создайте файл docker-compose.yml:

    Запуск всех сервисов:

    Теперь у вас есть полноценная инфраструктура, описанная в коде (Infrastructure as Code).

    Заключение курса

    Поздравляю! Вы прошли полный путь разработки современного веб-API на Python.

    Мы изучили:

  • Основы FastAPI: маршрутизация и параметры.
  • Pydantic: строгая валидация данных.
  • SQLAlchemy: асинхронная работа с базами данных.
  • Безопасность: аутентификация через JWT и OAuth2.
  • DevOps: тестирование и контейнеризация.
  • Теперь вы обладаете набором навыков, достаточным для создания надежных, быстрых и безопасных бэкенд-сервисов, готовых к работе в продакшене. FastAPI продолжает развиваться, и я рекомендую следить за официальной документацией, чтобы быть в курсе новых возможностей.

    Удачи в ваших проектах!