diff --git a/pyproject.toml b/pyproject.toml index c5b95bb..cf65f89 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,6 +29,7 @@ dependencies = [ "pydantic-extra-types==2.10.5", "semver==3.0.4", "pyjwt==2.10.1", + "xmltodict==1.0.2", "python-multipart==0.0.20", # CLI "typer-slim==0.16.1", diff --git a/src/apps/remd/v1/router.py b/src/apps/remd/v1/router.py index 05622af..aad08ea 100644 --- a/src/apps/remd/v1/router.py +++ b/src/apps/remd/v1/router.py @@ -1,6 +1,13 @@ from logging import getLogger +import xmltodict from fastapi import APIRouter, HTTPException, Request +from orjson import dumps, loads + +from apps.users.v1.schema import AEMDDemandContent +from shared.redis import client + +from . import schema as s logger = getLogger(__name__) router = APIRouter( @@ -13,18 +20,26 @@ router = APIRouter( @router.post('/callback') async def callback(request: Request): - logger.info(request.headers.get('content-type', '')) - # if not request.headers.get('content-type', '').startswith( - # 'application/xml' - # ): - # logger.warning('Content-Type must be application/xml') - # raise HTTPException( - # status_code=400, detail='Content-Type must be application/xml' - # ) - body_bytes = await request.body() if not body_bytes: logger.warning('Empty body') raise HTTPException(status_code=400, detail='Empty body') - print(body_bytes) + body = body_bytes.decode('utf-8').replace('\r', '').replace('\n', '') + body_dict = xmltodict.parse(body) + body = s.Remd.model_validate(body_dict) + file_request = body.Envelope.body.sendDocumentFileRequest + + data = await client.get(f'aemd_messages:{file_request.relatesToMessage}') + + if not data: + raise HTTPException(status_code=400, detail='Message not found') + + messageData = AEMDDemandContent(**loads(data)) + await client.delete(f'aemd_messages:{file_request.relatesToMessage}') + await client.set( + f'aemd{messageData["vitaId"]}:{messageData["emdrId"]}', + dumps(s.AEMDFileData(data=file_request.file.data)), + ) + + return diff --git a/src/apps/remd/v1/schema.py b/src/apps/remd/v1/schema.py new file mode 100644 index 0000000..19c39c4 --- /dev/null +++ b/src/apps/remd/v1/schema.py @@ -0,0 +1,28 @@ +from typing import TypedDict + +from pydantic import BaseModel, Field + + +class FileModel(BaseModel): + data: str + + +class RequestModel(BaseModel): + relatesToMessage: str + file: FileModel + + +class BodyModel(BaseModel): + sendDocumentFileRequest: RequestModel + + +class EnvelopeModel(BaseModel): + body: BodyModel = Field(..., alias='s:Body') + + +class Remd(BaseModel): + Envelope: EnvelopeModel = Field(..., alias='s:Envelope') + + +class AEMDFileData(TypedDict): + data: str diff --git a/src/apps/users/v1/router.py b/src/apps/users/v1/router.py index 032782a..cc1d422 100644 --- a/src/apps/users/v1/router.py +++ b/src/apps/users/v1/router.py @@ -206,7 +206,7 @@ async def get_aemd(user: Annotated[User, Depends(login)]): return_items: list[s.AEMDReturnFile] = [] for item in items: - is_cached = await cache.get(f'aemd:{item["localUid"]}') + is_cached = await cache.get(f'aemd:{user.vita_id}:{item["emdrId"]}') return_items.append( s.AEMDReturnFile( @@ -233,7 +233,12 @@ async def post_aemd(user: Annotated[User, Depends(login)], emdrId: str): @router.get('/aemd/{emdrId}') async def get_aemd_file(user: Annotated[User, Depends(login)], emdrId: str): - return + data = await cache.get(f'aemd:{user.vita_id}:{emdrId}') + + if not data: + raise e.NotFoundException(status_code=404, detail='File not found') + + return loads(data) @router.post('/measurement', status_code=status.HTTP_202_ACCEPTED)