Change admin methods, Add /status, Add descriptions

This commit is contained in:
Kai Vogelgesang 2022-10-04 14:32:04 +02:00
parent 83294ac7c9
commit 69dc4a3d56
Signed by: kai
GPG Key ID: 0A95D3B6E62C0879

View File

@ -7,7 +7,26 @@ from .settings import settings
db = client["party"] db = client["party"]
app = FastAPI() description = """
Party party \U0001F973
"""
tags_metadata = [
{
"name": "guests",
"description": "Operations with guests (i.e., users). Intended to be called from the respective party frontend.",
},
{
"name": "admin",
"description": "Operations for administrative purposes. Require the **admin token**. Intended to be called from the admin UI",
},
]
app = FastAPI(
title="PartyPage Manager",
description=description,
openapi_tags=tags_metadata,
)
Coming = Literal["yes", "no", "maybe"] Coming = Literal["yes", "no", "maybe"]
GrammaticalGender = Literal["m", "f", "d"] GrammaticalGender = Literal["m", "f", "d"]
@ -30,7 +49,7 @@ async def find_guest(party: str, token: str) -> Guest:
# Guest methods # Guest methods
@app.get("/{party}/{token}/me", response_model=Guest) @app.get("/{party}/{token}/me", response_model=Guest, tags=["guests"])
async def get_self(guest: Guest = Depends(find_guest)): async def get_self(guest: Guest = Depends(find_guest)):
return guest return guest
@ -39,7 +58,7 @@ class GuestUpdate(BaseModel):
coming: Coming coming: Coming
@app.patch("/{party}/{token}/update") @app.patch("/{party}/{token}/update", tags=["guests"])
async def update_self( async def update_self(
party: str, update: GuestUpdate, guest: Guest = Depends(find_guest) party: str, update: GuestUpdate, guest: Guest = Depends(find_guest)
): ):
@ -48,6 +67,22 @@ async def update_self(
await db[party].replace_one({"_id": guest.id}, guest_dict) await db[party].replace_one({"_id": guest.id}, guest_dict)
class PartyStatus(BaseModel):
definitely_coming: int
maybe_coming: int
@app.get("/{party}/{token}/status", response_model=PartyStatus, tags=["guests"])
async def get_party_status(party: str, _=Depends(find_guest)):
definitely_coming = await db[party].count_documents({"coming": "yes"})
maybe_coming = await db[party].count_documents({"coming": "maybe"})
return {
"definitely_coming": definitely_coming,
"maybe_coming": maybe_coming,
}
# Admin methods # Admin methods
@ -56,32 +91,47 @@ async def auth_admin(admin_token: str):
raise HTTPException(status.HTTP_401_UNAUTHORIZED) raise HTTPException(status.HTTP_401_UNAUTHORIZED)
@app.get("/{party}/{admin_token}/list", response_model=list[Guest]) @app.get("/{party}/{admin_token}/list", response_model=list[Guest], tags=["admin"])
async def list_guests(party: str, _=Depends(auth_admin)): async def list_guests(party: str, _=Depends(auth_admin)):
return await db[party].find().to_list(None) return await db[party].find().to_list(None)
class GuestSet(BaseModel): class GuestCreate(BaseModel):
token: str token: str
name: str name: str
coming: Coming | None coming: Coming | None
grammatical_gender: GrammaticalGender grammatical_gender: GrammaticalGender
@app.put("/{party}/{admin_token}/set", response_model=Guest) @app.put("/{party}/{admin_token}/new", response_model=Guest, tags=["admin"])
async def edit_or_create_new_guest( async def create_new_guest(party: str, new_guest: GuestCreate, _=Depends(auth_admin)):
party: str, guest_set: GuestSet, _=Depends(auth_admin) existing = await db[party].find_one({"token": new_guest.token})
):
existing = await db[party].find_one({"token": guest_set.token})
if existing: if existing:
# update the existing guest raise HTTPException(
existing.update(guest_set.dict()) status.HTTP_400_BAD_REQUEST, f"Token {new_guest.token!r} is already in use"
)
await db[party].replace_one({"_id": existing["_id"]}, existing) insert_result = await db[party].insert_one(new_guest.dict())
return await db[party].find_one({"_id": existing["_id"]}) inserted = await db[party].find_one({"_id": insert_result.inserted_id})
return inserted
else:
# create a new guest class GuestModify(MongoModel):
insert_result = await db[party].insert_one(guest_set.dict()) token: str | None
inserted = await db[party].find_one({"_id": insert_result.inserted_id}) name: str | None
return inserted coming: Coming | None
grammatical_gender: GrammaticalGender | None
@app.patch("/{party}/{admin_token}/modify", response_model=Guest, tags=["admin"])
async def modify_guest(party: str, modified_guest: GuestModify, _=Depends(auth_admin)):
existing = await db[party].find_one({"_id": modified_guest.id})
if not existing:
raise HTTPException(status.HTTP_404_NOT_FOUND)
print(modified_guest.dict())
print(modified_guest.dict(exclude={"id"}, exclude_unset=True))
existing.update(modified_guest.dict(exclude={"id"}, exclude_unset=True))
await db[party].replace_one({"_id": existing["_id"]}, existing)
return await db[party].find_one({"_id": existing["_id"]})