From 4548b523438db033c48bb6e31098aaaf7459a50a Mon Sep 17 00:00:00 2001 From: Cannon Lock Date: Wed, 7 Feb 2024 11:46:48 -0600 Subject: [PATCH] Add a objects endpoint for ingest process --- api/models/object.py | 7 ++++--- api/routes/ingest.py | 26 +++++++++++++++++++++----- api/tests/main.py | 11 +++++++++++ 3 files changed, 36 insertions(+), 8 deletions(-) diff --git a/api/models/object.py b/api/models/object.py index 2a07c07..cde2abd 100644 --- a/api/models/object.py +++ b/api/models/object.py @@ -10,12 +10,14 @@ class Base(BaseModel): source: Optional[dict] = None mime_type: Optional[str] = None sha256_hash: Optional[str] = None + object_group_id: Optional[int] = None class Config: orm_mode = True class Post(Base): + scheme: SchemeEnum host: str bucket: str @@ -27,14 +29,13 @@ class Config: class Get(Post): id: int - object_group_id: Optional[int] = None created_on: datetime.datetime updated_on: datetime.datetime deleted_on: Optional[datetime.datetime] = None -class GetSecureURL(Base): - secure_url: str +class GetSecureURL(Get): + pre_signed_url: str class Patch(Base): diff --git a/api/routes/ingest.py b/api/routes/ingest.py index 377cec7..4700871 100644 --- a/api/routes/ingest.py +++ b/api/routes/ingest.py @@ -1,9 +1,9 @@ -import datetime +import os from fastapi import APIRouter, Depends, HTTPException from sqlalchemy import insert, select, update, and_ from sqlalchemy.orm import selectinload, joinedload -from pydantic import parse_obj_as +import minio from api.database import ( get_async_session, @@ -116,14 +116,13 @@ async def patch_ingest_process(id: int, object: IngestProcessModel.Patch, groups return response -@router.get("/{id}/objects", response_model=list[Object.Get]) +@router.get("/{id}/objects", response_model=list[Object.GetSecureURL]) async def get_ingest_process_objects(id: int, groups: list[str] = Depends(get_groups)): """Get all objects for an ingestion process""" engine = get_engine() async_session = get_async_session(engine) - objects = None async with async_session() as session: select_stmt = select(IngestProcessSchema).where(and_(IngestProcessSchema.id == id)) @@ -131,6 +130,23 @@ async def get_ingest_process_objects(id: int, groups: list[str] = Depends(get_gr object_stmt = select(ObjectGroup).where(ObjectGroup.id == ingest_process.object_group_id).options(selectinload(ObjectGroup.objects)) objects_iterator = await session.execute(object_stmt) - objects = [Object.Get(x) for x in objects_iterator.scalar().objects] + schema_objects = objects_iterator.scalar().objects + if len(schema_objects) == 0: + return [] + try: + # Attach the secure url + first_object = schema_objects[0] + m = minio.Minio(endpoint=first_object.host, access_key=os.environ['access_key'], secret_key=os.environ['secret_key'], secure=True) + + for obj in schema_objects: + obj.pre_signed_url = m.presigned_get_object(bucket_name=obj.bucket, object_name=obj.key) + + return schema_objects + + except Exception as e: + raise HTTPException( + status_code=500, + detail=f"Failed to get secure url for object: {e}" + ) diff --git a/api/tests/main.py b/api/tests/main.py index 07c28f2..910e3c1 100644 --- a/api/tests/main.py +++ b/api/tests/main.py @@ -543,3 +543,14 @@ def test_get_objects(self, api_client): for object in objects: assert object['key'] in keys + #@pytest.skip("Manual testing only") + def test_get_objects_known_ingest_process(self, api_client): + + ingest_process_id = 1 + + response = api_client.get(f"/ingest-process/{ingest_process_id}/objects") + assert response.status_code == 200 + objects = response.json() + + assert len(objects) > 0 + assert objects[0]['pre_signed_url'] is not None