Skip to content

Commit

Permalink
Merge pull request #6593 from hotosm/fastapi-refactor
Browse files Browse the repository at this point in the history
JSONResponse handling and cleanups
  • Loading branch information
prabinoid authored Oct 9, 2024
2 parents 4fda6e3 + 36d6c65 commit 683d2d3
Show file tree
Hide file tree
Showing 28 changed files with 463 additions and 326 deletions.
64 changes: 36 additions & 28 deletions backend/api/comments/resources.py
Original file line number Diff line number Diff line change
@@ -1,30 +1,31 @@
# from flask_restful import , request, current_app
# from schematics.exceptions import Exception

from datetime import datetime

from databases import Database
from fastapi import APIRouter, Depends, Request
from loguru import logger
from starlette.authentication import requires
from fastapi.responses import JSONResponse

from backend.db import get_db, get_session
from backend.models.dtos.mapping_dto import TaskCommentDTO
from backend.models.dtos.message_dto import ChatMessageDTO
from backend.models.dtos.user_dto import AuthUserDTO
from backend.models.dtos.mapping_dto import TaskCommentDTO
from backend.services.mapping_service import MappingService, MappingServiceError
from backend.services.messaging.chat_service import ChatService
from backend.services.users.user_service import UserService
from backend.services.project_service import ProjectService
from backend.services.mapping_service import MappingService, MappingServiceError
from backend.services.users.authentication_service import tm
from backend.services.users.authentication_service import login_required
from fastapi import APIRouter, Depends, Request
from backend.db import get_session
from starlette.authentication import requires
from loguru import logger
from databases import Database
from backend.db import get_db
from datetime import datetime
from backend.services.users.authentication_service import login_required, tm
from backend.services.users.user_service import UserService

session = get_session()


router = APIRouter(
prefix="/projects",
tags=["projects"],
dependencies=[Depends(get_session)],
dependencies=[Depends(get_db)],
responses={404: {"description": "Not found"}},
)

Expand Down Expand Up @@ -75,7 +76,10 @@ async def post(
"""
user = await UserService.get_user_by_id(user.id, db)
if await UserService.is_user_blocked(user.id, db):
return {"Error": "User is on read only mode", "SubCode": "ReadOnly"}, 403
return JSONResponse(
content={"Error": "User is on read only mode", "SubCode": "ReadOnly"},
status_code=403,
)

request_json = await request.json()
message = request_json.get("message")
Expand All @@ -87,12 +91,16 @@ async def post(
username=user.username,
)
try:
project_messages = await ChatService.post_message(
chat_dto, project_id, user.id, db
)
return project_messages
async with db.transaction():
project_messages = await ChatService.post_message(
chat_dto, project_id, user.id, db
)
return project_messages
except ValueError as e:
return {"Error": str(e).split("-")[1], "SubCode": str(e).split("-")[0]}, 403
return JSONResponse(
content={"Error": str(e).split("-")[1], "SubCode": str(e).split("-")[0]},
status_code=403,
)


@router.get("/{project_id}/comments/")
Expand Down Expand Up @@ -138,8 +146,6 @@ async def get(request: Request, project_id: int, db: Database = Depends(get_db))
return project_messages


# class CommentsProjectsRestAPI():
# @token_auth.login_required
@router.delete("/{project_id}/comments/{comment_id}/")
async def delete(
project_id: int,
Expand Down Expand Up @@ -185,16 +191,18 @@ async def delete(
"""
authenticated_user_id = user.id
try:
await ChatService.delete_project_chat_by_id(
project_id, comment_id, authenticated_user_id, db
)
return {"Success": "Comment deleted"}, 200
async with db.transaction():
await ChatService.delete_project_chat_by_id(
project_id, comment_id, authenticated_user_id, db
)
return JSONResponse(content={"Success": "Comment deleted"}, status_code=200)
except ValueError as e:
return {"Error": str(e).split("-")[1], "SubCode": str(e).split("-")[0]}, 403
return JSONResponse(
content={"Error": str(e).split("-")[1], "SubCode": str(e).split("-")[0]},
status_code=403,
)


# class CommentsTasksRestAPI():
# @token_auth.login_required
@router.post("/{project_id}/comments/tasks/{task_id}/")
@requires("authenticated")
@tm.pm_only(False)
Expand Down
41 changes: 24 additions & 17 deletions backend/api/interests/resources.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
from asyncpg.exceptions import UniqueViolationError
from databases import Database
from fastapi import APIRouter, Depends
from fastapi.responses import JSONResponse

from backend.db import get_db
from backend.models.dtos.interests_dto import InterestDTO
from backend.models.dtos.user_dto import AuthUserDTO
from backend.services.interests_service import InterestService
from backend.services.organisation_service import OrganisationService
from backend.services.users.authentication_service import login_required

from fastapi import APIRouter, Depends
from backend.db import get_session
from backend.models.dtos.user_dto import AuthUserDTO
from databases import Database
from backend.db import get_db
from asyncpg.exceptions import UniqueViolationError


router = APIRouter(
prefix="/interests",
tags=["interests"],
dependencies=[Depends(get_session)],
dependencies=[Depends(get_db)],
responses={404: {"description": "Not found"}},
)

Expand Down Expand Up @@ -70,19 +69,21 @@ async def post(
raise ValueError("User not a Org Manager")
except ValueError as e:
error_msg = f"InterestsAllAPI POST: {str(e)}"
return {"Error": error_msg, "SubCode": "UserNotPermitted"}, 403
return JSONResponse(
content={"Error": error_msg, "SubCode": "UserNotPermitted"}, status_code=403
)

try:
new_interest_dto = await InterestService.create(interest_dto.name, db)
return new_interest_dto

except UniqueViolationError:
return (
{
return JSONResponse(
content={
"Error": "Value '{0}' already exists".format(interest_dto.name),
"SubCode": "NameExists",
},
400,
status_code=400,
)


Expand Down Expand Up @@ -153,7 +154,9 @@ async def get(
raise ValueError("User not a Org Manager")
except ValueError as e:
error_msg = f"InterestsRestAPI GET: {str(e)}"
return {"Error": error_msg, "SubCode": "UserNotPermitted"}, 403
return JSONResponse(
content={"Error": error_msg, "SubCode": "UserNotPermitted"}, status_code=403
)

interest_dto = await InterestService.get(interest_id, db)
return interest_dto
Expand Down Expand Up @@ -217,7 +220,9 @@ async def patch(
raise ValueError("User not a Org Manager")
except ValueError as e:
error_msg = f"InterestsRestAPI PATCH: {str(e)}"
return {"Error": error_msg, "SubCode": "UserNotPermitted"}, 403
return JSONResponse(
content={"Error": error_msg, "SubCode": "UserNotPermitted"}, status_code=403
)

update_interest = await InterestService.update(interest_id, interest_dto, db)
return update_interest
Expand Down Expand Up @@ -269,7 +274,9 @@ async def delete(
raise ValueError("User not a Org Manager")
except ValueError as e:
error_msg = f"InterestsRestAPI DELETE: {str(e)}"
return {"Error": error_msg, "SubCode": "UserNotPermitted"}, 403
return JSONResponse(
content={"Error": error_msg, "SubCode": "UserNotPermitted"}, status_code=403
)

await InterestService.delete(interest_id, db)
return {"Success": "Interest deleted"}, 200
return JSONResponse(content={"Success": "Interest deleted"}, status_code=200)
3 changes: 1 addition & 2 deletions backend/api/issues/resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,14 @@

from backend.models.dtos.mapping_issues_dto import MappingIssueCategoryDTO
from backend.services.mapping_issues_service import MappingIssueCategoryService
from backend.db import get_session
from backend.db import get_db
from backend.models.dtos.user_dto import AuthUserDTO
from backend.services.users.authentication_service import login_required

router = APIRouter(
prefix="/tasks",
tags=["issues"],
dependencies=[Depends(get_session)],
dependencies=[Depends(get_db)],
responses={404: {"description": "Not found"}},
)

Expand Down
19 changes: 8 additions & 11 deletions backend/api/licenses/actions.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,21 @@
from backend.services.users.user_service import UserService
from backend.services.users.authentication_service import login_required
from fastapi import APIRouter, Depends, Request
from backend.db import get_session
from starlette.authentication import requires
from backend.models.dtos.user_dto import AuthUserDTO
from databases import Database
from fastapi import APIRouter, Depends, Request
from fastapi.responses import JSONResponse

from backend.db import get_db
from backend.models.dtos.user_dto import AuthUserDTO
from backend.services.users.authentication_service import login_required
from backend.services.users.user_service import UserService

router = APIRouter(
prefix="/licenses",
tags=["licenses"],
dependencies=[Depends(get_session)],
dependencies=[Depends(get_db)],
responses={404: {"description": "Not found"}},
)


# class LicensesActionsAcceptAPI(Resource):
# @token_auth.login_required
@router.post("/{license_id}/actions/accept-for-me/")
@requires("authenticated")
async def post(
request: Request,
license_id: int,
Expand Down Expand Up @@ -56,4 +53,4 @@ async def post(
description: Internal Server Error
"""
await UserService.accept_license_terms(user.id, license_id, db)
return {"Success": "Terms Accepted"}, 200
return JSONResponse(content={"Success": "Terms Accepted"}, status_code=200)
18 changes: 9 additions & 9 deletions backend/api/licenses/resources.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
from backend.models.dtos.licenses_dto import LicenseDTO
from backend.services.license_service import LicenseService
from fastapi import APIRouter, Depends
from backend.db import get_session
from databases import Database
from backend.db import get_db
from fastapi import APIRouter, Depends
from fastapi.responses import JSONResponse

from backend.db import get_db
from backend.models.dtos.licenses_dto import LicenseDTO
from backend.services.license_service import LicenseService

router = APIRouter(
prefix="/licenses",
tags=["licenses"],
dependencies=[Depends(get_session)],
dependencies=[Depends(get_db)],
responses={404: {"description": "Not found"}},
)

Expand Down Expand Up @@ -59,7 +59,7 @@ async def post(license_dto: LicenseDTO, db: Database = Depends(get_db)):
description: Internal Server Error
"""
new_license_id = await LicenseService.create_license(license_dto, db)
return {"licenseId": new_license_id}, 201
return JSONResponse(content={"licenseId": new_license_id}, status_code=201)


@router.get("/{license_id}/")
Expand Down Expand Up @@ -145,7 +145,7 @@ async def patch(
description: Internal Server Error
"""
await LicenseService.update_license(license_dto, license_id, db)
return {"status": "Updated"}, 200
return JSONResponse(content={"status": "Updated"}, status_code=200)


@router.delete("/{license_id}/")
Expand Down Expand Up @@ -183,7 +183,7 @@ async def delete(license_id: int, db: Database = Depends(get_db)):
description: Internal Server Error
"""
await LicenseService.delete_license(license_id, db)
return {"Success": "License deleted"}, 200
return JSONResponse(content={"Success": "License deleted"}, status_code=200)


@router.get("/")
Expand Down
20 changes: 11 additions & 9 deletions backend/api/notifications/actions.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
from databases import Database
from fastapi import APIRouter, Depends, Request
from fastapi.responses import JSONResponse

from backend.db import get_db, get_session
from backend.db import get_db
from backend.models.dtos.user_dto import AuthUserDTO
from backend.services.messaging.message_service import MessageService
from backend.services.users.authentication_service import login_required

router = APIRouter(
prefix="/notifications",
tags=["notifications"],
dependencies=[Depends(get_session)],
dependencies=[Depends(get_db)],
responses={404: {"description": "Not found"}},
)

Expand Down Expand Up @@ -53,9 +54,9 @@ async def delete(
data = await request.json()
message_ids = data["messageIds"]
if message_ids:
await MessageService.delete_multiple_messages(message_ids, user.id, db)

return {"Success": "Messages deleted"}, 200
async with db.transaction():
await MessageService.delete_multiple_messages(message_ids, user.id, db)
return JSONResponse(content={"Success": "Messages deleted"}, status_code=200)


@router.delete("/delete-all/")
Expand Down Expand Up @@ -89,8 +90,9 @@ async def delete(
description: Internal Server Error
"""
message_type = request.query_params.get("messageType")
await MessageService.delete_all_messages(user.id, db, message_type)
return {"Success": "Messages deleted"}, 200
async with db.transaction():
await MessageService.delete_all_messages(user.id, db, message_type)
return JSONResponse(content={"Success": "Messages deleted"}, status_code=200)


@router.post("/mark-as-read-all/")
Expand Down Expand Up @@ -125,7 +127,7 @@ async def post(
"""
message_type = request.query_params.get("messageType")
await MessageService.mark_all_messages_read(user.id, db, message_type)
return {"Success": "Messages marked as read"}, 200
return JSONResponse(content={"Success": "Messages marked as read"}, status_code=200)


@router.post("/mark-as-read-multiple/")
Expand Down Expand Up @@ -169,4 +171,4 @@ async def post(
if message_ids:
await MessageService.mark_multiple_messages_read(message_ids, user.id, db)

return {"Success": "Messages marked as read"}, 200
return JSONResponse(content={"Success": "Messages marked as read"}, status_code=200)
Loading

0 comments on commit 683d2d3

Please sign in to comment.