From 731b9d384ad573be913efa2dd0675e2ddb3836ce Mon Sep 17 00:00:00 2001 From: Siarhei Siniak Date: Wed, 9 Jul 2025 11:12:56 +0300 Subject: [PATCH] [+] partially add storing of tickers --- deps/test-task-2025-06-30-v1/Makefile | 1 + .../test_task_2025_06_30_v1/async_api/app.py | 31 +++++++++++++++++-- .../test_task_2025_06_30_v1/tickers/logic.py | 14 +++++++++ .../tickers_retrieval/emcont.py | 6 ++++ 4 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 deps/test-task-2025-06-30-v1/python/online/fxreader/pr34/test_task_2025_06_30_v1/tickers/logic.py diff --git a/deps/test-task-2025-06-30-v1/Makefile b/deps/test-task-2025-06-30-v1/Makefile index f3ec962..5ec8f2b 100644 --- a/deps/test-task-2025-06-30-v1/Makefile +++ b/deps/test-task-2025-06-30-v1/Makefile @@ -22,6 +22,7 @@ venv_compile: venv: uv \ venv \ + -p 3.13 \ $(UV_ARGS) \ --seed \ $(ENV_PATH) diff --git a/deps/test-task-2025-06-30-v1/python/online/fxreader/pr34/test_task_2025_06_30_v1/async_api/app.py b/deps/test-task-2025-06-30-v1/python/online/fxreader/pr34/test_task_2025_06_30_v1/async_api/app.py index c613031..a0542a2 100644 --- a/deps/test-task-2025-06-30-v1/python/online/fxreader/pr34/test_task_2025_06_30_v1/async_api/app.py +++ b/deps/test-task-2025-06-30-v1/python/online/fxreader/pr34/test_task_2025_06_30_v1/async_api/app.py @@ -1,12 +1,19 @@ import asyncio +import datetime +import logging # import os from ..tickers_retrieval.emcont import Emcont from ..tickers.models import Ticker from ..tickers.settings import Settings as ModelsSettings +from ..tickers.logic import ticker_store_multiple import sqlalchemy.ext.asyncio +from sqlalchemy.ext.asyncio import AsyncSession +from sqlalchemy.ext.asyncio import async_sessionmaker from typing import Any +logger = logging.getLogger(__name__) + async def run() -> None: engine = sqlalchemy.ext.asyncio.create_async_engine( ModelsSettings.singleton().db_url @@ -15,8 +22,27 @@ async def run() -> None: engine ) - async def store_cb(rates: Any, timestamp: Any, session: Any) -> None: - print(rates, timestamp.isoformat()) + async def store_cb( + rates: list[Emcont.rates_get_t.data_t.rate_t], + timestamp: datetime.datetime, + session: 'async_sessionmaker[AsyncSession]', + ) -> None: + await ticker_store_multiple( + session, + [ + Ticker( + id=-1, + timestamp=timestamp, + value=rate.value, + ) + for rate in rates + ] + ) + + logger.info(dict( + rates=rates, + timestamp=timestamp.isoformat() + )) await Emcont.worker( only_symbols={'EURUSD', 'USDJPY', 'GBPUSD', 'AUDUSD', 'USDCAD'}, @@ -25,4 +51,5 @@ async def run() -> None: ) if __name__ == '__main__': + logging.basicConfig(level=logging.INFO) asyncio.run(run()) diff --git a/deps/test-task-2025-06-30-v1/python/online/fxreader/pr34/test_task_2025_06_30_v1/tickers/logic.py b/deps/test-task-2025-06-30-v1/python/online/fxreader/pr34/test_task_2025_06_30_v1/tickers/logic.py new file mode 100644 index 0000000..c9295a9 --- /dev/null +++ b/deps/test-task-2025-06-30-v1/python/online/fxreader/pr34/test_task_2025_06_30_v1/tickers/logic.py @@ -0,0 +1,14 @@ +from sqlalchemy.ext.asyncio import AsyncSession +from sqlalchemy.ext.asyncio import async_sessionmaker + +from .models import Ticker + +async def ticker_store_multiple( + session: 'async_sessionmaker[AsyncSession]', + tickers: list[Ticker], +) -> None: + async with session() as active_session: + async with active_session.begin(): + active_session.add_all( + tickers, + ) diff --git a/deps/test-task-2025-06-30-v1/python/online/fxreader/pr34/test_task_2025_06_30_v1/tickers_retrieval/emcont.py b/deps/test-task-2025-06-30-v1/python/online/fxreader/pr34/test_task_2025_06_30_v1/tickers_retrieval/emcont.py index 0b2f0a8..e486aa6 100644 --- a/deps/test-task-2025-06-30-v1/python/online/fxreader/pr34/test_task_2025_06_30_v1/tickers_retrieval/emcont.py +++ b/deps/test-task-2025-06-30-v1/python/online/fxreader/pr34/test_task_2025_06_30_v1/tickers_retrieval/emcont.py @@ -38,12 +38,18 @@ class Emcont: alias='Ask', ) ] + + @pydantic.computed_field + def value(self) -> decimal.Decimal: + return (self.ask + self.bid) / 2 + product_type: Annotated[ str, pydantic.Field( alias='ProductType', ) ] + rates: Annotated[ list[rate_t], pydantic.Field(