Патч
All checks were successful
Build And Push / publish (push) Successful in 1m11s

This commit is contained in:
2025-10-19 19:58:48 +03:00
parent 265d4b31aa
commit 6523a65dd5
7 changed files with 163 additions and 39 deletions

View File

@ -8,7 +8,8 @@ from fastapi import APIRouter, Body, Depends, status
from apps.users.auth import login
from apps.users.models import User
from clients import clients as c
from clients.vitacore import schema as s
from clients.tmk import schema as ts
from clients.vitacore import schema as vs
from shared.redis import client as cache
logger = getLogger(__name__)
@ -20,7 +21,7 @@ router = APIRouter(
)
@router.get('/getProfile', response_model=s.ProfileModel)
@router.get('/getProfile', response_model=vs.ProfileModel)
async def get_profile(user: Annotated[User, Depends(login)]):
"""
Get profile of user.
@ -28,7 +29,7 @@ async def get_profile(user: Annotated[User, Depends(login)]):
return await c.vitacore_api.getProfile(user.vita_id)
@router.get('/getDepartments', response_model=list[s.OrganizationsModel])
@router.get('/getDepartments', response_model=list[vs.OrganizationsModel])
async def get_departments():
"""
Get list of departments.
@ -36,7 +37,7 @@ async def get_departments():
return await c.vitacore_api.getDepartments()
@router.get('/getWorkers', response_model=s.WorkersModel)
@router.get('/getWorkers', response_model=vs.WorkersModel)
async def get_workers(
user: Annotated[User, Depends(login)], departmentId: str
):
@ -46,7 +47,7 @@ async def get_workers(
return await c.vitacore_api.getWorkers(departmentId)
@router.get('/getSpecs', response_model=s.SpecsV021Model)
@router.get('/getSpecs', response_model=vs.SpecsV021Model)
async def get_specs(user: Annotated[User, Depends(login)]):
"""
Get list of specialties.
@ -54,7 +55,7 @@ async def get_specs(user: Annotated[User, Depends(login)]):
return await c.vitacore_api.getSpecsV021()
@router.get('/getEntries', response_model=s.EntriesModel)
@router.get('/getEntries', response_model=vs.EntriesModel)
async def get_entries(user: Annotated[User, Depends(login)]):
"""
Get list of entries for user by id.
@ -155,6 +156,14 @@ async def get_pat_flg(user: Annotated[User, Depends(login)]):
return await c.vitacore_api.getPatFLG(user.vita_id)
@router.get('/queue', response_model=list[ts.QueueModel])
async def queue(_: Annotated[User, Depends(login)]):
"""
Get list of VKS queues.
"""
return await c.tmk_api.getQueue()
# @router.post('/measurement', status_code=status.HTTP_202_ACCEPTED)
# async def measurement(tdn_access_token: Annotated[str, Depends(token)]):
# patientId = '6debe050-b57e-442b-9b0e-8d304ca382b0'
@ -206,35 +215,6 @@ async def measurements(
return data
@router.get('/test')
@router.get('/aemd/test')
async def test_route():
return await c.aemd_api.searchRegistryItem('16247900267')
@router.get('/queue')
async def queue(user: Annotated[bool, Depends(login)]):
return [
{
'id': 60,
'guid': '92b3343d-1cb2-47b2-8497-a37e38b6ba24',
'tmk_date': None,
'created_at': '2025-04-02 15:21:19.890343',
'code_mo': '166502',
'mo_name': 'ГАУЗ "ГКБ№7 ИМ. М.Н.САДЫКОВА"',
'doctor_spec': '109',
'doctor_snils': None,
'patient_name': 'Иванов Петр Федорович',
'patient_birthday': '1997-03-01',
'patient_snils': '099-678-666 12',
'patient_policy': None,
'patient_phone': '+79123456789',
'patient_email': None,
'tmk_status': 1,
'tmk_status_name': 'Создана',
'tmk_cancel_reason': None,
'tmk_cancel_reason_name': None,
'vks_doctor_link': None,
'vks_patient_link': None,
'doctor_spec_name': 'врач-терапевт',
}
]

View File

@ -1,6 +1,7 @@
from .aemd.api import AEMD_API
from .esia.api import ESIA_API
from .tdn.api import TDN_API
from .tmk.api import TMK_API
from .vitacore.api import VITACORE_API
@ -8,6 +9,7 @@ class ClientsObject:
_esia_api = None
_vitacore_api = None
_tdn_api = None
_tmk_api = None
_aemd_api = None
@property
@ -31,6 +33,13 @@ class ClientsObject:
return self._tdn_api
@property
def tmk_api(self):
if not self._tmk_api:
self._tmk_api = TMK_API()
return self._tmk_api
@property
def aemd_api(self):
if not self._aemd_api:

View File

97
src/clients/tmk/api.py Normal file
View File

@ -0,0 +1,97 @@
from datetime import date
from logging import getLogger
from typing import Literal
from fastapi import status as st
from httpx import AsyncClient
from core.config import settings
from shared import exceptions as e
from shared.functions import clean_params
from shared.redis import client as cache
from . import schema as s
class TMK_API(AsyncClient):
def __init__(self):
self.logger = getLogger(__name__)
super().__init__(
base_url=settings.TMK_BASE_URL,
)
async def get_token(self):
token = cache.get('tmk_token')
if token is None:
token = await self.login()
cache.set('tmk_token', token, 10800)
else:
token = token.decode()
return token
async def login(self):
req = await self.post(
'/auth',
json={
'login': settings.TMK_LOGIN,
'password': settings.TMK_PASSWORD,
},
)
match req.status_code:
case st.HTTP_200_OK:
return s.AccessTokenModel.model_validate(
req.json()
).access_token
case _:
self.logger.error(req.json())
raise e.UnknownException
async def getQueue(
self,
code_mo: str | None = None,
doctor_spec: str | None = None,
doctor_snils: str | None = None,
doctor_snils_strict: Literal['y', 'n'] = 'n',
date_begin: date | None = None,
date_end: date | None = None,
patient_snils: str | None = None,
patient_fio: str | None = None,
patient_policy: str | None = None,
patient_phone: str | None = None,
patient_birthdate: date | None = None,
tk_status: str | None = None,
):
token = await self.get_token()
req = await self.get(
'/getQueue',
headers={'Authorization': f'Bearer {token}'},
params=clean_params(
{
'code_mo': code_mo,
'doctor_spec': doctor_spec,
'doctor_snils': doctor_snils,
'doctor_snils_strict': doctor_snils_strict,
'date_begin': date_begin,
'date_end': date_end,
'patient_snils': patient_snils,
'patient_fio': patient_fio,
'patient_policy': patient_policy,
'patient_phone': patient_phone,
'patient_birthdate': patient_birthdate,
'tk_status': tk_status,
}
),
)
match req.status_code:
case st.HTTP_200_OK:
return [s.QueueModel.model_validate(i) for i in req.json()]
case _:
self.logger.error(req.json())
raise e.UnknownException

31
src/clients/tmk/schema.py Normal file
View File

@ -0,0 +1,31 @@
from datetime import datetime
from pydantic import BaseModel
class AccessTokenModel(BaseModel):
access_token: str
class QueueModel(BaseModel):
id: int
guid: str
created_at: datetime
code_mo: int | None
mo_name: str | None
doctor_spec: str
doctor_snils: str | None
doctor_fio: str | None
patient_name: str | None
patient_birthday: datetime | None
patient_snils: str
patient_policy: str | None
patient_phone: str | None
patient_email: str | None
tmk_status: int
tmk_status_name: str
tmk_cancel_reason: int | None
tmk_cancel_reason_name: str | None
vks_doctor_link: str | None
vks_patient_link: str | None
doctor_spec_name: str | None

View File

@ -41,9 +41,6 @@ class Settings(BaseSettings):
# Loki Logging
LOKI_URL: str | None = Field(default=None)
# Environment
TMK_BASE_URL: str = Field(default='https://tmk-api.tatar.ru/api')
# ESIA
ESIA_BASE_URL: str = Field(default='https://esia.gosuslugi.ru')
ESIA_CLIENT_ID: str = Field(default='')
@ -70,6 +67,11 @@ class Settings(BaseSettings):
TDN_LOGIN: str = Field(default='')
TDN_PASSWORD: str = Field(default='')
# TMK
TMK_BASE_URL: str = Field(default='https://tmk-api.tatar.ru/api')
TMK_LOGIN: str = Field(default='admin')
TMK_PASSWORD: str = Field(default='12345')
@model_validator(mode='after')
def celery_env(self):
environ['CELERY_BROKER_URL'] = self.REDIS_URL

5
src/shared/functions.py Normal file
View File

@ -0,0 +1,5 @@
from typing import Any
def clean_params(data: dict[Any, Any]):
return {k: v for k, v in data.items() if v is not None}