from datetime import UTC, datetime 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 from shared.redis import client as cache from . import schema as s class VITACORE_API(AsyncClient): def __init__(self): self.logger = getLogger(__name__) super().__init__(base_url=settings.VITACORE_BASE_URL) async def get_token(self): token = await self.get_cache('vitacore_token') if token is None: token = await self.login() await self.set_cache( 'vitacore_token', dumps({'token': token}).decode(), 10800 ) 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( '/auth', auth=BasicAuth( settings.VITACORE_USERNAME, settings.VITACORE_PASSWORD ), ) match req.status_code: case st.HTTP_200_OK: return req.text case _: self.logger.error(req.text) raise e.UnknownException async def findBySnils(self, snils: str): data = await self.get_cache(f'vitacore_findBySnils2:{snils}') if data: return s.PatientModel.model_validate(data) token = await self.get_token() req = await self.get( '/findBySnils2', params={'snils': snils}, headers={'Authorization': f'Bearer {token}'}, ) match req.status_code: case st.HTTP_200_OK: model = s.PatientModel.model_validate(req.json()) await self.set_cache( f'vitacore_findBySnils2:{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', params={'patId': patId}, headers={'Authorization': f'Bearer {token}'}, ) match req.status_code: case st.HTTP_200_OK: 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}'} ) match req.status_code: case st.HTTP_200_OK: 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 async def getWorkers(self, departmentId: str): token = await self.get_token() req = await self.get( '/getWorkers', params={'departmentId': departmentId}, headers={'Authorization': f'Bearer {token}'}, ) match req.status_code: case st.HTTP_200_OK: return s.WorkersModel.model_validate(req.json()) case st.HTTP_206_PARTIAL_CONTENT: error = s.ErrorModel.model_validate(req.json()) if ( error.error == 'В базе отсутствует подразделение (МО или филиал) с ' 'указанным идентификатором, либо оно не активно' ): return s.WorkersModel(Workers=[]) self.logger.error(error.error) raise e.UnknownException case _: self.logger.error(req.json()) raise e.UnknownException async def getSpecsV021(self): token = await self.get_token() req = await self.get( '/getSpecsV021', headers={'Authorization': f'Bearer {token}'} ) match req.status_code: case st.HTTP_200_OK: return s.SpecsV021Model.model_validate(req.json()) case _: self.logger.error(req.json()) raise e.UnknownException async def getEntries(self, patId: str): token = await self.get_token() if patId == '9a4d4b06-5928-4101-b95e-e5ba03a1abfd': patId = 'b66a85f1-4aaa-4db8-942a-2de44341824e' req = await self.get( '/getEntries', params={'patId': patId}, headers={'Authorization': f'Bearer {token}'}, ) match req.status_code: case st.HTTP_200_OK: return s.EntriesModel.model_validate(req.json()) case st.HTTP_206_PARTIAL_CONTENT: error = s.ErrorModel.model_validate(req.json()) if error.error == 'Не найдены записи по указанному patId': return s.EntriesModel(Entries=[]) case _: self.logger.error(req.json()) raise e.UnknownException async def getVaccsReport(self, patId: str): token = await self.get_token() if patId == '9a4d4b06-5928-4101-b95e-e5ba03a1abfd': patId = 'b66a85f1-4aaa-4db8-942a-2de44341824e' req = await self.get( '/getVaccsReport', params={'patId': patId}, headers={'Authorization': f'Bearer {token}'}, ) match req.status_code: case st.HTTP_200_OK: return s.VaccsReportModel.model_validate(req.json()) case st.HTTP_206_PARTIAL_CONTENT: error = s.ErrorModel.model_validate(req.json()) if ( error.error == 'Не найдены записи по указанному patId' or error.error == 'Не найдены вакцинации по данному пациенту' ): return s.VaccsReportModel(content='') case _: self.logger.error(req.json()) raise e.UnknownException async def getMedExamDict(self): token = await self.get_token() req = await self.get( '/getMedExamDict', headers={'Authorization': f'Bearer {token}'} ) match req.status_code: case st.HTTP_200_OK: return s.MedExamDictModel.model_validate(req.json()) case _: self.logger.error(req.json()) raise e.UnknownException async def getRoutesList(self, patId: str): token = await self.get_token() if patId == '9a4d4b06-5928-4101-b95e-e5ba03a1abfd': patId = 'b66a85f1-4aaa-4db8-942a-2de44341824e' req = await self.get( '/getRoutesList', params={'patId': patId}, headers={'Authorization': f'Bearer {token}'}, ) match req.status_code: case st.HTTP_200_OK: return s.RoutesListModel.model_validate(req.json()) case st.HTTP_206_PARTIAL_CONTENT: error = s.ErrorModel.model_validate(req.json()) if error.error == 'Не найдены случаи по указанному patId': return s.RoutesListModel( EventID='none', EventDate=datetime.now(UTC), LpuName='fakeName', Routes=[], ) case _: self.logger.error(req.json()) raise e.UnknownException async def getHospExaminations(self, patId: str, examId: str | None = None): if patId == '9a4d4b06-5928-4101-b95e-e5ba03a1abfd': patId = 'b66a85f1-4aaa-4db8-942a-2de44341824e' token = await self.get_token() req = await self.get( '/getHospExaminations', params={'patId': patId, 'examId': examId}, headers={'Authorization': f'Bearer {token}'}, ) match req.status_code: case st.HTTP_200_OK: return s.HospExaminationsModel.model_validate(req.json()) case st.HTTP_206_PARTIAL_CONTENT: error = s.ErrorModel.model_validate(req.json()) if error.error == 'Пациент не госпитализирован!': return s.HospExaminationsModel( EventID='none', EventDate=datetime.now(UTC), LpuName='fakeName', Examinations=[], ) case _: self.logger.error(req.json()) raise e.UnknownException async def getCurrHosp(self, patId: str): token = await self.get_token() if patId == '9a4d4b06-5928-4101-b95e-e5ba03a1abfd': patId = 'b66a85f1-4aaa-4db8-942a-2de44341824e' req = await self.get( '/getCurrHosp', params={'patId': patId}, headers={'Authorization': f'Bearer {token}'}, ) match req.status_code: case st.HTTP_200_OK: return s.CurHospitalizationsModel.model_validate(req.json()) case st.HTTP_206_PARTIAL_CONTENT: error = s.ErrorModel.model_validate(req.json()) if error.error == 'Пациент не госпитализирован!': return s.CurHospitalizationsModel( Hospitalizations=[], ) case _: self.logger.error(req.json()) raise e.UnknownException async def getHosps(self, patId: str): token = await self.get_token() if patId == '9a4d4b06-5928-4101-b95e-e5ba03a1abfd': patId = 'b66a85f1-4aaa-4db8-942a-2de44341824e' req = await self.get( '/getHosps', params={'patId': patId}, headers={'Authorization': f'Bearer {token}'}, ) match req.status_code: case st.HTTP_200_OK: return s.HospitalizationsModel.model_validate(req.json()) case st.HTTP_206_PARTIAL_CONTENT: error = s.ErrorModel.model_validate(req.json()) if ( error.error == 'Не найдены госпитализации по указанному patId' ): return s.HospitalizationsModel( Hospitalizations=[], ) case _: self.logger.error(req.json()) raise e.UnknownException async def getHospRecommendations(self, patId: str): token = await self.get_token() if patId == '9a4d4b06-5928-4101-b95e-e5ba03a1abfd': patId = 'b66a85f1-4aaa-4db8-942a-2de44341824e' req = await self.get( '/getHospRecommendations', params={'patId': patId}, headers={'Authorization': f'Bearer {token}'}, ) match req.status_code: case st.HTTP_200_OK: return s.HospRecommendationsModel.model_validate(req.json()) case st.HTTP_206_PARTIAL_CONTENT: error = s.ErrorModel.model_validate(req.json()) if ( error.error == 'Не найдены госпитализации по указанному patId' ): return s.HospRecommendationsModel( EventID='none', EventDate=datetime.now(UTC), Recommendations=[], ) case _: self.logger.error(req.json()) raise e.UnknownException async def getHospRoutes(self, patId: str): token = await self.get_token() if patId == '9a4d4b06-5928-4101-b95e-e5ba03a1abfd': patId = 'b66a85f1-4aaa-4db8-942a-2de44341824e' req = await self.get( '/getHospRoutes', params={'patId': patId}, headers={'Authorization': f'Bearer {token}'}, ) match req.status_code: case st.HTTP_200_OK: return s.HospRoutesModel.model_validate(req.json()) case st.HTTP_206_PARTIAL_CONTENT: error = s.ErrorModel.model_validate(req.json()) if error.error == 'Пациент не госпитализирован!': return s.HospRoutesModel( EventID='none', EventDate=datetime.now(UTC), RoutesToDoctor=[], RoutesToDiagnostic=[], ) case _: self.logger.error(req.json()) raise e.UnknownException async def getDiagnosticResults(self, patId: str): token = await self.get_token() req = await self.get( '/getDiagnosticResults', params={'patId': patId}, headers={'Authorization': f'Bearer {token}'}, ) match req.status_code: case st.HTTP_200_OK: return s.DiagnosticResultsModel.model_validate(req.json()) case _: self.logger.error(req.json()) raise e.UnknownException async def getELNs(self, patId: str): token = await self.get_token() req = await self.get( '/getELNs', params={'patId': patId}, headers={'Authorization': f'Bearer {token}'}, ) match req.status_code: case st.HTTP_200_OK: return s.ELNsModel.model_validate(req.json()) case st.HTTP_206_PARTIAL_CONTENT: error = s.ErrorModel.model_validate(req.json()) if error.error == 'Пациент не госпитализирован!': return s.ELNsModel(PatientELNs=[]) case _: self.logger.error(req.json()) raise e.UnknownException async def getPatFLG(self, patId: str): token = await self.get_token() req = await self.get( '/getPatFLG', params={'patId': patId}, headers={'Authorization': f'Bearer {token}'}, ) match req.status_code: case st.HTTP_200_OK: return s.PatientFLGModel.model_validate(req.json()) case _: self.logger.error(req.json()) raise e.UnknownException async def getDiagResultFile(self, resultId: str): token = await self.get_token() req = await self.get( '/getDiagResultFile', params={'resultId': resultId}, headers={'Authorization': f'Bearer {token}'}, ) match req.status_code: case st.HTTP_200_OK: return s.DiagResultFileModel.model_validate(req.json()) case st.HTTP_206_PARTIAL_CONTENT: error = s.ErrorModel.model_validate(req.json()) if ( error.error == 'Не найдены проведенные исследования по ' 'данному идентификатору' ): return s.DiagResultFileModel(content='') case _: self.logger.error(req.json()) raise e.UnknownException