From b67862b115a9e5ed00b8378515faa37578716394 Mon Sep 17 00:00:00 2001 From: Pradip-p Date: Mon, 24 Jun 2024 20:55:37 +0545 Subject: [PATCH] feat: add endpoints and functions for project retrieval --- src/backend/app/config.py | 2 +- src/backend/app/projects/project_crud.py | 57 ++++++++++++++++++++++ src/backend/app/projects/project_routes.py | 19 ++++++++ 3 files changed, 77 insertions(+), 1 deletion(-) diff --git a/src/backend/app/config.py b/src/backend/app/config.py index 993e75c9..9623b4ac 100644 --- a/src/backend/app/config.py +++ b/src/backend/app/config.py @@ -53,7 +53,7 @@ def assemble_cors_origins( POSTGRES_HOST: Optional[str] = "db" POSTGRES_USER: Optional[str] = "dtm" POSTGRES_PASSWORD: Optional[str] = "dtm" - POSTGRES_DB: Optional[str] = "datm-db" + POSTGRES_DB: Optional[str] = "dtm_db" DTM_DB_URL: Optional[PostgresDsn] = None diff --git a/src/backend/app/projects/project_crud.py b/src/backend/app/projects/project_crud.py index 3c67b3b6..b851310f 100644 --- a/src/backend/app/projects/project_crud.py +++ b/src/backend/app/projects/project_crud.py @@ -1,7 +1,9 @@ import json +from typing import List, Optional from sqlalchemy.orm import Session from app.projects import project_schemas from app.db import db_models +from app.models.enums import HTTPStatus from loguru import logger as log import shapely.wkb as wkblib from shapely.geometry import shape @@ -9,7 +11,62 @@ from app.utils import merge_multipolygon from fmtm_splitter.splitter import split_by_square from fastapi.concurrency import run_in_threadpool +from app.db import database +from fastapi import Depends +async def get_project_by_id( + db: Session = Depends(database.get_db), project_id: Optional[int] = None +) -> db_models.DbProject: + """Get a single project by id.""" + if not project_id: + return None + + db_project = db.query(db_models.DbProject).filter(db_models.DbProject.id == project_id).first() + if not db_project: + raise HTTPException( + status_code=HTTPStatus.NOT_FOUND, + detail=f"Project with ID {project_id} does not exist", + ) + return db_project + +async def get_projects( + db: Session, + skip: int = 0, + limit: int = 100, +): + """Get all projects.""" + db_projects = ( + db.query(db_models.DbProject) + .order_by(db_models.DbProject.id.desc()) + .offset(skip) + .limit(limit) + .all() + ) + project_count = db.query(db_models.DbProject).count() + return project_count, await convert_to_app_projects(db_projects) + +async def convert_to_app_projects( + db_projects: List[db_models.DbProject], +) -> List[project_schemas.ProjectInfo]: + """Legacy function to convert db models --> Pydantic. + + TODO refactor to use Pydantic model methods instead. + """ + if db_projects and len(db_projects) > 0: + filtered_projects = [ + { + "id": project.id, + "name": project.name, + "short_description": project.short_description, + "description": project.description, + "per_task_instructions": project.per_task_instructions, + "outline": None + } + for project in db_projects if project is not None + ] + return [project_schemas.ProjectOut(**project) for project in filtered_projects] + else: + return [] async def create_project_with_project_info( db: Session, project_metadata: project_schemas.ProjectIn diff --git a/src/backend/app/projects/project_routes.py b/src/backend/app/projects/project_routes.py index e3ef5cca..07125498 100644 --- a/src/backend/app/projects/project_routes.py +++ b/src/backend/app/projects/project_routes.py @@ -13,6 +13,7 @@ from app.utils import multipolygon_to_polygon from app.s3 import s3_client from app.config import settings +from app.db import db_models router = APIRouter( @@ -127,3 +128,21 @@ async def generate_presigned_url(data: project_schemas.PresignedUrlRequest): status_code=HTTPStatus.BAD_REQUEST, detail=f"Failed to generate pre-signed URL. {e}", ) + +@router.get("/", tags=["Projects"], response_model=list[project_schemas.ProjectOut]) +async def read_projects( + skip: int = 0, + limit: int = 100, + db: Session = Depends(database.get_db), +): + """Return all projects.""" + total_count, projects = await project_crud.get_projects(db, skip, limit) + return projects + +@router.get("/{project_id}", tags=["Projects"], response_model=project_schemas.ProjectOut) +async def read_project( + db: Session = Depends(database.get_db), + project: db_models.DbProject = Depends(project_crud.get_project_by_id), +): + """Get a specific project by ID.""" + return project \ No newline at end of file