From 707d02d2b15df6b28d79b5dd2c604fe79d1898e5 Mon Sep 17 00:00:00 2001 From: sujanadh Date: Thu, 18 Jan 2024 13:52:09 +0545 Subject: [PATCH] feat: paginated submissions by project --- src/backend/app/submission/submission_crud.py | 21 +++++++++++ .../app/submission/submission_routes.py | 37 ++++++++++++++++++- .../app/submission/submission_schemas.py | 19 ++++++++++ 3 files changed, 75 insertions(+), 2 deletions(-) diff --git a/src/backend/app/submission/submission_crud.py b/src/backend/app/submission/submission_crud.py index d4659a0764..c0d20c4710 100644 --- a/src/backend/app/submission/submission_crud.py +++ b/src/backend/app/submission/submission_crud.py @@ -762,3 +762,24 @@ async def get_submissions_by_date( ] return response + + +async def get_submission_by_project(project_id:int, skip:0, limit:100, db:Session): + project = await project_crud.get_project(db, project_id) + s3_project_path = f"/{project.organisation_id}/{project_id}" + s3_submission_path = f"/{s3_project_path}/submission.zip" + + try: + file = get_obj_from_bucket(settings.S3_BUCKET_NAME, s3_submission_path) + except ValueError as e: + return 0, [] + + with zipfile.ZipFile(file, "r") as zip_ref: + with zip_ref.open("submissions.json") as file_in_zip: + content = file_in_zip.read() + + content = json.loads(content) + start_index = skip + end_index = skip + limit + paginated_content = content[start_index:end_index] + return len(content), paginated_content diff --git a/src/backend/app/submission/submission_routes.py b/src/backend/app/submission/submission_routes.py index 24771d5445..ea68e9db2c 100644 --- a/src/backend/app/submission/submission_routes.py +++ b/src/backend/app/submission/submission_routes.py @@ -21,7 +21,7 @@ import os from typing import Optional -from fastapi import APIRouter, BackgroundTasks, Depends, Response +from fastapi import APIRouter, BackgroundTasks, Depends, Response, Query from fastapi.concurrency import run_in_threadpool from fastapi.responses import FileResponse, JSONResponse from osm_fieldwork.odk_merge import OdkMerge @@ -32,7 +32,7 @@ from app.config import settings from app.db import database from app.projects import project_crud, project_schemas -from app.submission import submission_crud +from app.submission import submission_crud, submission_schemas from app.tasks import tasks_crud router = APIRouter( @@ -357,3 +357,36 @@ async def get_submission_form_fields( odk_form = central_crud.get_odk_form(project) response = odk_form.form_fields(project.odkid, str(task_list[0])) return response + +@router.get("/submission_table/{project_id}") +async def submission_table( + background_tasks: BackgroundTasks, + project_id: int, + page: int = Query(1, ge=1), + results_per_page: int = Query(13, le=100), + db: Session = Depends(database.get_db) + ): + """ + This api returns the submission table of a project. + It takes two parameter: project_id and task_id. + project_id: The ID of the project. This endpoint returns the submission table of this project. + task_id: The ID of the task. This endpoint returns the submission table of this task. + """ + skip = (page - 1) * results_per_page + limit = results_per_page + count, data = await submission_crud.get_submission_by_project(project_id, skip, limit, db) + background_task_id = await project_crud.insert_background_task_into_database( + db, "sync_submission", project_id + ) + + background_tasks.add_task( + submission_crud.update_submission_in_s3, db, project_id, background_task_id + ) + pagination = await project_crud.get_pagination( + page, count, results_per_page, count + ) + response = submission_schemas.PaginatedSubmissions( + results=data, + pagination=submission_schemas.PaginationInfo(**pagination.dict()), + ) + return response \ No newline at end of file diff --git a/src/backend/app/submission/submission_schemas.py b/src/backend/app/submission/submission_schemas.py index b2b30015e2..c760b707c9 100644 --- a/src/backend/app/submission/submission_schemas.py +++ b/src/backend/app/submission/submission_schemas.py @@ -17,3 +17,22 @@ # """Pydantic models for data submissions.""" + +from typing import List, Optional, Union +from pydantic import BaseModel + +class PaginationInfo(BaseModel): + """Pagination JSON return.""" + has_next: bool + has_prev: bool + next_num: Optional[int] + page: int + pages: int + prev_num: Optional[int] + per_page: int + total: int + + +class PaginatedSubmissions(BaseModel): + results: List + pagination: PaginationInfo