From 043de7e034fa44b2f7527d125002cda0593a3f8c Mon Sep 17 00:00:00 2001 From: Miwory Date: Wed, 12 Nov 2025 12:19:30 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9F=D0=B0=D1=82=D1=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apps/esia/v1/router.py | 2 +- src/apps/tdn/auth.py | 4 +-- src/apps/users/auth.py | 7 +++-- src/apps/users/v1/router.py | 12 +++++-- src/clients/tdn/schema.py | 4 +-- src/clients/tmk/api.py | 4 +-- src/clients/vitacore/api.py | 62 ++++++++++++++++++++++++++++++++----- src/shared/redis.py | 2 +- 8 files changed, 76 insertions(+), 21 deletions(-) diff --git a/src/apps/esia/v1/router.py b/src/apps/esia/v1/router.py index 9187455..934f3cb 100644 --- a/src/apps/esia/v1/router.py +++ b/src/apps/esia/v1/router.py @@ -73,6 +73,6 @@ async def callback(session: AsyncSessionDep, code: str): user = existing_user access_token = secrets.token_urlsafe(32) - cache.set(access_token, f'user:{user.id}') + await cache.set(access_token, f'user:{user.id}') return s.Token(access_token=access_token) diff --git a/src/apps/tdn/auth.py b/src/apps/tdn/auth.py index f0d80f0..6ed023c 100644 --- a/src/apps/tdn/auth.py +++ b/src/apps/tdn/auth.py @@ -3,11 +3,11 @@ from shared.redis import client as cache async def token(): - access_token = cache.get('tdn_token') + access_token = await cache.get('tdn_token') if access_token is None: tokens = await c.tdn_api.signin() - cache.set('tdn_token', tokens.accessToken, 60) + await cache.set('tdn_token', tokens.accessToken, 60) return tokens.accessToken diff --git a/src/apps/users/auth.py b/src/apps/users/auth.py index fa8d4bc..f97e1d7 100644 --- a/src/apps/users/auth.py +++ b/src/apps/users/auth.py @@ -16,12 +16,15 @@ async def login( session: AsyncSessionDep, credentials: Annotated[HTTPAuthorizationCredentials, Depends(BEARER)], ): - user = cache.get(credentials.credentials) + user = await cache.get(credentials.credentials) if user is None: raise e.UnauthorizedException - _, user_id = user.decode().split(':') + try: + _, user_id = user.decode().split(':') + except ValueError: + raise e.UnauthorizedException from None user_model_stmt = select(User).where(User.id == int(user_id)) user_model = (await session.execute(user_model_stmt)).scalar_one_or_none() diff --git a/src/apps/users/v1/router.py b/src/apps/users/v1/router.py index d4c2f2c..aa23c72 100644 --- a/src/apps/users/v1/router.py +++ b/src/apps/users/v1/router.py @@ -31,7 +31,12 @@ async def get_profile(user: Annotated[User, Depends(login)]): return await c.vitacore_api.getProfile(user.vita_id) -@router.get('/getDepartments', response_model=list[vs.OrganizationsModel]) +@router.get( + '/getDepartments', + responses={ + status.HTTP_200_OK: {'model': vs.OrganizationsModel}, + }, +) async def get_departments(): """ Get list of departments. @@ -346,7 +351,7 @@ async def measurement( 'status': status, } cache_key = f'tdn:measurement:{user.id}:{created}' - cache.set(cache_key, dumps(data)) + await cache.set(cache_key, dumps(data)) @router.get('/measurements') @@ -354,6 +359,7 @@ async def measurements( user: Annotated[User, Depends(login)], ): data = [ - cache.get(key) for key in cache.keys(f'tdn:measurement:{user.id}:*') + cache.get(key) + for key in await cache.keys(f'tdn:measurement:{user.id}:*') ] return data diff --git a/src/clients/tdn/schema.py b/src/clients/tdn/schema.py index 1c14360..8f4c8ae 100644 --- a/src/clients/tdn/schema.py +++ b/src/clients/tdn/schema.py @@ -102,8 +102,8 @@ class SeriesValueModel(BaseModel): realm: SeriesRealmModel createdAt: datetime updatedAt: datetime - nvalue: str | None - fvalue: str | None + nvalue: int | None + fvalue: float | None svalue: str | None filepath: str | None mobileId: str | None diff --git a/src/clients/tmk/api.py b/src/clients/tmk/api.py index 247168c..05d1557 100644 --- a/src/clients/tmk/api.py +++ b/src/clients/tmk/api.py @@ -19,11 +19,11 @@ class TMK_API(AsyncClient): super().__init__(base_url=settings.TMK_BASE_URL, verify=False) async def get_token(self): - token = cache.get('tmk_token') + token = await cache.get('tmk_token') if token is None: token = await self.login() - cache.set('tmk_token', token, 10800) + await cache.set('tmk_token', token, 10800) else: token = token.decode() diff --git a/src/clients/vitacore/api.py b/src/clients/vitacore/api.py index 35741df..fd3d879 100644 --- a/src/clients/vitacore/api.py +++ b/src/clients/vitacore/api.py @@ -3,6 +3,7 @@ from logging import getLogger from fastapi import status as st from httpx import AsyncClient, BasicAuth +from orjson import dumps, loads from core.config import settings from shared import exceptions as e @@ -17,16 +18,28 @@ class VITACORE_API(AsyncClient): super().__init__(base_url=settings.VITACORE_BASE_URL) async def get_token(self): - token = cache.get('vitacore_token') + token = await self.get_cache('vitacore_token') if token is None: token = await self.login() - cache.set('vitacore_token', token, 10800) + await self.set_cache( + 'vitacore_token', dumps({'token': token}).decode(), 10800 + ) - else: - token = token.decode() + return token - return token + return token['token'] + + async def get_cache(self, key: str): + data = await cache.get(key) + + if data: + return loads(data.decode()) + + return None + + async def set_cache(self, key: str, value: str, ttl: int = 600): + await cache.set(key, value, ttl) async def login(self): req = await self.post( @@ -45,6 +58,11 @@ class VITACORE_API(AsyncClient): raise e.UnknownException async def findBySnils(self, snils: str): + data = await self.get_cache(f'vitacore_findBySnils:{snils}') + + if data: + return s.PatientsModel.model_validate(data) + token = await self.get_token() req = await self.get( '/findBySnils', @@ -54,12 +72,23 @@ class VITACORE_API(AsyncClient): match req.status_code: case st.HTTP_200_OK: - return s.PatientsModel.model_validate(req.json()) + model = s.PatientsModel.model_validate(req.json()) + await self.set_cache( + f'vitacore_findBySnils:{snils}', + model.model_dump_json(), + 14400, + ) + return model case _: self.logger.error(req.json()) raise e.UnknownException async def getProfile(self, patId: str): + data = await self.get_cache(f'vitacore_getProfile:{patId}') + + if data: + return s.ProfileModel.model_validate(data) + token = await self.get_token() req = await self.get( '/getProfile', @@ -69,12 +98,23 @@ class VITACORE_API(AsyncClient): match req.status_code: case st.HTTP_200_OK: - return s.ProfileModel.model_validate(req.json()) + model = s.ProfileModel.model_validate(req.json()) + await self.set_cache( + f'vitacore_getProfile:{patId}', + model.model_dump_json(), + 14400, + ) + return model case _: self.logger.error(req.json()) raise e.UnknownException async def getDepartments(self): + data = await self.get_cache('vitacore_getDepartments') + + if data: + return s.OrganizationsModel.model_validate(data) + token = await self.get_token() req = await self.get( '/getDepartments', headers={'Authorization': f'Bearer {token}'} @@ -82,7 +122,13 @@ class VITACORE_API(AsyncClient): match req.status_code: case st.HTTP_200_OK: - return s.OrganizationsModel.model_validate(req.json()) + model = s.OrganizationsModel.model_validate(req.json()) + await self.set_cache( + 'vitacore_getDepartments', + model.model_dump_json(), + 14400, + ) + return model case _: self.logger.error(req.text) raise e.UnknownException diff --git a/src/shared/redis.py b/src/shared/redis.py index bdbc532..ab85560 100644 --- a/src/shared/redis.py +++ b/src/shared/redis.py @@ -1,4 +1,4 @@ -from redis import Redis +from redis.asyncio import Redis from core.config import settings