Skip to content

Template for fast api projects with libraries: fastapi, uvicorn, environs, black, flake8, isort, pre-commit.

Notifications You must be signed in to change notification settings

Mikey191/fastapi_project

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🔹 Базовая настройка FastAPI

По шагам:


🟩 Шаг 1. Создание структуры проекта и main.py

📁 Структура на этом этапе:

fastapi_project/
├── app/
│   ├── __init__.py
│   └── main.py
├── requirements.txt

🔧 Что делать:

1.1. Создаем проект и виртуальное окружение

Открой VSCode, открой терминал (Ctrl + ~) и выполни:

mkdir fastapi_project
cd fastapi_project
python -m venv venv
.\venv\Scripts\Activate.ps1  # Активируем виртуальное окружение в PowerShell

Теперь ты должен видеть что-то вроде: (venv) PS C:\...\fastapi_project> — это значит окружение работает.


1.2. Установка FastAPI и Uvicorn

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

📄 requirements.txt

fastapi
uvicorn[standard]

Установи зависимости:

pip install -r requirements.txt

1.3. Создаем папку app и файл main.py

mkdir app
ni app\main.py
ni app\__init__.py

📄 app/main.py

from fastapi import FastAPI

# Создаем экземпляр приложения FastAPI
app = FastAPI()

# Простейший маршрут
@app.get("/")
def read_root():
    return {"message": "Hello, FastAPI!"}

✅ Как запустить приложение

Запуск в PowerShell из корня проекта:

uvicorn app.main:app --reload
  • app.main — путь до файла app/main.py
  • app — объект FastAPI внутри файла
  • --reload — сервер будет перезапускаться при изменении кода

🌐 Проверка

Перейди в браузере по адресам:


✅ Результат:

  • У тебя есть минимальный рабочий FastAPI проект
  • Он запускается через Uvicorn
  • Есть один GET-эндпоинт /

🟩 Шаг 2. Добавление models.py и POST-обработки с Pydantic


🔧 Что мы делаем на этом шаге:

  1. Создаём файл models.py
  2. Определяем Pydantic-модель User
  3. Обновляем main.py — добавим POST-эндпоинт, который принимает JSON и возвращает его обратно
  4. Протестируем через Swagger

📁 Структура проекта после этого шага:

fastapi_project/
├── app/
│   ├── __init__.py
│   ├── main.py
│   └── models.py          👈 Новый файл
├── requirements.txt

📄 1. Создаём файл app/models.py

Если в терминале:

ni app\models.py

Добавим туда модель:

from pydantic import BaseModel

# Модель для POST-запроса
class User(BaseModel):
    username: str
    message: str

Пояснение:

  • BaseModel — базовый класс Pydantic
  • FastAPI будет использовать эту модель для валидации входящего JSON
  • Если поля отсутствуют или неверного типа — автоматически вернётся 422 ошибка

📄 2. Обновим app/main.py

Добавим POST-эндпоинт:

from fastapi import FastAPI
from app.models import User  # 👈 Импорт модели

app = FastAPI()

@app.get("/")
def read_root():
    return {"message": "Hello, FastAPI!"}

@app.post("/")
async def create_user(user: User):
    """
    Пример приёма JSON через POST-запрос.
    Данные автоматически валидируются Pydantic.
    """
    return {
        "username": user.username,
        "message": user.message,
        "status": "Received successfully ✅"
    }

🔃 3. Перезапусти сервер (если ещё не запущен с --reload, просто сохрани файл)

uvicorn app.main:app --reload

🔬 4. Протестируй POST-запрос в Swagger UI

Перейди по адресу: 👉 http://localhost:8000/docs

Найди раздел POST / → нажми “Try it out”

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

{
  "username": "Vasya",
  "message": "I am Batman"
}

Ты должен получить ответ:

{
  "username": "Vasya",
  "message": "I am Batman",
  "status": "Received successfully ✅"
}

✅ Результат:

  • У тебя есть Pydantic-модель User
  • Она используется в POST-запросе по пути /
  • Валидация работает автоматически
  • Можно тестировать прямо из браузера через Swagger

🟩 Шаг 3: Работа с переменными окружения и конфигурацией проекта

На этом этапе ты:

  • Создашь .env файл с настройками
  • Добавишь config.py, который будет безопасно читать переменные окружения
  • Подключишь эту конфигурацию в main.py (например, чтобы отобразить DATABASE_URL)

🧱 Структура проекта после этого шага:

fastapi_project/
├── app/
│   ├── __init__.py
│   ├── main.py
│   ├── models.py
│   └── config.py       👈 Новый файл
├── .env                👈 Новый файл
├── requirements.txt

📦 1. Установка библиотеки environs

Это удобный способ работать с .env файлами (альтернатива python-dotenv).

pip install environs

И обязательно добавь в requirements.txt:

environs

📄 2. Создание .env файла в корне проекта

Создай файл .env в корне (рядом с requirements.txt).

Можно через терминал:

ni .env

И добавь туда следующее:

DATABASE_URL=sqlite:///./test.db
SECRET_KEY=my_super_secret_key
DEBUG=True

📄 3. Создание app/config.py

from dataclasses import dataclass
from environs import Env

# Конфиг для БД
@dataclass
class DatabaseConfig:
    database_url: str

# Общая конфигурация проекта
@dataclass
class Config:
    db: DatabaseConfig
    secret_key: str
    debug: bool

# Функция загрузки из .env
def load_config(path: str = None) -> Config:
    env = Env()
    env.read_env(path)  # Загружаем переменные окружения из .env

    return Config(
        db=DatabaseConfig(
            database_url=env("DATABASE_URL")
        ),
        secret_key=env("SECRET_KEY"),
        debug=env.bool("DEBUG", default=False)
    )

🔁 4. Обновление main.py — подключим конфиг

Теперь обновим main.py, чтобы использовать конфигурацию:

from fastapi import FastAPI
from app.models import User
from app.config import load_config  # 👈 Импортируем конфигурацию

app = FastAPI()

# Загружаем конфиг
config = load_config()

@app.get("/")
def read_root():
    return {"message": "Hello, FastAPI!"}

@app.post("/")
async def create_user(user: User):
    return {
        "username": user.username,
        "message": user.message,
        "status": "Received successfully ✅"
    }

@app.get("/db")
def get_db_info():
    """
    Возвращает строку подключения к БД из переменной окружения
    """
    return {"db_url": config.db.database_url}

🚀 5. Перезапусти сервер (если уже не активен)

uvicorn app.main:app --reload

🌐 6. Проверка

Перейди по адресу:

Ты должен увидеть:

{
  "db_url": "sqlite:///./test.db"
}

✅ Результат:

  • Переменные хранятся в .env и не захардкожены
  • Все настройки централизованы в config.py
  • main.py читает эти переменные через load_config()
  • Ты можешь легко переключаться между dev/prod-режимами через .env

🟩 Шаг 4: Логирование в FastAPI через отдельный модуль logger.py

На этом шаге:

  • Создаём файл logger.py с настройкой логирования
  • Подключаем его в main.py
  • Добавим логирование действий (например, POST-запросов)

📁 Структура проекта после шага:

fastapi_project/
├── app/
│   ├── __init__.py
│   ├── main.py
│   ├── models.py
│   ├── config.py
│   └── logger.py       👈 Новый файл
├── .env
├── requirements.txt

📄 1. Создание app/logger.py

Создай файл через PowerShell:

ni app\logger.py

Добавь код:

import logging

def setup_logger():
    # Создаем объект логгера
    logger = logging.getLogger("my_app")
    logger.setLevel(logging.DEBUG)  # Уровень логирования (можно INFO/ERROR/WARNING)

    # Создаем консольный обработчик
    ch = logging.StreamHandler()
    ch.setLevel(logging.DEBUG)

    # Формат сообщений
    formatter = logging.Formatter(
        "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
    )
    ch.setFormatter(formatter)

    # Добавляем обработчик к логгеру
    logger.addHandler(ch)

    return logger

# Глобальный логгер для импорта
logger = setup_logger()

📄 2. Обновим main.py — логгируем действия

Теперь добавим логгер:

from fastapi import FastAPI
from app.models import User
from app.config import load_config
from app.logger import logger  # 👈 Импортируем логгер

app = FastAPI()
config = load_config()

@app.get("/")
def read_root():
    logger.info("GET / — Hello message отправлен")
    return {"message": "Hello, FastAPI!"}

@app.post("/")
async def create_user(user: User):
    logger.info(f"POST / — получены данные от пользователя: {user.username}")
    return {
        "username": user.username,
        "message": user.message,
        "status": "Received successfully ✅"
    }

@app.get("/db")
def get_db_info():
    logger.debug("GET /db — возвращаем строку подключения к БД")
    return {"db_url": config.db.database_url}

📺 3. Перезапусти сервер (если ещё не запущен)

uvicorn app.main:app --reload

🧪 4. Протестируй и посмотри в терминал

Зайди на:

Сделай GET и POST-запросы. В терминале VSCode ты увидишь:

2025-07-04 10:25:34,102 - my_app - INFO - GET / — Hello message отправлен
2025-07-04 10:25:38,499 - my_app - INFO - POST / — получены данные от пользователя: Vasya
2025-07-04 10:25:42,341 - my_app - DEBUG - GET /db — возвращаем строку подключения к БД

✅ Результат:

  • У тебя есть централизованный логгер
  • Все важные события логируются в консоль
  • Можно в будущем логировать в файл или отправлять в Sentry

🟩 Шаг 5: Завершение настройки .env и переменных окружения

На этом этапе:

  • Подчистим и проверим .env
  • Расширим его для продакшн/отладки
  • Подтвердим, как DEBUG и SECRET_KEY читаются в main.py
  • Добавим защиту от случайного запуска без .env

📁 Актуальная структура проекта:

fastapi_project/
├── app/
│   ├── __init__.py
│   ├── main.py
│   ├── models.py
│   ├── config.py
│   └── logger.py
├── .env                    ✅
├── requirements.txt

🔧 1. Проверим содержимое .env

📄 .env

DATABASE_URL=sqlite:///./test.db
SECRET_KEY=my_super_secret_key
DEBUG=True

📄 2. Добавим в main.py использование этих переменных

Теперь в main.py мы можем использовать config.secret_key и config.debug.

Обнови main.py:

from fastapi import FastAPI
from app.models import User
from app.config import load_config
from app.logger import logger

app = FastAPI()
config = load_config()

@app.get("/")
def read_root():
    logger.info("GET / — Hello message отправлен")
    return {
        "message": "Hello, FastAPI!",
        "debug": config.debug
    }

@app.post("/")
async def create_user(user: User):
    logger.info(f"POST / — получены данные от пользователя: {user.username}")
    return {
        "username": user.username,
        "message": user.message,
        "status": "Received successfully ✅",
        "secret_key_used": config.secret_key
    }

@app.get("/db")
def get_db_info():
    logger.debug("GET /db — возвращаем строку подключения к БД")
    return {
        "db_url": config.db.database_url
    }

⚠️ 3. Защита от отсутствия .env

Обновим config.py — если .env не найден, отобразим понятное сообщение.

📄 app/config.py (добавим обработку ошибок):

from dataclasses import dataclass
from environs import Env
from pathlib import Path

@dataclass
class DatabaseConfig:
    database_url: str

@dataclass
class Config:
    db: DatabaseConfig
    secret_key: str
    debug: bool

def load_config(path: str = None) -> Config:
    env = Env()

    # Проверяем наличие .env файла
    env_path = path or ".env"
    if not Path(env_path).is_file():
        raise FileNotFoundError(f"Файл {env_path} не найден. Создайте .env на основе документации.")

    env.read_env(env_path)

    return Config(
        db=DatabaseConfig(
            database_url=env("DATABASE_URL")
        ),
        secret_key=env("SECRET_KEY"),
        debug=env.bool("DEBUG", default=False)
    )

Теперь, если .env нет — приложение не стартует и пишет ошибку вроде:

FileNotFoundError: Файл .env не найден. Создайте .env на основе документации.

🧪 4. Проверка

Запусти приложение:

uvicorn app.main:app --reload

И открой:

  • GET / — покажет debug: true
  • POST / — вернёт secret_key_used
  • GET /db — покажет db_url

✅ Результат:

  • Все конфиги читаются централизованно
  • .env файл — обязательный и контролируемый
  • FastAPI читает переменные как из настроек продакшна

🟩 Шаг 6: Настройка линтеров и автоформаттеров (Black, Flake8, isort)

На этом шаге ты:

  • Установишь black, flake8, isort
  • Создашь конфигурационные файлы
  • Научишься запускать форматирование кода вручную в PowerShell
  • Убедишься, что твой код соответствует стилю

📁 Структура проекта после шага:

fastapi_project/
├── app/
│   ├── main.py
│   ├── models.py
│   ├── config.py
│   └── logger.py
├── .env
├── requirements.txt
├── .black                  ✅
├── .flake8                 ✅
├── .isort.cfg              ✅

📦 1. Установка инструментов

pip install black flake8 isort

Добавь в requirements.txt (в конце):

black
flake8
isort

📄 2. Создание файла .black

ni .black

Содержимое:

[tool.black]
line-length = 120
target-version = ['py311']  # замените на свою версию Python
extend-exclude = '''
(
    venv
  | alembic
  | docker
  | __pycache__
  | .git
)
'''

📄 3. Создание .flake8

ni .flake8

Содержимое:

[flake8]
exclude = __init__.py,venv,alembic,docker,.git,__pycache__
max-line-length = 120
ignore = E203, E266, E501, W503

📄 4. Создание .isort.cfg

ni .isort.cfg

Содержимое:

[tool.isort]
profile = black

[settings]
# include_trailing_comma = true # тут выдает ошибку
line_length = 120
lines_after_imports = 2
skip = __init__.py,venv,alembic,docker,.git,__pycache__

🚀 5. Как запускать инструменты вручную

Важно: Запускай из корня проекта

➤ Запуск Black

black --config .black .

➤ Запуск Flake8

flake8 --config .flake8 .

➤ Запуск isort

isort --settings-file .isort.cfg .

✅ Что делают эти инструменты:

Инструмент Что делает
black Форматирует код автоматически
flake8 Проверяет стиль, длину строк, ошибки
isort Сортирует импорты, приводит к единому стилю

🧪 Проверка

Попробуй сделать намеренно плохо отформатированный импорт в main.py:

from fastapi import FastAPI
from app.models import User
from app.config import load_config
from app.logger import logger
import os,sys

Затем запусти:

isort --settings-file .isort.cfg .
black --config .black .
flake8 --config .flake8 .

Ошибки будут найдены и/или автоматически исправлены.


✅ Результат:

  • Твой проект теперь можно проверять и форматировать перед каждым коммитом
  • Все инструменты конфигурируются отдельно
  • Ты знаешь, как запускать их вручную в PowerShell

🟩 Шаг 7: Настройка pre-commit хуков для автоматического запуска линтеров перед каждым коммитом

На этом шаге ты:

  • Установишь и настроишь pre-commit
  • Создашь .pre-commit-config.yaml
  • Добавишь удобный скрипт pre-commit
  • Подключишь хуки к Git
  • Проверишь, что линтеры запускаются автоматически при коммите

📁 Итоговая структура проекта:

fastapi_project/
├── app/
├── .env
├── requirements.txt
├── .black
├── .flake8
├── .isort.cfg
├── .pre-commit-config.yaml   ✅
├── pre-commit                ✅

📦 1. Установка pre-commit

pip install pre-commit

И добавь в requirements.txt:

pre-commit

📄 2. Создание .pre-commit-config.yaml

ni .pre-commit-config.yaml

Содержимое:

repos:
  - repo: local
    hooks:
      - id: isort
        name: isort
        entry: isort --settings-file ./.isort.cfg .
        args: ["--profile", "black"]
        language: system
        types: [python]
        pass_filenames: false

      - id: black
        name: black
        entry: black --config ./.black .
        language: system
        types: [python]
        pass_filenames: false

      - id: flake8
        name: flake8
        entry: flake8 --config .flake8 .
        language: system
        types: [python]
        pass_filenames: false

📄 3. Создание bash-скрипта pre-commit (ручной запуск)

⚠️ На Windows PowerShell этот файл ты можешь создать как обычный .ps1 или .bat, но проще просто запускать команды вручную (см. ниже)

Создай обычный pre-commit скрипт:

ni pre-commit

Содержимое:

isort --settings-file ./.isort.cfg .
black --config ./.black .
flake8 --config .flake8 .

Для запуска вручную на Windows:

bash pre-commit  # если установлен Git Bash

Либо просто напрямую:

isort --settings-file ./.isort.cfg .
black --config ./.black .
flake8 --config .flake8 .

🔗 4. Подключение pre-commit хуков к git

Перейди в терминал (в корне проекта) и выполни:

pre-commit install

После этого перед каждым коммитом автоматически будут запускаться isort, black, flake8.


🧪 5. Проверка

  1. Измени любой .py файл и сделай некрасивый код (например, добавь лишние пробелы или неотсортированные импорты)
  2. Сделай git-коммит:
git add .
git commit -m "Test pre-commit"

В консоли ты увидишь как запускаются проверки:

[INFO] Installing environment for local.
[INFO] Once installed this environment will be reused.
isort...........................................(passed/rewritten)
black...........................................(passed/rewritten)
flake8..........................................(passed)

✅ Результат:

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

About

Template for fast api projects with libraries: fastapi, uvicorn, environs, black, flake8, isort, pre-commit.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages