Асинхронный микросервис для сбора, хранения и анализа цен криптовалют (BTC/ETH) с биржи Deribit.
Проект реализует полный цикл обработки данных: от фонового сбора через Celery до предоставления REST API на FastAPI.
- Язык: Python 3.12
- Web Framework: FastAPI
- Database: PostgreSQL + SQLAlchemy 2.0 + AsyncPG
- Background Tasks: Celery + Redis
- HTTP Client: AIOHTTP
- Containerization: Docker & Docker Compose
- Package Manager: UV
- Testing: Pytest, Mypy
- Фоновый сбор данных: Каждую минуту Celery-воркер забирает актуальные цены BTC/ETH с Deribit API.
- API интерфейс:
- Получение последней цены по тикеру.
- Получение истории цен с фильтрацией по времени.
- Мониторинг: Консольный дашборд для наблюдения за ценами в реальном времени.
Для запуска требуется только Docker и Make.
make upЭта команда соберет образы, запустит базу данных, Redis, API и Воркер.
После запуска API доступно по адресу: http://localhost:8001
-
Swagger UI: http://localhost:8001/docs
-
Проверка последней цены:
curl "http://localhost:8001/api/v1/prices/last?ticker=btc_usd"Можно запустить терминальный интерфейс для мониторинга цен:
make dashboardmake downВ проекте настроен контроль качества кода.
Запуск тестов
make testЗапускает Unit и Integration тесты с использованием pytest-cov. Текущее покрытие: >95%.
Статическая типизация
В проекте используется mypy для проверки типов, что позволяет минимизировать ошибки на этапе разработки.
Запуск проверки
make lintЗапускает проверку статической типизации всех модулей проекта. Текущий статус: ошибок не обнаружено
Так как Celery по своей природе синхронен, а весь стек работы с сетью и БД асинхронный, использован "мост" через asyncio.run() внутри задач Celery. Это позволяет переиспользовать единую логику сервисов и утилит.
Для работы Celery с asyncpg был выбран poolclass=NullPool. Причина: При использовании fork (или spawn процессов Celery) и asyncio.run, стандартный пул соединений SQLAlchemy (QueuePool) может приводить к ошибкам "InterfaceError: another operation is in progress", так как соединения привязываются к уничтоженным Event Loops. Отключение пула гарантирует чистое соединение для каждой задачи.
Для хранения цен используется тип DECIMAL, а не Float, чтобы избежать проблем с потерей точности, свойственных финансовым данным.
Для сборки Docker-образа используется современный менеджер uv. Виртуальное окружение вынесено в /uv-venv (вне рабочей директории /app), чтобы при монтировании томов локальные файлы не затирали установленные зависимости внутри контейнера.
.
├── app/
│ ├── api/ # Роуты
│ ├── core/ # Конфигурация, БД, Логгер
│ ├── services/ # Бизнес-логика
│ ├── main.py # Точка входа FastAPI
│ └── worker.py # Точка входа Celery
├── migrations/ # Миграции БД
├── tests/ # Тесты
├── docker-compose.yml
├── Dockerfile
├── Makefile
└── pyproject.toml # Зависимости и настройки линтеров