TinyUrl API - REST API на основе фреймворка FastAPI, позволяющее создавать короткие ссылки.
В TinyUrl API реализована простая пользовательская система с аутентификацией при помощи JWT токенов и cookie, в рамках которой можно регистрировать пользователей, залогиниться и разлогиниться, а также получить информацию о текущем пользователе. Методы работы с ссылками включают создание короткой ссылки для переданного URL с возможностью указать кастомный алиас и время жизни ссылки, метод, выполняющий переадресацию на оригинальный URL при переходе по короткой ссылке, методы обновления и удаления собственных коротких ссылок, метод, возвращающий статистику количества переходов по ссылке (а еще дату ее создания и дату последнего перехода), метод поиска коротких ссылок, привязанных к определенному URL и метод получения залогиненным пользователем всех созданных им коротких ссылок.
Стек проекта:
- Python 3.12
- FastApi
- PostgresQL
- Redis
- Celery
- Flower
*полный список зависимостей можно посмотреть в файле requirements.txt
- Убедитесь, что на вашем компьютере / сервере установлены git, docker и docker-compose. Если не установлены, то установите согласно инструкциям с официальных сайтов.
- Склонируйте этот репозиторий при помощи команды:
git clone git@github.com:yegerless/tinyurl-api.git
- Зайдите в директорию проекта при помощи следующей команды:
cd tinyurl-api
- В корневой директории проекта лежит файл example.env с несколькими конфигурационными параметрами приложения. Пропишите в нем ваши настройки (обязательно сгенерируйте ваш собственный SECRET_KEY и пароли) и переименуйте этот файл в .env
- Запустите TinyUrl API с docker-compose при помощи следующей команды:
docker compose up
- Откройте любой браузер и перейдите по URL, который указан в файле .env в переменных HOST_URL_OR_DOMEN:HOST_PORT. Документация API доступна по url HOST_URL_OR_DOMEN:HOST_PORT/docs (например 127.0.0.1:8088/docs).
- Отслеживать фоновые задачи Celery можно при помощи Flower, который доступен после запуска приложения по url HOST_URL_OR_DOMEN:8800 (например 127.0.0.1:8800).
В качестве СУБД проекта используется PostgresQL. Название базы данных указывается в файле .env в переменной POSTGRES_DB, username пользователя PostgresQL указывается в файле .env в переменной POSTGRES_USER.
В базе данных проекта находятся две таблицы:
- User (данные пользователей)
- Link (данные ссылок)
- id - первичный ключ, идентификатор пользователя
- email - email пользователя, который также используется в качестве username при регистрации
- hashed_password - хэш пароля
- created_at - дата и время создания пользователя
- last_login_at - дата и время последнего логина
- is_active - идентификатор активного пользователя (TRUE - пользователь активен, FALSE - пользователь отключен)
- id - первичный ключ
- user_id - внешний ключ, связь с многие к одному с таблицей User
- alias - код короткой ссылки
- source_url - исходный URL, на который выполняется переадресация
- created_at - дата и время создания ссылки
- expires_at - дата и время удаления ссылки
- last_used_at - дата и время последнего перехода по ссылке
- transitions_quantity - количество переходов по ссылке
Полная документация API в формате swagger доступна по URL HOST_URL_OR_DOMEN/docs после запуска через docker-compose.
Принимает POST запрос на регистрацию пользователя. Валидирует переданные параметры и создает нового пользователя.
Обязательные параметры тела запроса:
- username (требуется передать email пользователя)
- password
Пример запроса:
curl -X 'POST' \ 'http://127.0.0.1:8088/auth/signup' \ -H 'accept: application/json' \ -H 'Content-Type: application/x-www-form-urlencoded' \ -d 'grant_type=password&username=example%40email.com&password=test-password&scope=&client_id=string&client_secret=string'
Пример ответа:
{ "message": "Пользователь example@email.com зарегистрирован" }
Принимает POST запрос для залогинивания пользователя. Валидирует переданные параметры и выдает JWT токен, который сохраняется в cookie
Обязательные параметры тела запроса:
- username (требуется передать email пользователя)
- password
Пример запроса:
curl -X 'POST' \ 'http://127.0.0.1:8088/auth/login' \ -H 'accept: application/json' \ -H 'Content-Type: application/x-www-form-urlencoded' \ -d 'grant_type=password&username=example%40email.com&password=test-password&scope=&client_id=string&client_secret=string'
Пример ответа:
{ "message": "Пользователь example@email.com успешно залогинился" }
Принимает POST запрос и разлогинивает пользователя, удаляя JWT токен из cookie.
Пример запроса:
curl -X 'POST' \ 'http://127.0.0.1:8088/auth/logout' \ -H 'accept: application/json' \ -d ''
Пример ответа:
{ "message": "Пользователь example@email.com успешно разлогинился" }
Принимает GET запрос и возвращает данные текущего пользователя (email и дату время последнего входа в систему).
Пример запроса:
curl -X 'GET' \ 'http://127.0.0.1:8088/auth/current-user' \ -H 'accept: application/json'
Пример ответа:
{ "username": "example@email.com", "last_login_at": "2025-03-31 14:51:28.090401" }
Принимает POST запрос, создает кастомную короткую ссылку если передан параметр alias. Если ничего не передано, то генерирует alias автоматически и создает короткую ссылку. Если создается с параметром expires_at в формате даты с точностью до минуты, то после указанного времени короткая ссылка автоматически удаляется.
Параметры тела запроса:
- source_url (URL для которого будет создана короткая ссылка) - обязательный параметр
- custom_alias (кастомный код короткой ссылки, если не передан, то сгенерируется автоматически)
- expires_at (дата и время удаления ссылки, если не передан, то ссылка не будет удалена автоматически)
Пример запроса:
curl -X 'POST' \ 'http://127.0.0.1:8088/links/shorten' \ -H 'accept: application/json' \ -H 'Content-Type: application/json' \ -d '{ "source_url": "https://pikabu.ru", "custom_alias": "pkb", "expires_at": "01.01.2025 04:20" }'
Пример ответа:
{ "message": "Короткая ссылка успешно создана.", "short_link": "127.0.0.1:8088/links/pkb" }
Принимает GET запрос, возвращает все короткие ссылки, привязанные к переданному оригинальному url. Авторизованный пользователь получит данные только о своих ссылках. Неавторизованный пользователь получит данные только о тех ссылках, которые были созданы неавторизованными пользователями.
Обязательный параметр запроса:
- original_url (исходный URL, для которого необходимо найти короткие ссылки)
Пример запроса:
curl -X 'GET' \ 'http://127.0.0.1:8088/links/search?original_url=https%3A%2F%2Fpikabu.ru' \ -H 'accept: application/json'
Пример ответа:
{ "message": "Найдено 1 котортких ссылок для https://pikabu.ru", "shotr_codes_list": [ "127.0.0.1:8088/links/pika" ] }
Принимает GET запрос, возвращает оригинальный URL, дату создания короткой ссылке, количество переходов по ней и дату последнего использования.
Обязательный параметр пути:
- short_code (alias короткой ссылки)
Пример запроса:
curl -X 'GET' \ 'http://127.0.0.1:8088/links/pika/stats' \ -H 'accept: application/json'
Пример ответа:
{ "message": "Найдены следующие статистики по короткой ссылке 127.0.0.1:8088/links/pika", "original_url": "https://pikabu.ru", "created_at": "2025-03-31T11:55:14.286316", "transitions_quantity": 7, "last_used_at": "2025-03-31T15:08:00.878123" }
Принимает GET запрос, возвращает словарь со всеми короткими ссылками, которые создал пользователь в формате {short_code: original_url}.
Пример запроса:
curl -X 'GET' \ 'http://127.0.0.1:8088/links/all_my_links' \ -H 'accept: application/json'
Пример ответа:
{ "message": "Найдены следующие короткие ссылки", "links_dict": { "127.0.0.1:8088/links/pika": "https://pikabu.ru", "127.0.0.1:8088/links/fastapi": "https://fastapi.tiangolo.com" } }
Принимает GET запрос и возвращает ResponseRedirect на оригинальный URL, который привязан к короткой ссылке.
Обязательный параметр пути:
- short_code (alias короткой ссылки)
Пример запроса:
curl -X 'GET' \ 'http://127.0.0.1:8088/links/pika' \ -H 'accept: application/json'
Принимает DELETE запрос и удаляет запись о короткой ссылке из БД.
Обязательный параметр пути:
- short_code (alias короткой ссылки)
Пример запроса:
curl -X 'DELETE' \ 'http://127.0.0.1:8088/links/fastapi' \ -H 'accept: application/json'
Пример ответа:
{ "message": "Ссылка 127.0.0.1:8088/links/fastapi удалена" }
Принимает PUT запрос, обновляет короткий адрес (принимает кастомный или генеруриет новый). Перед обновлением проверяет, что исходный адрес принадлежит пользователю, который отправил запрос.
Обязательный параметр пути:
- short_code (alias короткой ссылки)
Пример запроса:
curl -X 'PUT' \ 'http://127.0.0.1:8088/links/pika' \ -H 'accept: application/json' \ -H 'Content-Type: application/json' \ -d '{ "new_alias": "pkb", "expires_at": "10.04.2025 12:30" }'
Пример ответа:
{ "message": "Ссылка изменена", "old_short_link": "127.0.0.1:8088/links/pika", "new_short_link": "127.0.0.1:8088/links/pkb" }
Реализован скрипт для нагрузочного тестирования tests/locustfile.py.
Запуск нагрузочного тестирования:
- Запустите сервис (инструкция выше)
- В отдельном терминале зайдите в корневую директорию проекта
- Перейдите в директорию tests/ при помощи следующей команды:
cd tests
- Запустите locust при помощи команды:
locust
- Откройте в браузере следующий url
http://127.0.0.1:8089
- Запустите нагрузочное тестривание соответствующей кнопкой в графическом интерфейсе locust