Skip to content

Commit

Permalink
Merge pull request #6553 from hotosm/fastapi-refactor
Browse files Browse the repository at this point in the history
Fastapi refactor
  • Loading branch information
prabinoid committed Sep 4, 2024
2 parents ab1fd97 + 253761c commit ebd2d98
Show file tree
Hide file tree
Showing 11 changed files with 456 additions and 365 deletions.
23 changes: 11 additions & 12 deletions backend/api/projects/activities.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
from fastapi import APIRouter, Depends, Request
from backend.services.stats_service import StatsService
from backend.services.project_service import ProjectService
from backend.db import get_session

from backend.db import get_db, get_session
from databases import Database
from fastapi import HTTPException


router = APIRouter(
Expand All @@ -12,9 +13,8 @@
responses={404: {"description": "Not found"}},
)

# class ProjectsActivitiesAPI(Resource):
@router.get("/{project_id}/activities/")
async def get(request: Request, project_id):
async def get(request: Request, project_id: int, db: Database = Depends(get_db)):
"""
Get all user activity on a project
---
Expand All @@ -41,15 +41,14 @@ async def get(request: Request, project_id):
500:
description: Internal Server Error
"""
ProjectService.exists(project_id)
await ProjectService.exists(project_id, db)
page = int(request.query_params.get("page")) if request.query_params.get("page") else 1
activity = StatsService.get_latest_activity(project_id, page)
return activity.model_dump(by_alias=True), 200
activity = await StatsService.get_latest_activity(project_id, page, db)
return activity


# class ProjectsLastActivitiesAPI(Resource):
@router.get("/{project_id}/activities/latest/")
async def get(request: Request, project_id):
async def get(request: Request, project_id: int, db: Database = Depends(get_db)):
"""
Get latest user activity on all of project task
---
Expand All @@ -71,6 +70,6 @@ async def get(request: Request, project_id):
500:
description: Internal Server Error
"""
ProjectService.exists(project_id)
activity = StatsService.get_last_activity(project_id)
return activity.model_dump(by_alias=True), 200
await ProjectService.exists(project_id, db)
activity = await StatsService.get_last_activity(project_id, db)
return activity
19 changes: 10 additions & 9 deletions backend/api/projects/contributions.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
# from flask_restful import Resource

from backend.models.postgis.project import Project
from backend.services.project_service import ProjectService
from backend.services.stats_service import StatsService
from fastapi import APIRouter, Depends
from backend.db import get_session
from backend.db import get_db
from databases import Database

router = APIRouter(
prefix="/projects",
Expand All @@ -12,9 +15,8 @@
responses={404: {"description": "Not found"}},
)

# class ProjectsContributionsAPI(Resource):
@router.get("/{project_id}/contributions/")
async def get(project_id):
async def get(project_id: int, db: Database = Depends(get_db)):
"""
Get all user contributions on a project
---
Expand All @@ -37,14 +39,13 @@ async def get(project_id):
500:
description: Internal Server Error
"""
ProjectService.exists(project_id)
contributions = StatsService.get_user_contributions(project_id)
return contributions.model_dump(by_alias=True), 200
await Project.exists(project_id, db)
contributions = await StatsService.get_user_contributions(project_id, db)
return contributions


# class ProjectsContributionsQueriesDayAPI(Resource):
@router.get("/{project_id}/contributions/queries/day/")
async def get(project_id):
async def get(project_id: int, db: Database = Depends(get_db)):
"""
Get contributions by day for a project
---
Expand All @@ -67,5 +68,5 @@ async def get(project_id):
500:
description: Internal Server Error
"""
contribs = ProjectService.get_contribs_by_day(project_id)
return contribs.model_dump(by_alias=True), 200
contribs = await ProjectService.get_contribs_by_day(project_id, db)
return contribs
40 changes: 19 additions & 21 deletions backend/api/projects/resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
from starlette.authentication import requires
import json
from sqlalchemy.ext.asyncio import AsyncSession

from backend.db import get_db
from databases import Database
from backend.services.users.authentication_service import login_required
Expand Down Expand Up @@ -920,7 +921,7 @@ async def get(request: Request, project_id: int, db: Database = Depends(get_db))


@router.get("/{project_id}/queries/nogeometries/")
async def get(request: Request, project_id):
async def get(request: Request, project_id: int, db: Database = Depends(get_db)):
"""
Get HOT Project for mapping
---
Expand Down Expand Up @@ -963,11 +964,10 @@ async def get(request: Request, project_id):
else False
)
locale = request.headers.get("accept-language")
project_dto = ProjectService.get_project_dto_for_mapper(
project_id, None, locale, True
project_dto = await ProjectService.get_project_dto_for_mapper(
project_id, None, db, locale, True
)
project_dto = project_dto.model_dump(by_alias=True)

#TODO Send file.
if as_file:
return send_file(
io.BytesIO(geojson.dumps(project_dto).encode("utf-8")),
Expand All @@ -976,7 +976,7 @@ async def get(request: Request, project_id):
download_name=f"project_{str(project_id)}.json",
)

return project_dto, 200
return project_dto
except ProjectServiceError as e:
return {"Error": str(e).split("-")[1], "SubCode": str(e).split("-")[0]}, 403
finally:
Expand All @@ -988,8 +988,7 @@ async def get(request: Request, project_id):


@router.get("/{project_id}/queries/notasks/")
@requires("authenticated")
async def get(request: Request, project_id):
async def get(request: Request, project_id: int, db: Database = Depends(get_db), user: AuthUserDTO = Depends(login_required)):
"""
Retrieves a Tasking-Manager project
---
Expand Down Expand Up @@ -1022,21 +1021,20 @@ async def get(request: Request, project_id):
500:
description: Internal Server Error
"""
if not ProjectAdminService.is_user_action_permitted_on_project(
request.user.display_name, project_id
if not await ProjectAdminService.is_user_action_permitted_on_project(
request.user.display_name, project_id, db
):
return {
"Error": "User is not a manager of the project",
"SubCode": "UserPermissionError",
}, 403

project_dto = ProjectAdminService.get_project_dto_for_admin(project_id)
return project_dto.model_dump(by_alias=True), 200
project_dto = await ProjectAdminService.get_project_dto_for_admin(project_id, db)
return project_dto


# class ProjectsQueriesAoiAPI():
@router.get("/{project_id}/queries/aoi/")
async def get(request: Request, project_id):
async def get(request: Request, project_id: int, db: Database = Depends(get_db)):
"""
Get AOI of Project
---
Expand Down Expand Up @@ -1069,11 +1067,11 @@ async def get(request: Request, project_id):
as_file = (
strtobool(request.query_params.get("as_file"))
if request.query_params.get("as_file")
else True
else False
)

project_aoi = ProjectService.get_project_aoi(project_id)

project_aoi = await ProjectService.get_project_aoi(project_id, db)
#TODO as file.
if as_file:
return send_file(
io.BytesIO(geojson.dumps(project_aoi).encode("utf-8")),
Expand All @@ -1082,11 +1080,11 @@ async def get(request: Request, project_id):
download_name=f"{str(project_id)}.geojson",
)

return project_aoi, 200
return project_aoi


@router.get("/{project_id}/queries/priority-areas/")
async def get(project_id):
async def get(project_id: int, db: Database = Depends(get_db)):
"""
Get Priority Areas of a project
---
Expand All @@ -1112,8 +1110,8 @@ async def get(project_id):
description: Internal Server Error
"""
try:
priority_areas = ProjectService.get_project_priority_areas(project_id)
return priority_areas, 200
priority_areas = await ProjectService.get_project_priority_areas(project_id, db)
return priority_areas
except ProjectServiceError:
return {"Error": "Unable to fetch project"}, 403

Expand Down
2 changes: 0 additions & 2 deletions backend/api/projects/statistics.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
responses={404: {"description": "Not found"}},
)

# class ProjectsStatisticsQueriesPopularAPI(Resource):
@router.get("/queries/popular/")
async def get():
"""
Expand All @@ -32,7 +31,6 @@ async def get():
return stats.model_dump(by_alias=True), 200


# class ProjectsStatisticsAPI(Resource):
@router.get("/{project_id}/statistics/")
async def get(project_id: int, session: AsyncSession = Depends(get_session)):
"""
Expand Down
14 changes: 7 additions & 7 deletions backend/models/dtos/mapping_dto.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,29 +53,29 @@ class TaskHistoryDTO(BaseModel):
"""Describes an individual action that was performed on a mapping task"""

history_id : Optional[int] = Field(alias="historyId", default=None)
task_id: Optional[str] = Field(alias="taskId", default=None)
task_id: Optional[int] = Field(alias="taskId", default=None)
action: Optional[str] = None
action_text: Optional[str] = Field(alias="actionText", default=None)
action_date: datetime = Field(alias="actionDate", default=None)
action_by: Optional[str] = Field(alias="actionBy", default=None)
picture_url: Optional[str] = Field(alias="pictureUrl", default=None)
issues: Optional[List[TaskMappingIssueDTO]] = None

class Config:
populate_by_name = True


class TaskStatusDTO(BaseModel):
"""Describes a DTO for the current status of the task"""
def __init__(self, task_status, **data):
super().__init__(**data)
self.task_id = task_status["task_id"]
self.task_status = task_status["task_status"]
self.action_date = task_status["action_date"]
self.action_by = task_status["action_by"]

task_id: Optional[int] = Field(alias="taskId", default=None)
task_status: Optional[str] = Field(alias="taskStatus", default=None)
action_date: Optional[datetime] = Field(alias="actionDate", default=None)
action_by: Optional[str] = Field(alias="actionBy", default=None)

class Config:
populate_by_name = True


class TaskDTO(BaseModel):
"""Describes a Task DTO"""
Expand Down
Loading

0 comments on commit ebd2d98

Please sign in to comment.