Skip to content

yegerless/tinyurl-api

Repository files navigation

TinyUrl API

TinyUrl API - REST API на основе фреймворка FastAPI, позволяющее создавать короткие ссылки.
В TinyUrl API реализована простая пользовательская система с аутентификацией при помощи JWT токенов и cookie, в рамках которой можно регистрировать пользователей, залогиниться и разлогиниться, а также получить информацию о текущем пользователе. Методы работы с ссылками включают создание короткой ссылки для переданного URL с возможностью указать кастомный алиас и время жизни ссылки, метод, выполняющий переадресацию на оригинальный URL при переходе по короткой ссылке, методы обновления и удаления собственных коротких ссылок, метод, возвращающий статистику количества переходов по ссылке (а еще дату ее создания и дату последнего перехода), метод поиска коротких ссылок, привязанных к определенному URL и метод получения залогиненным пользователем всех созданных им коротких ссылок.

Стек проекта:

  • Python 3.12
  • FastApi
  • PostgresQL
  • Redis
  • Celery
  • Flower

*полный список зависимостей можно посмотреть в файле requirements.txt


Запуск TinyUrl API

  1. Убедитесь, что на вашем компьютере / сервере установлены git, docker и docker-compose. Если не установлены, то установите согласно инструкциям с официальных сайтов.
  2. Склонируйте этот репозиторий при помощи команды:
git clone git@github.com:yegerless/tinyurl-api.git  
  1. Зайдите в директорию проекта при помощи следующей команды:
cd tinyurl-api  
  1. В корневой директории проекта лежит файл example.env с несколькими конфигурационными параметрами приложения. Пропишите в нем ваши настройки (обязательно сгенерируйте ваш собственный SECRET_KEY и пароли) и переименуйте этот файл в .env
  2. Запустите TinyUrl API с docker-compose при помощи следующей команды:
docker compose up  
  1. Откройте любой браузер и перейдите по URL, который указан в файле .env в переменных HOST_URL_OR_DOMEN:HOST_PORT. Документация API доступна по url HOST_URL_OR_DOMEN:HOST_PORT/docs (например 127.0.0.1:8088/docs).
  2. Отслеживать фоновые задачи Celery можно при помощи Flower, который доступен после запуска приложения по url HOST_URL_OR_DOMEN:8800 (например 127.0.0.1:8800).

Структура базы данных TinyUrl API

В качестве СУБД проекта используется PostgresQL. Название базы данных указывается в файле .env в переменной POSTGRES_DB, username пользователя PostgresQL указывается в файле .env в переменной POSTGRES_USER.
В базе данных проекта находятся две таблицы:

  1. User (данные пользователей)
  2. Link (данные ссылок)
Структура таблицы User
  • id - первичный ключ, идентификатор пользователя
  • email - email пользователя, который также используется в качестве username при регистрации
  • hashed_password - хэш пароля
  • created_at - дата и время создания пользователя
  • last_login_at - дата и время последнего логина
  • is_active - идентификатор активного пользователя (TRUE - пользователь активен, FALSE - пользователь отключен)
Структура таблицы Link
  • 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.

Роутер /auth

POST /auth/signup

Принимает 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 /auth/login

Принимает 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 /auth/logout

Принимает POST запрос и разлогинивает пользователя, удаляя JWT токен из cookie.
Пример запроса:

curl -X 'POST' \ 'http://127.0.0.1:8088/auth/logout' \ -H 'accept: application/json' \ -d ''  

Пример ответа:

{ "message": "Пользователь example@email.com успешно разлогинился" }  
GET /auth/current-user

Принимает 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" }  

Роутер /links

POST /links/shorten

Принимает 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 /links/search

Принимает 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 /links/{short_code}/stats

Принимает 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 /links/all_my_links

Принимает 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 /links/{short_code}

Принимает GET запрос и возвращает ResponseRedirect на оригинальный URL, который привязан к короткой ссылке.
Обязательный параметр пути:

  • short_code (alias короткой ссылки)
    Пример запроса:
curl -X 'GET' \ 'http://127.0.0.1:8088/links/pika' \ -H 'accept: application/json'  
DELETE /links/{short_code}

Принимает 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 /links/{short_code}

Принимает 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.
Запуск нагрузочного тестирования:

  1. Запустите сервис (инструкция выше)
  2. В отдельном терминале зайдите в корневую директорию проекта
  3. Перейдите в директорию tests/ при помощи следующей команды:
cd tests  
  1. Запустите locust при помощи команды:
locust  
  1. Откройте в браузере следующий url
http://127.0.0.1:8089  
  1. Запустите нагрузочное тестривание соответствующей кнопкой в графическом интерфейсе locust

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages