Leaderly - это бесплатная open-source библиотека на Python для создания системы рейтинга (лидерборда) в реальном времени с использованием Redis и PostgreSQL.
- Leaderly 🚀
- ⚡ Высокая производительность - Redis для кэширования и быстрых операций
- 🗄️ Постоянное хранение - PostgreSQL для надежного сохранения данных
- 🔄 Синхронизация в реальном времени - WebSocket для мгновенных обновлений
- 🎯 Гибкая настройка - Поддержка пользовательских тегов и формул подсчета очков
- 🌐 Веб-интерфейс - Готовый dashboard на Vue.js
- 🐳 Docker поддержка - Легкий запуск нужного окружения (Redis, PostgreSQL) с Docker Compose
Скопируйте папку src в ту директорию, где вы планируете использовать модуль
# Запуск Redis, PostgreSQL, WebSocketAPI и Web-ui
docker compose up -d
# Проверка статуса
docker compose psвеб-интерфейс будет доступен по адресу http://localhost:5173/
Класс LeaderboardClient находится в файле src/leaderboard.py и полностью наследует все методы DBManager из src/bases/db_manager.py. Ниже представлено полное описание всех доступных методов.
__init__(redis_host, redis_port, pg_host, pg_port, pg_user, pg_password, pg_dbname)
Инициализирует подключение к Redis и PostgreSQL.
Параметры:
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
redis_host |
str | 'localhost' | Хост Redis сервера |
redis_port |
int | 6379 | Порт Redis сервера |
pg_host |
str | 'localhost' | Хост PostgreSQL сервера |
pg_port |
int | 5432 | Порт PostgreSQL сервера |
pg_user |
str | 'postgres' | Имя пользователя PostgreSQL |
pg_password |
str | '2991' | Пароль PostgreSQL |
pg_dbname |
str | 'leaderly' | Название базы данных |
Обновляет счет игрока в лидерборде. Если игрок с таким ключом не существует, он будет создан.
Параметры:
| Параметр | Тип | Описание |
|---|---|---|
key |
str | Уникальный идентификатор игрока |
score |
float | Новое значение счета |
Возвращает: None
Пример:
# Создание нового игрока
lb.update_score("player1", 1000)
# Обновление счета существующего игрока
lb.update_score("player1", 1500)
# Отрицательные счета
lb.update_score("player2", -500)Получает текущий счет игрока.
Параметры:
| Параметр | Тип | Описание |
|---|---|---|
key |
str | Уникальный идентификатор игрока |
Возвращает:
float- счет игрока, если найденNone- если игрок не найден
Пример:
score = lb.get_score("player1")
if score is not None:
print(f"Счет: {score}")
else:
print("Игрок не найден")Обновляет теги игрока. Теги могут использоваться для хранения дополнительной информации.
Параметры:
| Параметр | Тип | Описание |
|---|---|---|
key |
str | Уникальный идентификатор игрока |
tags |
List[float] | Список числовых тегов |
Возвращает: None
Пример:
# Добавление тегов
lb.update_tags("player1", [1.5, 2.5, 3.5])
# Обновление тегов
lb.update_tags("player1", [10, 20, 30, 40])
# Очистка всех тегов
lb.update_tags("player1", [])Получает список тегов игрока.
Параметры:
| Параметр | Тип | Описание |
|---|---|---|
key |
str | Уникальный идентификатор игрока |
Возвращает:
List[float]- список тегов (может быть пустым)None- если игрок не найден
Пример:
tags = lb.get_tags("player1")
if tags:
print(f"Теги: {tags}")
else:
print("Теги отсутствуют")Возвращает топ-N игроков из лидерборда, отсортированных по убыванию счета.
Параметры:
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
n |
int | 0 | Количество игроков (0 - вернуть всех) |
Возвращает: List[tuple(key, score, tags)]
Пример:
# Топ-10 игроков
top10 = lb.get_leaderboard(10)
for rank, (key, score, tags) in enumerate(top10, 1):
print(f"{rank}. {key}: {score} очков, теги: {tags}")
# Все игроки
all_players = lb.get_leaderboard(0)
print(f"Всего игроков: {len(all_players)}")Удаляет игрока из лидерборда вместе со всеми его тегами.
Параметры:
| Параметр | Тип | Описание |
|---|---|---|
key |
str | Уникальный идентификатор игрока |
Возвращает: None
Пример:
# Удаление игрока
lb.delete_object("player1")
# Проверка, что игрок удален
score = lb.get_score("player1") # Вернет None| Метод | Параметры | Возвращает | Описание |
|---|---|---|---|
__init__() |
redis_host, redis_port, pg_host, pg_port, pg_user, pg_password, pg_dbname | None |
Инициализация подключения к БД |
update_score() |
key, score | None |
Обновление счета игрока |
get_score() |
key | float или None |
Получение счета игрока |
update_tags() |
key, tags | None |
Обновление тегов игрока |
get_tags() |
key | List[float] или None |
Получение тегов игрока |
get_leaderboard() |
n | List[tuple] |
Получение топ-N игроков |
delete_object() |
key | None |
Удаление игрока |
В проекте используется WebSocket api, документация к реализации которой находится здесь
Leaderly включает в себя современный веб-интерфейс на Vue.js 3 для визуализации и управления лидербордом в реальном времени.
- Vue.js 3 - прогрессивный JavaScript фреймворк
- Vite - быстрый сборщик проектов
- Vue Router - маршрутизация для SPA
- Chart.js - графики и визуализация данных
- WebSocket - real-time обновления
О запуске веб-интерфейса - здесь
Leaderly/
│
├── src/ # Исходный код проекта
│ ├── api/ # WebSocket API сервер
│ │ └── ws-api.py # FastAPI WebSocket сервер (основной endpoint)
│ │
│ ├── bases/ # Классы для работы с БД
│ │ └── db_manager.py # DBManager - работа с Redis и PostgreSQL
│ │
│ ├── web/ # Веб-интерфейс на Vue.js
│ │ ├── components/ # Vue компоненты
│ │ │ └── Header.vue # Шапка с навигацией
│ │ ├── views/ # Страницы приложения
│ │ │ ├── Home.vue # Главная страница
│ │ │ └── Leaderboard.vue # Страница с таблицей лидеров
│ │ ├── assets/ # Статические файлы
│ │ │ └── logo/ # Логотипы
│ │ │ └── logo.png # Логотип Leaderly
│ │ ├── App.vue # Корневой компонент Vue
│ │ ├── main.js # Точка входа Vue приложения
│ │ ├── router.js # Маршрутизация Vue Router
│ │ ├── index.html # HTML шаблон
│ │ ├── package.json # NPM зависимости и скрипты
│ │ ├── package-lock.json # Фиксация версий зависимостей
│ │ └── vite.config.js # Конфигурация Vite сборщика
│ │
│ └── leaderboard.py # Клиентская обертка (экспортируемый интерфейс)
│
├── tests/ # Модульные тесты
│ └── test_db_manager.py # Тесты для DBManager
│
├── docker-compose.yml # Docker Compose конфигурация
├── requirements.txt # Python зависимости
├── example.py # Пример использования библиотеки
└── README.md # Документация проекта
from src.leaderboard import LeaderboardClient
# Создание клиента с параметрами по умолчанию
lb = LeaderboardClient()
# Добавление игроков
lb.update_score("alice", 1500)
lb.update_score("bob", 2300)
lb.update_score("charlie", 1800)
lb.update_score("diana", 3200)
# Получение счета конкретного игрока
score = lb.get_score("alice")
print(f"Счет Alice: {score}") # Счет Alice: 1500
# Получение топ-3 игроков
top3 = lb.get_leaderboard(3)
for rank, (key, score, tags) in enumerate(top3, 1):
print(f"{rank}. {key}: {score} очков")
# 1. diana: 3200 очков
# 2. bob: 2300 очков
# 3. charlie: 1800 очков
# Обновление счета
lb.update_score("alice", 3500) # Alice теперь лидер
# Удаление игрока
lb.delete_object("charlie")