This commit is contained in:
@ -8,7 +8,8 @@ from fastapi import APIRouter, Body, Depends, status
|
|||||||
from apps.users.auth import login
|
from apps.users.auth import login
|
||||||
from apps.users.models import User
|
from apps.users.models import User
|
||||||
from clients import clients as c
|
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
|
from shared.redis import client as cache
|
||||||
|
|
||||||
logger = getLogger(__name__)
|
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)]):
|
async def get_profile(user: Annotated[User, Depends(login)]):
|
||||||
"""
|
"""
|
||||||
Get profile of user.
|
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)
|
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():
|
async def get_departments():
|
||||||
"""
|
"""
|
||||||
Get list of departments.
|
Get list of departments.
|
||||||
@ -36,7 +37,7 @@ async def get_departments():
|
|||||||
return await c.vitacore_api.getDepartments()
|
return await c.vitacore_api.getDepartments()
|
||||||
|
|
||||||
|
|
||||||
@router.get('/getWorkers', response_model=s.WorkersModel)
|
@router.get('/getWorkers', response_model=vs.WorkersModel)
|
||||||
async def get_workers(
|
async def get_workers(
|
||||||
user: Annotated[User, Depends(login)], departmentId: str
|
user: Annotated[User, Depends(login)], departmentId: str
|
||||||
):
|
):
|
||||||
@ -46,7 +47,7 @@ async def get_workers(
|
|||||||
return await c.vitacore_api.getWorkers(departmentId)
|
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)]):
|
async def get_specs(user: Annotated[User, Depends(login)]):
|
||||||
"""
|
"""
|
||||||
Get list of specialties.
|
Get list of specialties.
|
||||||
@ -54,7 +55,7 @@ async def get_specs(user: Annotated[User, Depends(login)]):
|
|||||||
return await c.vitacore_api.getSpecsV021()
|
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)]):
|
async def get_entries(user: Annotated[User, Depends(login)]):
|
||||||
"""
|
"""
|
||||||
Get list of entries for user by id.
|
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)
|
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)
|
# @router.post('/measurement', status_code=status.HTTP_202_ACCEPTED)
|
||||||
# async def measurement(tdn_access_token: Annotated[str, Depends(token)]):
|
# async def measurement(tdn_access_token: Annotated[str, Depends(token)]):
|
||||||
# patientId = '6debe050-b57e-442b-9b0e-8d304ca382b0'
|
# patientId = '6debe050-b57e-442b-9b0e-8d304ca382b0'
|
||||||
@ -206,35 +215,6 @@ async def measurements(
|
|||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
@router.get('/test')
|
@router.get('/aemd/test')
|
||||||
async def test_route():
|
async def test_route():
|
||||||
return await c.aemd_api.searchRegistryItem('16247900267')
|
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': 'врач-терапевт',
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
from .aemd.api import AEMD_API
|
from .aemd.api import AEMD_API
|
||||||
from .esia.api import ESIA_API
|
from .esia.api import ESIA_API
|
||||||
from .tdn.api import TDN_API
|
from .tdn.api import TDN_API
|
||||||
|
from .tmk.api import TMK_API
|
||||||
from .vitacore.api import VITACORE_API
|
from .vitacore.api import VITACORE_API
|
||||||
|
|
||||||
|
|
||||||
@ -8,6 +9,7 @@ class ClientsObject:
|
|||||||
_esia_api = None
|
_esia_api = None
|
||||||
_vitacore_api = None
|
_vitacore_api = None
|
||||||
_tdn_api = None
|
_tdn_api = None
|
||||||
|
_tmk_api = None
|
||||||
_aemd_api = None
|
_aemd_api = None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -31,6 +33,13 @@ class ClientsObject:
|
|||||||
|
|
||||||
return self._tdn_api
|
return self._tdn_api
|
||||||
|
|
||||||
|
@property
|
||||||
|
def tmk_api(self):
|
||||||
|
if not self._tmk_api:
|
||||||
|
self._tmk_api = TMK_API()
|
||||||
|
|
||||||
|
return self._tmk_api
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def aemd_api(self):
|
def aemd_api(self):
|
||||||
if not self._aemd_api:
|
if not self._aemd_api:
|
||||||
|
|||||||
0
src/clients/tmk/__init__.py
Normal file
0
src/clients/tmk/__init__.py
Normal file
97
src/clients/tmk/api.py
Normal file
97
src/clients/tmk/api.py
Normal 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
31
src/clients/tmk/schema.py
Normal 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
|
||||||
@ -41,9 +41,6 @@ class Settings(BaseSettings):
|
|||||||
# Loki Logging
|
# Loki Logging
|
||||||
LOKI_URL: str | None = Field(default=None)
|
LOKI_URL: str | None = Field(default=None)
|
||||||
|
|
||||||
# Environment
|
|
||||||
TMK_BASE_URL: str = Field(default='https://tmk-api.tatar.ru/api')
|
|
||||||
|
|
||||||
# ESIA
|
# ESIA
|
||||||
ESIA_BASE_URL: str = Field(default='https://esia.gosuslugi.ru')
|
ESIA_BASE_URL: str = Field(default='https://esia.gosuslugi.ru')
|
||||||
ESIA_CLIENT_ID: str = Field(default='')
|
ESIA_CLIENT_ID: str = Field(default='')
|
||||||
@ -70,6 +67,11 @@ class Settings(BaseSettings):
|
|||||||
TDN_LOGIN: str = Field(default='')
|
TDN_LOGIN: str = Field(default='')
|
||||||
TDN_PASSWORD: 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')
|
@model_validator(mode='after')
|
||||||
def celery_env(self):
|
def celery_env(self):
|
||||||
environ['CELERY_BROKER_URL'] = self.REDIS_URL
|
environ['CELERY_BROKER_URL'] = self.REDIS_URL
|
||||||
|
|||||||
5
src/shared/functions.py
Normal file
5
src/shared/functions.py
Normal 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}
|
||||||
Reference in New Issue
Block a user