Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
3143066
first commit dev
dmsnback Jan 21, 2026
895d793
add requirements
dmsnback Jan 21, 2026
19fd473
fix errors celery
dmsnback Jan 21, 2026
70fd3d4
schemas
dmsnback Jan 21, 2026
215527b
Merge pull request #1 from dmsnback/feature/shemas
dmsnback Jan 21, 2026
5232ea3
routers
dmsnback Jan 21, 2026
970783d
Merge pull request #2 from dmsnback/feature/routers
dmsnback Jan 21, 2026
aa47bbc
Добавлена пагинация
dmsnback Jan 22, 2026
54d1ce6
Merge pull request #3 from dmsnback/feature/routers
dmsnback Jan 22, 2026
bc18b7b
pytest
dmsnback Jan 22, 2026
802c4d0
Merge pull request #4 from dmsnback/feature/pytest
dmsnback Jan 22, 2026
cb0668e
actions
dmsnback Jan 22, 2026
4a2a9ca
actions
dmsnback Jan 22, 2026
8d0a7bb
actions
dmsnback Jan 22, 2026
059733f
actions
dmsnback Jan 22, 2026
f3cd9b3
actions
dmsnback Jan 22, 2026
f6d3bd2
actions
dmsnback Jan 22, 2026
6b7c671
Merge pull request #5 from dmsnback/feature/githubactions
dmsnback Jan 22, 2026
4365b98
actions push to dockerhub
dmsnback Jan 22, 2026
dab5c0a
actions push to dockerhub
dmsnback Jan 22, 2026
5d99fa8
actions push to dockerhub
dmsnback Jan 22, 2026
386d5e0
actions push to dockerhub
dmsnback Jan 22, 2026
4d2442c
Merge pull request #6 from dmsnback/feature/githubactions
dmsnback Jan 22, 2026
4f87701
fix import
dmsnback Jan 22, 2026
ea5f9b3
readme.md
dmsnback Jan 23, 2026
1483402
Merge pull request #7 from dmsnback/feature/readme
dmsnback Jan 23, 2026
a8c77bc
_
dmsnback Jan 23, 2026
eb1e77c
_
dmsnback Jan 23, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .flake8
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[flake8]
max-line-length = 79
extend-ignore = E501, W503, E203, E402, E712
exclude =
.git,
backend/alembic/versions/*,
backend/db/base.py,
__pycache__,
.tox,
.eggs,
*.egg,
.venv,
venv,
alembic/
93 changes: 93 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
name: Derbit Client workflow

on:
push:
branches:
- "**"
pull_request:

jobs:
lint:
name: Lint & Tests
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.11"

- name: Upgrade pip
run: python -m pip install --upgrade pip

- name: Install dependencies
run: pip install -r requirements.txt

- name: Black check
run: black --check .

- name: Isort check
run: isort --check-only .

- name: Flake8 check
run: flake8 .

- name: Run pytest
run: pytest -v

push_branch_dev_to_docker_hub:
name: Build and Push Docker(dev)
runs-on: ubuntu-latest
needs: lint

if: github.ref == 'refs/heads/dev'

steps:
- name: Check out the repo
uses: actions/checkout@v4

- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Login to Docker
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}

- name: Push to Docker Hub
uses: docker/build-push-action@v5
with:
push: true
tags: |
dmsn/derbit_client:dev

push_branch_main_to_docker_hub:
name: Build and Push Docker(prod)
runs-on: ubuntu-latest
needs: lint

if: github.ref == 'refs/heads/main'

steps:
- name: Check out the repo
uses: actions/checkout@v4

- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Login to Docker
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}

- name: Push to Docker Hub
uses: docker/build-push-action@v5
with:
push: true
tags: |
dmsn/derbit_client:prod
22 changes: 22 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Byte-compiled / optimized / DLL files
__pycache__
__pycache__/
*.py[codz]
*$py.class
Expand Down Expand Up @@ -205,3 +206,24 @@ cython_debug/
marimo/_static/
marimo/_lsp/
__marimo__/


logs/
*.log


*.sqlite
*.db
*.sqlite3

*.sql
*.dump
pgdata/
/postgres-data/


# IDE
.vscode/
.idea/

.pytest_cache/
9 changes: 9 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
FROM python:3.11-slim
LABEL maintainer="Dmitry Titenkov <lt200711@yandex.ru>"
LABEL version="1.0"
RUN mkdir /app
COPY requirements.txt /app
RUN pip3 install -r /app/requirements.txt --no-cache-dir -vvv
COPY . /app
WORKDIR /app
CMD [ "uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--reload" ]
17 changes: 17 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
all: build run-services migrate up

build:
@echo "Сборка образов..."
docker-compose build

run-services:
@echo "Запуск сервисов..."
docker-compose up -d db redis backend

migrate:
@echo "Применение миграций..."
docker-compose exec backend alembic upgrade head

up:
@echo "Запуск всех сервисов..."
docker-compose up -d
139 changes: 137 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,138 @@
# Derbit Client
<a name="Начало"></a>

Клиент каждую минуту забирает с биржи текущую цену btc_usd и eth_usd (index price валюты) после чего сохраняет в базу данных тикер валюты, текущую цену и время в UNIX timestamp
## Derbit Client

Клиент для криптобиржи Deribit

[![Derbit Client Lint annd Tests](https://img.shields.io/github/actions/workflow/status/dmsnback/derbit_client/main.yml?branch=main&style=flat-square&label=Derbit_Client%20Lint)](https://github.com/dmsnback/derbit_client/actions/workflows/main.yml)
[![Derbit Client Docker Dev](https://img.shields.io/github/actions/workflow/status/dmsnback/derbit_client/main.yml?branch=dev&style=flat-square&label=Derbit_Client%20Docker%20Dev)](https://github.com/dmsnback/derbit_client/actions/workflows/main.yml)
[![Derbit Client Docker Prod](https://img.shields.io/github/actions/workflow/status/dmsnback/derbit_client/main.yml?branch=main&style=flat-square&label=Derbit_Client%20Docker%20Prod)](https://github.com/dmsnback/derbit_client/actions/workflows/main.yml)


- [Описание](#Описание)
- [Технологии](#Технологии)
- [Тестирование](#Тестирование)
- [Таблица эндпоинтов](#Таблица)
- [Шаблон заполнения .env-файла](#Шаблон)
- [Запуск проекта на локальной машине](#Запуск)
- [Автор](#Автор)

<a name="Описание"></a>

### Описание

Асинхронный клиент для криптобиржи Deribit.
Сервис периодически получает ```index price``` BTC_USD и ETH_USD,
сохраняет данные в базу тикер валюты, текущую цену и время в ```UNIX timestamp```.

Приложение написано с использованием **асинхронного FastAPI**, **SQLAlchemy**, **PostgreSQL**, **Celery** и **Redis**.

В проекте настроен **CI/CD pipeline** с использованием **GitHub Actions**:

```md
- Автоматическая проверка кода (black, isort, flake8)
- Запуск unit-тестов (`pytest`)
- Сборка Docker-образа
- Публикация образа в **Docker Hub** при пуше в соответствующие ветки
```

```md
Проект адаптирован для использования **PostgreSQL** и развёртывания в контейнерах **Docker**.
```

> [Вернуться в начало](#Начало)

<a name="Технологии"></a>

### Технологии

[![Python](https://img.shields.io/badge/Python-1000?style=for-the-badge&logo=python&logoColor=ffffff&labelColor=000000&color=000000)](https://www.python.org)
[![FastAPI](https://img.shields.io/badge/FastAPI-1000?style=for-the-badge&logo=fastapi&logoColor=ffffff&labelColor=000000&color=000000)](https://fastapi.tiangolo.com)
[![Celery](https://img.shields.io/badge/Celery-1000?style=for-the-badge&logo=celery&logoColor=ffffff&labelColor=000000&color=000000)](https://docs.celeryq.dev/en/stable/index.html)
[![Redis](https://img.shields.io/badge/Redis-1000?style=for-the-badge&logo=redis&logoColor=ffffff&labelColor=000000&color=000000)](https://redis-docs.ru)
[![aiohttp](https://img.shields.io/badge/aiohttp-1000?style=for-the-badge&logo=aiohttp&logoColor=ffffff&labelColor=000000&color=000000)](https://github.com/aio-libs/aiohttp?ysclid=mkqid6e88x702921033)
[![SQLAlchemy](https://img.shields.io/badge/SQLAlchemy-1000?style=for-the-badge&logo=sqlalchemy&logoColor=ffffff&labelColor=000000&color=000000)](https://www.sqlalchemy.org)
[![Pydantic](https://img.shields.io/badge/Pydantic_V2-1000?style=for-the-badge&logo=Pydantic&logoColor=ffffff&labelColor=000000&color=000000)](https://docs.pydantic.dev/latest/)
[![Docker](https://img.shields.io/badge/Docker-1000?style=for-the-badge&logo=docker&logoColor=ffffff&labelColor=000000&color=000000)](https://www.docker.com)
[![Postgres](https://img.shields.io/badge/Postgres-1000?style=for-the-badge&logo=postgresql&logoColor=ffffff&labelColor=000000&color=000000)](https://www.postgresql.org)
[![Pytest](https://img.shields.io/badge/Pytest-1000?style=for-the-badge&logo=pytest&logoColor=ffffff&labelColor=000000&color=000000)](https://docs.pytest.org/en/stable/index.htmlc)
[![GitHub Actions](https://img.shields.io/badge/github%20actions-%232671E5.svg?style=for-the-badge&logo=githubactions&logoColor=ffffff&labelColor=000000&color=000000)](https://github.com/features/actions)

> [Вернуться в начало](#Начало)

<a name="Тестирование"></a>

### Тестирование

В проекте реализованы **unit-тесты** с использованием `pytest` и `pytest-asyncio`.

- Тестируется CRUD-логика работы с ценами
- Асинхронные операции с базой данных
- Для тестов используется изолированная база данных (SQLite)

Запуск тестов локально:

```python
pytest -v
```

> [Вернуться в начало](#Начало)

<a name="Таблица"></a>

### Таблица эндпоинтов

**Prices**

|Метод|URL|Описание|
|:-:|:-:|:-:|
|GET|/all/{ticker}|Получение всех сохраненных данных по указанной валюте|
|GET|/latest/{ticker}|Получение последней цены валюты|
|GET|/filter_by_date/{ticker}|Получение цены валюты с фильтром по дате|

> [Вернуться в начало](#Начало)

<a name="Шаблон"></a>

### Шаблон заполнения .env-файла

> `env.example` с дефолтнными значениями расположен в корневой папке

```python
POSTGRES_DB = derbit_db # Имя базы дданнных
POSTGRES_USER = postgres # Имя юзера PostgreSQL
POSTGRES_PASSWORD = yourpassword # Пароль юзера PostgreSQL
DATABASE_URL = postgresql+asyncpg://postgres:yourpassword@db:5432/derbit_db # Указываем адрес БД
```

> [Вернуться в начало](#Начало)

<a name="Запуск"></a>

### Запуск проекта на локальной машине

- Склонируйте репозиторий

```python
git clone git@github.com:dmsnback/derbit_client.git
```

- Запускаем проект в **Docker**

```python
make all
```

- Документация к API станет доступна по адресу:

[http://localhost:8000/docs/](http://localhost:8000/docs/)

> [Вернуться в начало](#Начало)

<a name="Автор"></a>

### Автор

- [Титенков Дмитрий](https://github.com/dmsnback)

> [Вернуться в начало](#Начало)
Loading