Сервис для сокращения ссылок с JWT-аутентификацией, ролями, кэшированием в Redis и асинхронными задачами через Taskiq + RabbitMQ.
CHANGELOG - список обновлений
- Swagger UI: short-url-8bjl.onrender.com/docs
- Фронтенд: short-url-ui-9240.onrender.com
git clone https://github.com/hotpotato89/short-url.git
cd short-urluv sync --frozen
source .venv/bin/activatecp .env.example .envmkdir -p keys
openssl genrsa -out keys/private.pem 2048
openssl rsa -in keys/private.pem -pubout -out keys/public.pemdocker compose up -d --buildcurl http://localhost:8000/healthpytest --cov src.app --cov-report=termРезультат: 126 зеленых тестов.
Каждый пользователь получает 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-код.
| Метод | Эндпоинт | Описание |
|---|---|---|
| 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.
- Пользователь регистрируется и получает JWT-токен.
- Вставляет длинную ссылку → получает короткий
slug. - При переходе по
/{slug}происходит редирект. - Каждый переход инкрементит счётчик в Redis, а раз в 5 минут все клики пачкой записываются в БД.
- Для любой ссылки можно сгенерировать QR-код.
- Автор может менять
slugи удалять его.
Имеется счетчик кликов
Этот проект использует две мои собственные библиотеки, опубликованные на PyPI:
simple-redis-cache— инструмент для кэширования синхронных и асинхронных функций в Redis.async-argon2— асинхронная обёртка для хэширования паролей Argon2, не блокирующая event loop.
Обе библиотеки имеют 100% покрытие тестами, полную документацию и доступны для установки через pip.
Этот проект распространяется под лицензией MIT. Подробнее см. в файле LICENSE.