From a604597209c704b57b8c743eb7e550c114ac1546 Mon Sep 17 00:00:00 2001 From: Mike Liao Date: Tue, 22 Oct 2024 07:32:04 -0700 Subject: [PATCH 1/4] simplified the api naming and remove the user authentication --- .../backend/application/document_hub.py | 15 +++++++------- .../backend/business/document_manager.py | 11 +++++----- app/central_storage/webapi/routes/__init__.py | 2 +- ...ent_by_id.py => retrieve_document_info.py} | 17 +++++----------- .../webapi/routes/upload_document.py | 20 ++++++------------- 5 files changed, 24 insertions(+), 41 deletions(-) rename app/central_storage/webapi/routes/{get_document_by_id.py => retrieve_document_info.py} (71%) diff --git a/app/central_storage/backend/application/document_hub.py b/app/central_storage/backend/application/document_hub.py index 68a4ce7..caa04e4 100644 --- a/app/central_storage/backend/application/document_hub.py +++ b/app/central_storage/backend/application/document_hub.py @@ -4,22 +4,21 @@ from app.central_storage.backend.business.document_manager import ( class DocumentHub: - def __init__(self, user_id: str): - self.user_id = user_id + def __init__(self, ): self.document_manager = DocumentManager(self.user_id) return - async def get_document_by_id(self, document_id: str): - return await self.document_manager.get_document_details_by_id(document_id) + async def retrieve_document_info(self, document_id: str): + return await self.document_manager.retrieve_document_info(document_id) - async def upload_document_for_object( - self, object_id: str, file_name: str, file_data: bytes + async def upload_document( + self, associated_with: str, file_name: str, file_data: bytes ) -> bool: """Upload a file Args: file_name: the name of the file file (bytes): the file to be uploaded """ - return await self.document_manager.upload_file_for_object( - object_id, file_name, file_data + return await self.document_manager.upload_file( + associated_with, file_name, file_data ) diff --git a/app/central_storage/backend/business/document_manager.py b/app/central_storage/backend/business/document_manager.py index 2787945..41c0e50 100644 --- a/app/central_storage/backend/business/document_manager.py +++ b/app/central_storage/backend/business/document_manager.py @@ -3,11 +3,10 @@ from app.central_storage.backend.models.models import MediaType, DataFormat class DocumentManager: - def __init__(self, user_id) -> None: - self.user_id = user_id + def __init__(self) -> None: self.document_service = DocumentService() - async def get_document_details_by_id(self, document_id: str): + async def retrieve_document_info(self, document_id: str): await self.document_service.load_document(document_id=document_id) download_link = ( @@ -19,15 +18,15 @@ class DocumentManager: "file_download_url": download_link, } - async def upload_file_for_object( - self, object_id: str, file_name: str, file_data: bytes + async def upload_file( + self, associated_with: str, file_name: str, file_data: bytes ) -> bool: await self.document_service.new_document( file_name=file_name, # This 'UNKNOWN' will make the document manager decide the media type from file name media_type=MediaType.UNKNOWN, data_format=DataFormat.RAW, - created_by=object_id, + created_by=associated_with, ) return await self.document_service.save_document_file(file_data) or None # TODO: This should go to Freeleaps App diff --git a/app/central_storage/webapi/routes/__init__.py b/app/central_storage/webapi/routes/__init__.py index 4c8c6d5..84c0b9d 100644 --- a/app/central_storage/webapi/routes/__init__.py +++ b/app/central_storage/webapi/routes/__init__.py @@ -1,5 +1,5 @@ from fastapi import APIRouter -from .get_document_by_id import router as doc_router +from .retrieve_document_info import router as doc_router from .upload_document import router as ud_router api_router = APIRouter() diff --git a/app/central_storage/webapi/routes/get_document_by_id.py b/app/central_storage/webapi/routes/retrieve_document_info.py similarity index 71% rename from app/central_storage/webapi/routes/get_document_by_id.py rename to app/central_storage/webapi/routes/retrieve_document_info.py index a1dc665..bcf8941 100644 --- a/app/central_storage/webapi/routes/get_document_by_id.py +++ b/app/central_storage/webapi/routes/retrieve_document_info.py @@ -17,25 +17,18 @@ token_manager = TokenManager() # Web API # Fetch document by ID @router.get( - "/get-document-by-id/{document_id}", - operation_id="get-document-by-id", + "/retrieve_document_info/{document_id}", + operation_id="retrieve_document_info", summary="Fetch a document by its ID", description="Retrieve a specific document by its document ID and return file name and download URL", response_description="The document details including file name and download URL", ) -async def get_document_by_id( - document_id: str, - current_user: dict = Depends(token_manager.get_current_user), +async def retrieve_document_info( + document_id: str ): - user_id = current_user.get("id") - - if not user_id: - raise HTTPException( - status_code=HTTP_401_UNAUTHORIZED, detail="Could not validate credentials" - ) # Fetch the document using DocumentHub - document = await DocumentHub(user_id).get_document_by_id(document_id) + document = await DocumentHub().retrieve_document_info(document_id) # If document is not found, raise 404 error if not document: diff --git a/app/central_storage/webapi/routes/upload_document.py b/app/central_storage/webapi/routes/upload_document.py index d625a48..fda28d0 100644 --- a/app/central_storage/webapi/routes/upload_document.py +++ b/app/central_storage/webapi/routes/upload_document.py @@ -13,28 +13,20 @@ token_manager = TokenManager() @router.post( "/upload-document", - summary="upload a document for a given object.", + summary="upload a document with a given associated_with id.", description="upload a document. If success, returning the document id", ) async def attach_document_for_request( - object_id: str = Form(...), - file: UploadFile = File(None), - current_user: dict = Depends(token_manager.get_current_user), + associated_with: str = Form(...), + file: UploadFile = File(None) ): - print("current user", current_user) - user_id = current_user.get("id") - print("current user id", user_id) - if not user_id: - raise HTTPException( - status_code=HTTP_401_UNAUTHORIZED, detail="Could not validate credentials" - ) - document_hub = DocumentHub(user_id) + document_hub = DocumentHub() # File processing try: file_data = await file.read() # You can use async chunking for larger files - document_id = await document_hub.upload_document_for_object( - object_id, file.filename, file_data + document_id = await document_hub.upload_document( + associated_with, file.filename, file_data ) if document_id: From 154c0a4d36a80081b67a30ec62629bc20c42e0eb Mon Sep 17 00:00:00 2001 From: Mike Liao Date: Tue, 22 Oct 2024 17:20:44 -0700 Subject: [PATCH 2/4] add upload document api --- .../webapi/routes/upload_document.py | 21 +++++----- .../webapi/routes/upload_file.py | 42 +++++++++++++++++++ 2 files changed, 53 insertions(+), 10 deletions(-) create mode 100644 app/central_storage/webapi/routes/upload_file.py diff --git a/app/central_storage/webapi/routes/upload_document.py b/app/central_storage/webapi/routes/upload_document.py index fda28d0..bb8b471 100644 --- a/app/central_storage/webapi/routes/upload_document.py +++ b/app/central_storage/webapi/routes/upload_document.py @@ -5,36 +5,37 @@ from starlette.status import HTTP_401_UNAUTHORIZED from fastapi.encoders import jsonable_encoder from fastapi.responses import JSONResponse from app.central_storage.backend.application.document_hub import DocumentHub - +from pydantic import BaseModel router = APIRouter() -token_manager = TokenManager() +class Item(BaseModel): + associated_with: str + name: str + blob: bytes @router.post( "/upload-document", - summary="upload a document with a given associated_with id.", + summary="upload a document with a given associated_with id, document name and document data.", description="upload a document. If success, returning the document id", ) -async def attach_document_for_request( - associated_with: str = Form(...), - file: UploadFile = File(None) +async def upload_document( + item:Item ): document_hub = DocumentHub() # File processing try: - file_data = await file.read() # You can use async chunking for larger files document_id = await document_hub.upload_document( - associated_with, file.filename, file_data + item.associated_with, item.name, item.blob ) if document_id: - result = {"document_id": str(document_id), "file_name": file.filename} + result = {"document_id": str(document_id)} return JSONResponse(content=jsonable_encoder(result)) else: return JSONResponse( - status_code=500, content={"error": "File upload failed"} + status_code=500, content={"error": "Document upload failed"} ) except Exception as e: diff --git a/app/central_storage/webapi/routes/upload_file.py b/app/central_storage/webapi/routes/upload_file.py new file mode 100644 index 0000000..956c472 --- /dev/null +++ b/app/central_storage/webapi/routes/upload_file.py @@ -0,0 +1,42 @@ +from fastapi import APIRouter, UploadFile, File, Form, HTTPException +from fastapi import APIRouter, Depends +from infra.token.token_manager import TokenManager +from starlette.status import HTTP_401_UNAUTHORIZED +from fastapi.encoders import jsonable_encoder +from fastapi.responses import JSONResponse +from app.central_storage.backend.application.document_hub import DocumentHub + + +router = APIRouter() +token_manager = TokenManager() + + +@router.post( + "/upload-file", + summary="upload a document with a given associated_with id.", + description="upload a document. If success, returning the document id and file name", +) +async def upload_file( + associated_with: str = Form(...), + file: UploadFile = File(None) +): + + document_hub = DocumentHub() + # File processing + try: + file_data = await file.read() # You can use async chunking for larger files + document_id = await document_hub.upload_document( + associated_with, file.filename, file_data + ) + + if document_id: + result = {"document_id": str(document_id), "file_name": file.filename} + return JSONResponse(content=jsonable_encoder(result)) + else: + return JSONResponse( + status_code=500, content={"error": "File upload failed"} + ) + + except Exception as e: + print("this is exception", e) + return JSONResponse(status_code=500, content={"error": "Internal server error"}) From 4ebf8579dbfe72aabfcb7543c1e6c00f11971b1c Mon Sep 17 00:00:00 2001 From: Mike Liao Date: Tue, 22 Oct 2024 18:18:59 -0700 Subject: [PATCH 3/4] add 'read document as http media' --- .../backend/application/document_hub.py | 3 ++ .../backend/business/document_manager.py | 6 +++ .../routes/read_document_as_http_media.py | 37 +++++++++++++++++++ 3 files changed, 46 insertions(+) create mode 100644 app/central_storage/webapi/routes/read_document_as_http_media.py diff --git a/app/central_storage/backend/application/document_hub.py b/app/central_storage/backend/application/document_hub.py index caa04e4..2b59585 100644 --- a/app/central_storage/backend/application/document_hub.py +++ b/app/central_storage/backend/application/document_hub.py @@ -11,6 +11,9 @@ class DocumentHub: async def retrieve_document_info(self, document_id: str): return await self.document_manager.retrieve_document_info(document_id) + async def read_document_file_as_http_media_data(self, document_id: str): + return await self.document_manager.read_document_file_as_http_media_data(document_id) + async def upload_document( self, associated_with: str, file_name: str, file_data: bytes ) -> bool: diff --git a/app/central_storage/backend/business/document_manager.py b/app/central_storage/backend/business/document_manager.py index 41c0e50..6ed4201 100644 --- a/app/central_storage/backend/business/document_manager.py +++ b/app/central_storage/backend/business/document_manager.py @@ -18,6 +18,12 @@ class DocumentManager: "file_download_url": download_link, } + async def read_document_file_as_http_media_data(self, document_id: str): + await self.document_service.load_document(document_id=document_id) + + return await self.document_service.read_document_file_as_http_media_data() + + async def upload_file( self, associated_with: str, file_name: str, file_data: bytes ) -> bool: diff --git a/app/central_storage/webapi/routes/read_document_as_http_media.py b/app/central_storage/webapi/routes/read_document_as_http_media.py new file mode 100644 index 0000000..76b141c --- /dev/null +++ b/app/central_storage/webapi/routes/read_document_as_http_media.py @@ -0,0 +1,37 @@ +from fastapi import APIRouter +from infra.token.token_manager import TokenManager +from fastapi import APIRouter, Depends +from fastapi.encoders import jsonable_encoder +from fastapi.responses import JSONResponse +from fastapi import Depends, HTTPException +from starlette.status import HTTP_401_UNAUTHORIZED +from fastapi.encoders import jsonable_encoder +from fastapi.responses import JSONResponse +from infra.token.token_manager import TokenManager +from app.central_storage.backend.application.document_hub import DocumentHub + +router = APIRouter() + + +# Web API +# read document as http media +@router.get( + "/read-document-as-http-media/{document_id}", + operation_id="read-document-as-http-media", + summary="Read document as http media", + description="Read document as http media which can be used by html directly", + response_description="The http media which can be used by html directly", +) +async def read_document_as_http_media( + document_id: str +): + + # Fetch the document using DocumentHub + media = await DocumentHub().read_document_file_as_http_media_data(document_id) + + # If document is not found, raise 404 error + if not media: + raise HTTPException(status_code=404, detail="Document not found") + + # Return the document details + return JSONResponse(content=jsonable_encoder({"media": media})) From 92ef286d1661277a2d6160b2f117356e01f0729e Mon Sep 17 00:00:00 2001 From: Mike Liao Date: Tue, 22 Oct 2024 18:22:31 -0700 Subject: [PATCH 4/4] fix the routes --- app/central_storage/webapi/routes/__init__.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/central_storage/webapi/routes/__init__.py b/app/central_storage/webapi/routes/__init__.py index 84c0b9d..9f744dd 100644 --- a/app/central_storage/webapi/routes/__init__.py +++ b/app/central_storage/webapi/routes/__init__.py @@ -1,9 +1,11 @@ from fastapi import APIRouter -from .retrieve_document_info import router as doc_router +from .retrieve_document_info import router as ri_router from .upload_document import router as ud_router +from .read_document_as_http_media import router as rd_router api_router = APIRouter() -api_router.include_router(doc_router, tags=["attachment"]) -api_router.include_router(ud_router, tags=["attachment"]) +api_router.include_router(ri_router, tags=["document"]) +api_router.include_router(ud_router, tags=["document"]) +api_router.include_router(rd_router, tags=["document"]) websocket_router = APIRouter()