Skip to content

Repository files navigation

Short URL

Python FastAPI PostgreSQL Redis Docker SQLAlchemy Alembic QR Code logging Taskiq RabbitMQ SHA-256 Argon2 Rate Limiting TTL MIT CI/CD Deploy uv Pytest Pandas XlsxWriter Export Audit Enums JWT simple-redis-cache Async Argon2 Credits Credits System ClickBuffer

Сервис для сокращения ссылок с JWT-аутентификацией, ролями, кэшированием в Redis и асинхронными задачами через Taskiq + RabbitMQ.


CHANGELOG - список обновлений

🌐 Демо

⚠️ Сайт работает в ограниченном режиме: Taskiq воркер отключён из-за ограничений бесплатного тарифа Render. Клики не учитываются, просроченные ссылки не удаляются, а всё остальное работает.

Быстрый старт

Клонирование:

git clone https://github.com/hotpotato89/short-url.git
cd short-url

Виртуальное окружение:

uv sync --frozen
source .venv/bin/activate

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

cp .env.example .env

Генерация RSA ключей:

mkdir -p keys
openssl genrsa -out keys/private.pem 2048
openssl rsa -in keys/private.pem -pubout -out keys/public.pem

Запуск:

docker compose up -d --build

Проверка:

curl http://localhost:8000/health

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

pytest --cov src.app --cov-report=term

Результат: 126 зеленых тестов.

API эндпоинты

💰 Кредитная система

Каждый пользователь получает 5 кредитов при регистрации.

  • Создание ссылки — тратит 1 кредит
  • При 0 кредитах — создание ссылки недоступно (ошибка 403)
  • Автоматическое пополнение — +5 кредитов 1-го числа каждого месяца (через Taskiq Scheduler)

Эндпоинты:

Метод Эндпоинт Описание
GET /credits Получить баланс пользователя

📄 Пагинация

Используется курсорная пагинация для:

  • /admin/export-logs
  • /admin/users

**Параметры:**Увеличение счетчика кликов происходит в фоне через Taskiq (асинхронные задачи)

  • limit — количество записей на странице (1–100, по умолчанию 10)
  • cursor — ID последнего клика с предыдущей страницы (опционально)

Ответ:

  • items — список кликов
  • next_cursor — ID для следующей страницы (null, если данных больше нет)
  • has_more — есть ли ещё данные
  • limit — запрошенное количество

📱 QR-коды

Для каждой короткой ссылки можно сгенерировать QR-код.

Метод Эндпоинт Описание
GET /url/{slug}/qr Получить QR-код в формате PNG

Особенности:

  • Генерация на лету
  • Кэширование в Redis (24 часа)
  • Можно скачать с фронтенда
  • Не хранит бинарник в базе данных

Авторизация

Метод Эндпоинт Описание Требует токен
POST /auth/register Регистрация Нет
POST /auth/login Логин (access + refresh) Нет
POST /auth/refresh Обновить access и refresh Да (refresh)
POST /auth/logout Выход Да (refresh)
GET /auth/me Профиль Да

Ссылки

Метод Эндпоинт Описание Требует токен
POST /url Создать ссылку Да
GET /url/my Список своих ссылок Да
GET /{slug} Редирект Нет
PUT /url/{slug} Изменить адрес (владелец) Да
DELETE /url/{slug} Удалить (владелец) Да
GET /url/{slug}/info Получить данные конкретной ссылки (владелец или админ) Да

Документация

Метод Эндпоинт Описание
GET /docs Swagger UI
GET /openapi.json OpenAPI схема

Администрация

Метод Эндпоинт Описание
PATCH /admin/users/{user_id}/role Изменить роль другого пользователя
GET /admin/users Посмотреть список пользователей
GET /admin/export Экспоритировать сипсок ссылок
GET /admin/export-logs Логи экспортов (аудит)

Переменные окружение:

  • в файле .env.example

Особенности:

  • JWT access (15 минут) + refresh (7 дней) токены
  • RSA подпись токенов (асимметричное шифрование)
  • Обработка ошибок при расшифровке JWT токена
  • Async Argon2 хэширование паролей (своя библиотека репозиторий)
  • SHA-256 хэширование refresh токенов в базе данных
  • Чистая архитектура (Service → Repository)
  • Nginx reverse proxy + раздача статики Убрано по причине ненадобности.
  • Rate limiting (SlowAPI)
  • Кэширование редиректов в Redis (своя библиотека репозиторий)
  • CI/CD через Github Actions
  • QR-коды через библиотеку qrcode
  • TTL система для ссылок
  • Увеличение счетчика кликов происходит через ClickBuffer — пачки кликов накапливаются в Redis и раз в 5 минут сбрасываются в БД одним запросом
  • Автоматическое удаление истекших ссылок через Taskiq Scheduler
  • Структурированные логи через structlog с возможностью настроить JSON формат
  • Типобезопасность через Python Enums
  • Миксины, например IdPkMixin для моделей SQLAlchemy
  • Прегенерация слэгов в Redis пул для снижения CPU нагрузки
  • ClickBuffer — пачка кликов накапливается в Redis и раз в 5 минут сбрасывается в БД одним запросом (экономит ресурсы БД)

📊 Аудит экспорта

Каждый экспорт данных (CSV/JSON/XLSX) логируется:

  • Кто экспортировал (администратор)
  • Когда был выполнен экспорт
  • В каком формате

Просмотр логов доступен только супер-админу через эндпоинт /url/admin/export-logs.

🧠 Как это работает

  1. Пользователь регистрируется и получает JWT-токен.
  2. Вставляет длинную ссылку → получает короткий slug.
  3. При переходе по /{slug} происходит редирект.
  4. Каждый переход инкрементит счётчик в Redis, а раз в 5 минут все клики пачкой записываются в БД.
  5. Для любой ссылки можно сгенерировать QR-код.
  6. Автор может менять slug и удалять его.

Имеется счетчик кликов

📦 Собственные библиотеки в проекте

Этот проект использует две мои собственные библиотеки, опубликованные на PyPI:

  • simple-redis-cache — инструмент для кэширования синхронных и асинхронных функций в Redis.
  • async-argon2 — асинхронная обёртка для хэширования паролей Argon2, не блокирующая event loop.

Обе библиотеки имеют 100% покрытие тестами, полную документацию и доступны для установки через pip.

Автор:

📄 Лицензия

Этот проект распространяется под лицензией MIT. Подробнее см. в файле LICENSE.

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages