Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,4 @@ ignore = ["E501", "F401", "N806"]

[tool.pyright]
executionEnvironments = [{ root = "src" }]
typeCheckingMode = "standard"
typeCheckingMode = "basic"
21 changes: 21 additions & 0 deletions src/nominees/crud.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
from collections.abc import Sequence

import sqlalchemy
from sqlalchemy.ext.asyncio import AsyncSession

from nominees.tables import NomineeInfo


async def get_all_nominees(
db_session: AsyncSession,
) -> Sequence[NomineeInfo]:
nominees = (await db_session.scalars(
sqlalchemy
.select(NomineeInfo)
)).all()
return nominees

async def get_nominee_info(
db_session: AsyncSession,
computing_id: str,
Expand All @@ -30,3 +41,13 @@ async def update_nominee_info(
.where(NomineeInfo.computing_id == info.computing_id)
.values(info.to_update_dict())
)

async def delete_nominee_info(
db_session: AsyncSession,
computing_id: str,
):
await db_session.execute(
sqlalchemy
.delete(NomineeInfo)
.where(NomineeInfo.computing_id == computing_id)
)
94 changes: 68 additions & 26 deletions src/nominees/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,52 +8,96 @@
NomineeInfoUpdateParams,
)
from nominees.tables import NomineeInfo
from utils.shared_models import DetailModel
from utils.urls import AdminTypeEnum, admin_or_raise

router = APIRouter(
prefix="/nominee",
tags=["nominee"],
)


@router.get(
"/{computing_id:str}",
description="Nominee info is always publically tied to election, so be careful!",
response_model=NomineeInfoModel,
responses={
404: { "description": "nominee doesn't exist" }
},
operation_id="get_nominee"
"",
description="Get all nominees",
response_model=list[NomineeInfoModel],
responses={403: {"description": "need to be an admin", "model": DetailModel}},
operation_id="get_all_nominees",
)
async def get_nominee_info(
async def get_all_nominees(
request: Request,
db_session: database.DBSession,
computing_id: str
):
# Putting this behind a wall since there is private information here
await admin_or_raise(request, db_session)
nominees_list = await nominees.crud.get_all_nominees(db_session)

return JSONResponse([item.serialize() for item in nominees_list])


@router.post(
"",
description="Nominee info is always publically tied to election, so be careful!",
response_model=NomineeInfoModel,
responses={500: {"description": "failed to fetch new nominee", "model": DetailModel}},
operation_id="create_nominee",
)
async def create_nominee(request: Request, db_session: database.DBSession, body: NomineeInfoModel):
await admin_or_raise(request, db_session)
await nominees.crud.create_nominee_info(
db_session,
NomineeInfo(
computing_id=body.computing_id,
full_name=body.full_name,
linked_in=body.linked_in,
instagram=body.instagram,
email=body.email,
discord_username=body.discord_username,
),
)

nominee_info = await nominees.crud.get_nominee_info(db_session, body.computing_id)
if nominee_info is None:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="couldn't fetch newly created nominee"
)

return JSONResponse(nominee_info)


@router.get(
"/{computing_id:str}",
description="Nominee info is always publically tied to election, so be careful!",
response_model=NomineeInfoModel,
responses={404: {"description": "nominee doesn't exist"}},
operation_id="get_nominee",
)
async def get_nominee_info(request: Request, db_session: database.DBSession, computing_id: str):
# Putting this one behind the admin wall since it has contact information
await admin_or_raise(request, db_session, AdminTypeEnum.Election)
nominee_info = await nominees.crud.get_nominee_info(db_session, computing_id)
if nominee_info is None:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="nominee doesn't exist"
)
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="nominee doesn't exist")

return JSONResponse(nominee_info.serialize())


@router.delete("/{computing_id:str}", description="Delete a nominee", operation_id="delete_nominee")
async def delete_nominee_info(request: Request, db_session: database.DBSession, computing_id: str):
await admin_or_raise(request, db_session)
await nominees.crud.delete_nominee_info(db_session, computing_id)
await db_session.commit()


@router.patch(
"/{computing_id:str}",
description="Will create or update nominee info. Returns an updated copy of their nominee info.",
response_model=NomineeInfoModel,
responses={
500: { "description": "Failed to retrieve updated nominee." }
},
operation_id="update_nominee"
responses={500: {"description": "Failed to retrieve updated nominee."}},
operation_id="update_nominee",
)
async def provide_nominee_info(
request: Request,
db_session: database.DBSession,
body: NomineeInfoUpdateParams,
computing_id: str
request: Request, db_session: database.DBSession, body: NomineeInfoUpdateParams, computing_id: str
):
# TODO: There needs to be a lot more validation here.
await admin_or_raise(request, db_session, AdminTypeEnum.Election)
Expand All @@ -63,14 +107,15 @@ async def provide_nominee_info(
if body.full_name is not None:
updated_data["full_name"] = body.full_name
if body.linked_in is not None:
updated_data["linked_in"] = body.linked_in
updated_data["linked_in"] = body.linked_in
if body.instagram is not None:
updated_data["instagram"] = body.instagram
if body.email is not None:
updated_data["email"] = body.email
if body.discord_username is not None:
updated_data["discord_username"] = body.discord_username

# TODO: Look into using something built into SQLAlchemy/Pydantic for better entry updates
existing_info = await nominees.crud.get_nominee_info(db_session, computing_id)
# if not already existing, create it
if not existing_info:
Expand All @@ -97,8 +142,5 @@ async def provide_nominee_info(

nominee_info = await nominees.crud.get_nominee_info(db_session, computing_id)
if not nominee_info:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="failed to get updated nominee"
)
raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="failed to get updated nominee")
return JSONResponse(nominee_info.serialize())
Loading