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

This commit is contained in:
2025-11-11 12:58:58 +03:00
parent b602b75234
commit cf1324633d
9 changed files with 82 additions and 45 deletions

View File

@ -29,6 +29,7 @@ dependencies = [
"pydantic-extra-types==2.10.5",
"semver==3.0.4",
"pyjwt==2.10.1",
"python-multipart==0.0.20",
# CLI
"typer-slim==0.16.1",
]

View File

View File

View File

@ -0,0 +1,15 @@
from logging import getLogger
from fastapi import APIRouter
logger = getLogger(__name__)
router = APIRouter(
prefix='/remd',
tags=[
'REMD',
],
)
@router.get('/callback')
async def callback(): ...

View File

@ -3,7 +3,7 @@ from json import dumps
from logging import getLogger
from typing import Annotated
from fastapi import APIRouter, Body, Depends, status
from fastapi import APIRouter, Body, Depends, UploadFile, status
from apps.tdn.auth import token
from apps.users.auth import login
@ -91,7 +91,7 @@ async def get_routes_list(user: Annotated[User, Depends(login)]):
@router.get('/getHospExaminations')
async def get_hosp_examinations(
user: Annotated[User, Depends(login)], examId: str
user: Annotated[User, Depends(login)], examId: str | None = None
):
"""
Get list of hospital examinations.
@ -178,37 +178,6 @@ async def aemd(user: Annotated[User, Depends(login)]):
)
# @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'
# observations = await c.tdn_api.observations_search(
# tdn_access_token, patientId
# )
# if observations.total == 0:
# raise e.NotFoundException(detail='No observations found')
# observation = observations.items[-1]
# observation_measurements = await
# c.tdn_api.observations_measurement_search(
# tdn_access_token, observation.uid
# )
# return observation_measurements
# created = created_at.strftime('%Y-%m-%d %H:%M:%S')
# data = {
# 'ad': ad,
# 'sd': sd,
# 'pulse': pulse,
# 'created_at': created,
# 'comment': comment,
# 'status': status,
# }
# cache_key = f'tdn:measurement:{user.id}:{created}'
# cache.set(cache_key, dumps(data))
@router.post('/measurement', status_code=status.HTTP_202_ACCEPTED)
async def measurement(
tdn_access_token: Annotated[str, Depends(token)],
@ -217,7 +186,9 @@ async def measurement(
sd: Annotated[int, Body()],
pulse: Annotated[int, Body()],
comment: Annotated[str, Body()],
status: Annotated[str, Body()],
status: Annotated[int, Body(ge=1, le=3)],
serial_number: Annotated[str, Body()],
ekg: UploadFile,
):
observations = await c.tdn_api.observations_search(
tdn_access_token, user.vita_id
@ -235,6 +206,7 @@ async def measurement(
dad_measurement = None
pulse_measurement = None
health_measurement = None
health_measurement_created_at = None
observations = observations.items[::-1]
for observation in observations:
@ -264,8 +236,12 @@ async def measurement(
health_observationUid = measurement.observationUid
for metric in measurement.obsrvMtMetrics:
if metric.metric.code == 'HEALTH':
if metric.metric.code == 'HEALTH' and (
health_measurement_created_at is None
or metric.createdAt > health_measurement_created_at
):
health_measurement = metric.uid
health_measurement_created_at = metric.createdAt
if (
not ad_obsrvMeasurementUid
@ -276,6 +252,7 @@ async def measurement(
or not health_obsrvMeasurementUid
or not health_observationUid
or not health_measurement
or not health_measurement_created_at
):
ad_obsrvMeasurementUid = None
sad_measurement = None
@ -285,6 +262,7 @@ async def measurement(
health_obsrvMeasurementUid = None
health_observationUid = None
health_measurement = None
health_measurement_created_at = None
else:
break
@ -320,17 +298,17 @@ async def measurement(
# SAD
await c.tdn_api.create_series_values(
tdn_access_token, ad_series_uid, sad_measurement, nvalue=str(sd)
tdn_access_token, ad_series_uid, sad_measurement, nvalue=sd
)
# DAD
await c.tdn_api.create_series_values(
tdn_access_token, ad_series_uid, dad_measurement, nvalue=str(ad)
tdn_access_token, ad_series_uid, dad_measurement, nvalue=ad
)
# PULSE
await c.tdn_api.create_series_values(
tdn_access_token, ad_series_uid, pulse_measurement, nvalue=str(pulse)
tdn_access_token, ad_series_uid, pulse_measurement, nvalue=pulse
)
health_series = await c.tdn_api.create_series(
@ -346,7 +324,16 @@ async def measurement(
tdn_access_token,
health_series_uid,
health_measurement,
svalue=str(comment),
nvalue=status,
svalue=comment,
)
# EKG
await c.tdn_api.ekg(
tdn_access_token,
user.vita_id,
serial_number,
ekg,
)
created = datetime.now(UTC).strftime('%Y-%m-%d %H:%M:%S')
@ -364,7 +351,9 @@ async def measurement(
@router.get('/measurements')
async def measurements(
user: Annotated[str, Depends(login)],
user: Annotated[User, Depends(login)],
):
data = [cache.get(key) for key in cache.keys(f'tdn:measurement:{user}:*')]
data = [
cache.get(key) for key in cache.keys(f'tdn:measurement:{user.id}:*')
]
return data

View File

@ -3,6 +3,7 @@ from json import dumps
from logging import getLogger
from urllib.parse import quote, urlencode
from fastapi import UploadFile
from fastapi import status as st
from httpx import AsyncClient
@ -130,11 +131,11 @@ class TDN_API(AsyncClient):
seriesUid: str,
obsrvMtMetricUid: str,
*,
nvalue: str | None = None,
fvalue: str | None = None,
nvalue: int | None = None,
fvalue: float | None = None,
svalue: str | None = None,
):
data = {
data: dict[str, str | int | float] = {
'seriesUid': seriesUid,
'obsrvMtMetricUid': obsrvMtMetricUid,
}
@ -160,3 +161,27 @@ class TDN_API(AsyncClient):
case _:
self.logger.error(res.json())
raise e.UnknownException
async def ekg(
self,
access_token: str,
patientUid: str,
serial_number: str,
file: UploadFile,
):
req = await self.post(
'/ddn/observation/series-values/ecg/krb02',
headers={'Authorization': f'Bearer {access_token}'},
files={'ekg': (file.filename, file.file, file.content_type)},
json={
'patientUid': patientUid,
'serialNumber': serial_number,
},
)
match req.status_code:
case st.HTTP_200_OK:
return s.EkgModel.model_validate(req.json())
case _:
self.logger.error(req.json())
raise e.UnknownException

View File

@ -108,3 +108,8 @@ class SeriesValueModel(BaseModel):
filepath: str | None
mobileId: str | None
tisId: str | None
class EkgModel(BaseModel):
success: bool
# result: ...

View File

@ -199,7 +199,7 @@ class VITACORE_API(AsyncClient):
self.logger.error(req.json())
raise e.UnknownException
async def getHospExaminations(self, patId: str, examId: str):
async def getHospExaminations(self, patId: str, examId: str | None = None):
patId = 'b66a85f1-4aaa-4db8-942a-2de44341824e'
token = await self.get_token()
req = await self.get(

View File

@ -1,6 +1,7 @@
from fastapi import APIRouter, HTTPException
from apps.esia.v1.router import router as esia_router
from apps.remd.v1.router import router as remd_router
from apps.users.v1.router import router as users_router
from . import get_openapi_schema, get_swagger_html
@ -9,6 +10,7 @@ router = APIRouter(prefix='/v1')
router.include_router(esia_router)
router.include_router(users_router)
router.include_router(remd_router)
openapi_schema = get_openapi_schema(router)
swagger_ui_html = get_swagger_html(router)