Skip to content

Nicksok2413/CorporateMicroblog

Repository files navigation

Сервис корпоративных микроблогов 🚀

Python FastAPI SQLAlchemy PostgreSQL Nginx

Бэкенд для корпоративного сервиса микроблогов, реализованный на Python с использованием FastAPI, SQLAlchemy и PostgreSQL.

📝 Обзор

Этот проект представляет собой бэкенд-часть корпоративного сервиса микроблогов. Пользователи могут публиковать короткие сообщения ("твиты"), подписываться на других пользователей, ставить лайки и просматривать ленту новостей от тех, на кого они подписаны.

Архитектура:

  • Nginx (nginx сервис) выступает в роли входной точки (реверс-прокси), слушает порт 8000 (HTTP, с редиректом на HTTPS) и порт 8443 (HTTPS) на хост-машине. Он отвечает за:
    • Обеспечение HTTPS (SSL/TLS) (автоматически генерируется самоподписанный сертификат для разработки при первом запуске).
    • Установку Security Headers для повышения безопасности.
    • Применение Rate Limiting для защиты API от брутфорс-атак.
    • Раздачу статических файлов пользовательского интерфейса (из src/static/).
    • Раздачу загруженных медиафайлов (из /media/).
    • Проксирование всех API-запросов (начинающихся с /api/), документации (/docs, /redoc) и эндпоинта метрик (/metrics) на бэкенд-сервис FastAPI.
  • FastAPI (web сервис) работает под управлением Uvicorn, обрабатывает исключительно API-запросы (/api/...), взаимодействуя с базой данных PostgreSQL через асинхронный SQLAlchemy и Alembic для миграций. Запускается от non-root пользователя (appuser) для повышения безопасности. Интегрирован с Sentry для отслеживания ошибок и производительности (при наличии SENTRY_DSN).
  • PostgreSQL (db сервис) хранит все данные приложения. API-ключи пользователей хранятся в хешированном виде (Argon2 + SHA256 для поиска).
  • Init-контейнер (media-initializer сервис) используется для однократного наполнения тома с медиафайлами начальными данными при первом запуске.
  • Prometheus (prometheus сервис) собирает метрики с FastAPI-приложения (с эндпоинта /metrics).
  • Grafana (grafana сервис) визуализирует метрики, собранные Prometheus. Автоматически настраивается с Prometheus как источником данных.
  • Аутентификация пользователей предполагается внешней, бэкенд работает с предоставленным api-key в заголовке запроса к API, который проверяется по хешу в базе данных.
  • Все сервисы оркестрируются с помощью Docker Compose.

✨ Основные Возможности API (/api/...)

  • Твиты:
    • Создание нового твита (с текстом и опциональными изображениями).
    • Удаление своего твита (связанные медиафайлы также удаляются).
  • Лайки:
    • Постановка отметки "Нравится" твиту.
    • Снятие отметки "Нравится".
  • Подписки:
    • Подписка на другого пользователя.
    • Отписка от другого пользователя.
  • Лента:
    • Получение персонализированной ленты твитов от пользователей, на которых подписан текущий пользователь, и своих собственных твитов.
    • Сортировка ленты по популярности (количеству лайков).
  • Профили:
    • Получение информации о своем профиле (подписчики, подписки).
    • Получение информации о профиле другого пользователя по ID.
  • Медиа:
    • Загрузка изображений (POST /api/medias) для последующего прикрепления к твитам.

🛡️ Безопасность

  • HTTPS: Весь трафик шифруется (используется автоматически сгенерированный самоподписанный сертификат).
  • Хеширование API-ключей: Ключи хранятся в БД в виде хешей (Argon2 + SHA256).
  • Rate Limiting: Nginx ограничивает частоту запросов к API для защиты от подбора ключей.
  • Security Headers: Nginx устанавливает заголовки X-Frame-Options, X-Content-Type-Options, Referrer-Policy, HSTS для защиты от распространенных веб-атак.
  • Non-root контейнер: Основное приложение FastAPI работает от пользователя с ограниченными правами.
  • Аудит зависимостей: В CI/CD пайплайн включена проверка зависимостей на известные уязвимости (pip-audit).
  • Мониторинг Ошибок: Интеграция с Sentry (опционально, через SENTRY_DSN) для отслеживания ошибок.
  • Мониторинг Метрик: Сбор метрик приложения с помощью Prometheus и визуализация в Grafana.

🛠️ Технологический стек

  • Язык: Python 3.12
  • Веб-сервер/Прокси: Nginx (+ OpenSSL для генерации сертификата)
  • Фреймворк: FastAPI
  • ASGI сервер: Uvicorn
  • База данных: PostgreSQL 17
  • ORM: SQLAlchemy 2.0 (async)
  • Драйвер БД: psycopg3 (binary)
  • Миграции: Alembic
  • Хеширование: Passlib (Argon2)
  • Валидация данных: Pydantic V2
  • Логирование: Loguru
  • Мониторинг: Sentry SDK, Prometheus, Grafana
  • Тестирование: Pytest, pytest-asyncio, pytest-cov, httpx
  • Линтинг/Форматирование: Ruff
  • Типизация: Mypy
  • Аудит зависимостей: pip-audit
  • CI/CD: GitHub Actions
  • Контейнеризация: Docker, Docker Compose
  • Прочее: aiofiles, pre-commit, python-multipart, python-dotenv, su-exec

📂 Структура Проекта

├── .github/
│   └── workflows/
│       └── ci-cd.yml           # GitHub Actions CI/CD
│
├── alembic/                    # Alembic миграции БД
│
├── docker/                     # Конфигурации и Dockerfiles для сервисов
│   ├── media_init/
│   │   ├── sample_media/       # Медиафайлы для демонстрации
│   │   └── Dockerfile          # Dockerfile для init-контейнера медиа
│   ├── monitoring/
│   │   ├── grafana/
│   │   │   ├── dashboards/     # JSON файлы дашбордов
│   │   │   └── provisioning/   # Файлы автонастройки Grafana (datasources, dashboards)
│   │   └── prometheus/
│   │       └── prometheus.yml  # Конфигурация Prometheus
│   ├── nginx/
│   │   ├── Dockerfile          # Dockerfile для Nginx
│   │   ├── entrypoint.sh       # Скрипт генерации сертификата и запуска Nginx
│   │   └── nginx.conf          # Конфигурация Nginx
│   └── web/
│       ├── Dockerfile          # Dockerfile для FastAPI приложения
│       └── entrypoint.sh       # Скрипт точки входа web сервиса (миграции, chown, запуск uvicorn)
│
├── src/                        # Исходный код FastAPI приложения
│   ├── api/                    # API слой (роуты, зависимости)
│   ├── core/                   # Ядро (конфигурация, БД, исключения, логирование, настройки sentry)
│   ├── models/                 # Модели SQLAlchemy
│   ├── repositories/           # Репозитории (слой доступа к данным)
│   ├── schemas/                # Схемы Pydantic (валидация)
│   ├── services/               # Сервисы (бизнес-логика)
│   ├── static/                 # Статика фронтенда (раздается Nginx)
│   └── main.py                 # Точка входа FastAPI приложения
│
├── tests/                      # Тесты (unit, integration)
│   ├── conftest.py             # Общие фикстуры для всех тестов (объекты моделей и др.)
│   ├── integration/            
│   │   ├── api/                # Интеграционные тесты API
│   │   ├── core/               # Интеграционные тесты ядра приложения (ошибки)
│   │   └── conftest.py         # Фикстуры для интеграционных тестов (БД, HTTP-клиент и др.)
│   └── unit/                  
│       ├── core/               # Unit-тесты ядра приложения (сессии, настройки конфигурации, sentry)
│       ├── dependencies/       # Unit-тесты зависимостей
│       ├── repositories/       # Unit-тесты репозиториев
│       ├── routes/             # Unit-тесты функций-обработчиков роутов
│       ├── services/           # Unit-тесты сервисов (бизнес-логика)
│       └── conftest.py         # Фикстуры для unit-тестов (моки)
│
├── .dockerignore               # Игнорируемые файлы Docker при сборке
├── .env.example                # Шаблон файла переменных окружения
├── .gitignore                  # Игнорируемые файлы Git
├── .pre-commit-config.yaml     # Конфигурация Pre-commit
├── alembic.ini                 # Конфигурация Alembic
├── docker-compose.yml          # Docker Compose конфигурация (основной оркестратор)
├── pytest.ini                  # Конфигурация Pytest
├── requirements.txt            # Зависимости для Production
├── requirements-dev.txt        # Зависимости для разработки и тестов
└── README.md                   # Этот файл

🚀 Установка и Запуск

Для запуска проекта вам понадобятся Docker и Docker Compose.

  1. Клонируйте репозиторий:

    git clone https://github.com/Nicksok2413/CorporateMicroblog
    cd CorporateMicroblog
  2. Создайте файл переменных окружения: Скопируйте файл .env.example в .env:

    cp .env.example .env

    Отредактируйте .env, указав необходимые значения. Режимы TESTING и DEBUG должны быть False для production. (Опционально): Чтобы включить отправку ошибок в Sentry, раскомментируйте и установите переменную SENTRY_DSN, указав DSN вашего проекта Sentry. Если SENTRY_DSN не задан, интеграция Sentry будет отключена.

  3. Запустите с помощью Docker Compose: Эта команда соберет образы (если необходимо) и запустит контейнеры. Nginx будет слушать порт 8000 (HTTP, редирект на HTTPS) и 8443 (HTTPS) на вашем хосте. Копирование начальных медиафайлов будет выполнено автоматически при старте сервиса media-initializer (отработает и завершится). При первом запуске Nginx автоматически сгенерирует самоподписанный SSL-сертификат. Миграции базы данных будет выполнена автоматически при старте сервиса web.

    docker compose up -d --build
    • Флаг -d запускает контейнеры в фоновом режиме.
    • Флаг --build принудительно пересобирает образы (рекомендуется при первом запуске или после изменений в Dockerfile или коде).
    • При первом запуске может потребоваться время.
  4. Проверка:

    • Веб-интерфейс будет доступен по адресу https://localhost:8443.
    • HTTP (http://localhost:8000) будет редиректить на HTTPS (https://localhost:8443).
    • Возможно браузер выдаст предупреждение безопасности из-за самоподписанного сертификата. Примите его ("Продолжить", "Доверять" и т.п.), чтобы продолжить.
    • Документация API (Swagger UI) доступна по адресу https://localhost:8443/docs.
    • Альтернативная документация (ReDoc) доступна по адресу https://localhost:8443/redoc.
  5. Остановка: Для остановки контейнеров выполните:

    docker compose down

    Чтобы остановить и удалить тома (volumes) с данными PostgreSQL, медиа, логами и др.:

    docker compose down -v

📊 Мониторинг

  • Метрики Prometheus: http://localhost:9090. Сбор с /metrics сервиса web.
  • Grafana UI: http://localhost:3000 (логин/пароль по умолчанию: admin/admin).
  • Ошибки Sentry: Если SENTRY_DSN указан в .env.

🔑 Использование API

Аутентификация

Все API-эндпоинты (/api/...) требуют передачи исходного (не хешированного) API-ключа пользователя в HTTP-заголовке api-key. Бэкенд сам выполнит необходимые проверки хешей.

При использовании UI (/):

  1. В правом верхнем углу форма для ввода API-ключа.
  2. В поле 'api-key текущего пользователя' по умолчанию стоит API-ключ тестового пользователя: test (пользователь Nick).
  3. Для входа под другим пользователем введите API-ключ одного из тестовых пользователей (см. ниже) и нажмите 'Установить новый api-key'.

При использовании curl:

curl -k -X GET "https://localhost:8443/api/users/me" \
     -H "accept: application/json" \
     -H "api-key: test_api_key_value"

# Флаг -k нужен для curl, чтобы игнорировать ошибку самоподписанного сертификата

Тестовые пользователи

При первом запуске с применением миграций создаются следующие тестовые пользователи:

Имя ID API Ключ (api-key) Примечание
Nick 1 test Имеет твиты, подписки, лайки
Alice 2 alice_key Имеет твиты, подписки, лайки
Bob 3 bob_key Имеет твиты, подписки, лайки
Charlie 4 charlie_key Имеет твиты, подписки, лайки
David (no tweets) 5 david_key Без твитов

Используйте соответствующие значения из колонки "API Ключ" для аутентификации от имени нужного пользователя.

Примечание: Сами ключи хранятся в базе данных в виде безопасных хешей.

✅ Тестирование

Тесты используют отдельную базу данных SQLite в памяти и не требуют запущенного Docker Compose. Для запуска тестов необходимо установить зависимости для разработки. Рекомендуется делать это в виртуальном окружении.

  1. Создайте и активируйте виртуальное окружение (если еще нет):

    python -m venv .venv
    source .venv/bin/activate  # Linux/macOS
    # .venv\Scripts\activate  # Windows
  2. Установите dev-зависимости:

    pip install -r requirements-dev.txt
  3. Отредактируйте .env, указав TESTING=True. Для более подробного логирования можно включить режим отладки: DEBUG=True.

  4. Запустите тесты:

    pytest

    Эта команда запустит все тесты (unit и integration).

  5. Запуск тестов с отчетом о покрытии:

    pytest --cov=src --cov-report term-missing -vv
  6. Аудит зависимостей:

    pip-audit

🧹 Линтинг и Форматирование

Для поддержания качества кода используется pre-commit для автоматического запуска проверок перед каждым коммитом. Для проверки и форматирования кода используется Ruff. Для проверки типов используется mypy. Запускайте в активном виртуальном окружении.

Настройка pre-commit (единоразово после клонирования):

  1. Убедитесь, что вы в активном виртуальном окружении.
  2. Установите dev-зависимости (если ещё не установлены):
    pip install -r requirements-dev.txt
  3. Установите Git хуки:
    pre-commit install

Теперь ruff будут автоматически проверяться перед каждым git commit.

Ручной запуск проверок pre-commit:

  • Запуск всех pre-commit хуков на измененных файлах:
    pre-commit run
  • Запуск всех pre-commit хуков на всех файлах:
    pre-commit run --all-files

Ruff

  1. Проверка:

    ruff check .
  2. Проверка + автоисправление:

    ruff check . --fix
  3. Проверка форматирования:

    ruff format . --check
  4. Автоисправление форматирования:

    ruff format .

Проверка типов с mypy:

mypy src

💾 Миграции Базы Данных

Для управления схемой базы данных используется Alembic.

  • Применение миграций: Автоматически при старте контейнера web с помощью entrypoint.sh.
  • Создание новой миграции (при изменении моделей SQLAlchemy):
    # Убедитесь, что сервис БД запущен (docker-compose up -d db)
    # Выполняйте в активном venv с установленными зависимостями
    alembic revision --autogenerate -m "Краткое описание изменений"
    После генерации внимательно просмотрите созданный файл миграции в alembic/versions/ перед его применением.
  • Применение миграций вручную (если нужно):
    # Применить все до последней
    alembic upgrade head
    # Откатить последнюю миграцию
    alembic downgrade -1
    # Посмотреть историю
    alembic history

Спасибо за использование сервиса!

About

Internal corporate social network for employee communication. Features posts, likes, and content feeds.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors