Skip to content

Commit

Permalink
Merge pull request #6545 from hotosm/fastapi-refactor
Browse files Browse the repository at this point in the history
Fastapi refactor
  • Loading branch information
prabinoid committed Aug 27, 2024
2 parents 943be57 + ba31c95 commit 11dc0cd
Show file tree
Hide file tree
Showing 8 changed files with 737 additions and 325 deletions.
88 changes: 49 additions & 39 deletions backend/api/interests/resources.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
from backend.models.dtos.interests_dto import InterestDTO
from backend.services.interests_service import InterestService
from backend.services.organisation_service import OrganisationService
from backend.services.users.authentication_service import login_required

from sqlalchemy.exc import IntegrityError
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 backend.db import get_db
from loguru import logger
from asyncpg.exceptions import UniqueViolationError


router = APIRouter(
prefix="/interests",
Expand All @@ -17,9 +23,13 @@

INTEREST_NOT_FOUND = "Interest Not Found"


@router.post("/")
@requires("authenticated")
async def post(request: Request):
async def post(
interest_dto: InterestDTO,
db: Database = Depends(get_db),
user: AuthUserDTO = Depends(login_required),
):
"""
Creates a new interest
---
Expand Down Expand Up @@ -56,8 +66,8 @@ async def post(request: Request):
description: Internal Server Error
"""
try:
orgs_dto = OrganisationService.get_organisations_managed_by_user_as_dto(
request.user.display_name
orgs_dto = await OrganisationService.get_organisations_managed_by_user_as_dto(
user_id=user.id, db=db
)
if len(orgs_dto.organisations) < 1:
raise ValueError("User not a Org Manager")
Expand All @@ -66,16 +76,10 @@ async def post(request: Request):
return {"Error": error_msg, "SubCode": "UserNotPermitted"}, 403

try:
interest_dto = InterestDTO(request.get_json())
interest_dto.validate()
except Exception as e:
logger.error(f"Error validating request: {str(e)}")
return {"Error": str(e), "SubCode": "InvalidData"}, 400
new_interest_dto = await InterestService.create(interest_dto.name, db)
return new_interest_dto

try:
new_interest = InterestService.create(interest_dto.name)
return new_interest.model_dump(by_alias=True), 200
except IntegrityError:
except UniqueViolationError:
return (
{
"Error": "Value '{0}' already exists".format(interest_dto.name),
Expand All @@ -84,8 +88,9 @@ async def post(request: Request):
400,
)


@router.get("/")
async def get():
async def get(db: Database = Depends(get_db)):
"""
Get all interests
---
Expand All @@ -99,13 +104,16 @@ async def get():
500:
description: Internal Server Error
"""
interests = InterestService.get_all_interests()
return interests.model_dump(by_alias=True), 200
interests_dto = await InterestService.get_all_interests(db)
return interests_dto


@router.get("/{interest_id}/")
@requires("authenticated")
async def get(request: Request, interest_id: int):
async def get(
interest_id: int,
db: Database = Depends(get_db),
user: AuthUserDTO = Depends(login_required),
):
"""
Get an existing interest
---
Expand Down Expand Up @@ -141,21 +149,26 @@ async def get(request: Request, interest_id: int):
description: Internal Server Error
"""
try:
orgs_dto = OrganisationService.get_organisations_managed_by_user_as_dto(
request.user.display_name
orgs_dto = await OrganisationService.get_organisations_managed_by_user_as_dto(
user_id=user.id, db=db
)
if len(orgs_dto.organisations) < 1:
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

interest = InterestService.get(interest_id)
return interest.model_dump(by_alias=True), 200
interest_dto = await InterestService.get(interest_id, db)
return interest_dto


@router.patch("/{interest_id}/")
@requires("authenticated")
async def patch(request: Request, interest_id):
async def patch(
interest_id: int,
interest_dto: InterestDTO,
db: Database = Depends(get_db),
user: AuthUserDTO = Depends(login_required),
):
"""
Update an existing interest
---
Expand Down Expand Up @@ -200,28 +213,25 @@ async def patch(request: Request, interest_id):
description: Internal Server Error
"""
try:
orgs_dto = OrganisationService.get_organisations_managed_by_user_as_dto(
request.user.display_name
orgs_dto = await OrganisationService.get_organisations_managed_by_user_as_dto(
user_id=user.id, db=db
)
if len(orgs_dto.organisations) < 1:
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

try:
interest_dto = InterestDTO(request.json())
interest_dto.validate()
except Exception as e:
logger.error(f"Error validating request: {str(e)}")
return {"Error": str(e), "SubCode": "InvalidData"}, 400
update_interest = await InterestService.update(interest_id, interest_dto, db)
return update_interest

update_interest = InterestService.update(interest_id, interest_dto)
return update_interest.model_dump(by_alias=True), 200

@router.delete("/{interest_id}/")
@requires("authenticated")
async def delete(request: Request, interest_id: int):
async def delete(
interest_id: int,
db: Database = Depends(get_db),
user: AuthUserDTO = Depends(login_required),
):
"""
Delete a specified interest
---
Expand Down Expand Up @@ -255,14 +265,14 @@ async def delete(request: Request, interest_id: int):
description: Internal Server Error
"""
try:
orgs_dto = OrganisationService.get_organisations_managed_by_user_as_dto(
request.user.display_name
orgs_dto = await OrganisationService.get_organisations_managed_by_user_as_dto(
user_id=user.id, db=db
)
if len(orgs_dto.organisations) < 1:
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

InterestService.delete(interest_id)
await InterestService.delete(interest_id, db)
return {"Success": "Interest deleted"}, 200
4 changes: 0 additions & 4 deletions backend/api/organisations/resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,9 @@
from backend.services.users.authentication_service import login_required
from fastapi import APIRouter, Depends, Request, Query
from backend.db import get_db
from starlette.authentication import requires
from loguru import logger
from sqlalchemy.ext.asyncio import AsyncSession

from databases import Database
from backend.models.postgis.organisation import Organisation
from sqlalchemy import select, case
from fastapi import HTTPException


Expand Down
32 changes: 19 additions & 13 deletions backend/api/teams/resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,18 @@
)
from backend.services.team_service import TeamService, TeamServiceError
from backend.services.organisation_service import OrganisationService
from backend.services.users.authentication_service import login_required
from backend.services.users.user_service import UserService
from backend.models.dtos.user_dto import AuthUserDTO
from distutils.util import strtobool
from fastapi import APIRouter, Depends, Request
from backend.db import get_session
from backend.db import get_db, get_session
from starlette.authentication import requires
from loguru import logger
from sqlalchemy.ext.asyncio import AsyncSession
from databases import Database
from fastapi import HTTPException


router = APIRouter(
prefix="/teams",
Expand All @@ -22,6 +27,8 @@

# class TeamsRestAPI(Resource):
# @token_auth.login_required


@router.patch("/{team_id}/")
@requires("authenticated")
async def patch(request: Request, team_id: int):
Expand Down Expand Up @@ -109,8 +116,9 @@ async def patch(request: Request, team_id: int):
except TeamServiceError as e:
return str(e), 402


@router.get("/{team_id}/")
async def get(request: Request, team_id):
async def retrieve_team(request: Request, team_id: int, db: Database = Depends(get_db)):
"""
Retrieves a Team
---
Expand Down Expand Up @@ -146,11 +154,12 @@ async def get(request: Request, team_id):
user_id = 0
else:
user_id = authenticated_user_id
team_dto = TeamService.get_team_as_dto(team_id, user_id, omit_members)
return team_dto.model_dump(by_alias=True), 200
team_dto = await TeamService.get_team_as_dto(team_id, user_id, omit_members, db)
return team_dto

# TODO: Add delete API then do front end services and ui work


@router.delete("/{team_id}/")
@requires("authenticated")
async def delete(request: Request, team_id: int):
Expand Down Expand Up @@ -195,11 +204,8 @@ async def delete(request: Request, team_id: int):
return TeamService.delete_team(team_id)


# class TeamsAllAPI(Resource):
# @token_auth.login_required
@router.get("/")
@requires("authenticated")
async def get(request: Request, session: AsyncSession):
async def list_teams(request: Request, db: Database = Depends(get_db), user: AuthUserDTO = Depends(login_required)):
"""
Gets all teams
---
Expand Down Expand Up @@ -288,20 +294,20 @@ async def get(request: Request, session: AsyncSession):
search_dto.member_request = request.query_params.get("member_request", None)
search_dto.team_role = request.query_params.get("team_role", None)
search_dto.organisation = request.query_params.get("organisation", None)
search_dto.omit_member_list = strtobool(
search_dto.omit_members = strtobool(
request.query_params.get("omitMemberList", "false")
)
search_dto.full_member_list = strtobool(
search_dto.full_members_list = strtobool(
request.query_params.get("fullMemberList", "true")
)
search_dto.paginate = strtobool(request.query_params.get("paginate", "false"))
search_dto.page = request.query_params.get("page", 1)
search_dto.per_page = request.query_params.get("perPage", 10)
search_dto.user_id = user_id
search_dto.validate()

teams = await TeamService.get_all_teams(search_dto, session)
return teams.model_dump(by_alias=True), 200
teams = await TeamService.get_all_teams(search_dto, db)
return teams


@router.post("/")
@requires("authenticated")
Expand Down
Loading

0 comments on commit 11dc0cd

Please sign in to comment.