All checks were successful
Build Docker Image / build (pull_request) Successful in 3m38s
aiohttp follows 307 redirects but converts POST to GET, silently
dropping the request body. Standardize all @router.post('') to
@router.post('/') so the canonical URL always has a trailing slash,
preventing 307 redirects when clients POST with trailing slashes.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
179 lines
5.5 KiB
Python
179 lines
5.5 KiB
Python
from fastapi import APIRouter, Depends, HTTPException, Query
|
|
from typing import List, Optional
|
|
import logging
|
|
import pydantic
|
|
|
|
from ..db_engine import db, Manager, Team, Current, model_to_dict, fn
|
|
from ..dependencies import (
|
|
oauth2_scheme,
|
|
valid_token,
|
|
PRIVATE_IN_SCHEMA,
|
|
handle_db_errors,
|
|
)
|
|
|
|
logger = logging.getLogger("discord_app")
|
|
|
|
router = APIRouter(prefix="/api/v3/managers", tags=["managers"])
|
|
|
|
|
|
class ManagerModel(pydantic.BaseModel):
|
|
name: str
|
|
image: Optional[str] = None
|
|
headline: Optional[str] = None
|
|
bio: Optional[str] = None
|
|
|
|
|
|
@router.get("")
|
|
@handle_db_errors
|
|
async def get_managers(
|
|
name: list = Query(default=None),
|
|
active: Optional[bool] = None,
|
|
short_output: Optional[bool] = False,
|
|
):
|
|
if active is not None:
|
|
current = Current.latest()
|
|
t_query = Team.select_season(current.season)
|
|
t_query = t_query.where(
|
|
~(Team.abbrev.endswith("IL")) & ~(Team.abbrev.endswith("MiL"))
|
|
)
|
|
logger.info(f"tquery: {t_query}")
|
|
a_mgr = []
|
|
i_mgr = []
|
|
|
|
for x in t_query:
|
|
logger.info(f"Team: {x.abbrev} / mgr1: {x.manager1} / mgr2: {x.manager2}")
|
|
if x.manager1 is not None:
|
|
a_mgr.append(x.manager1)
|
|
logger.info(f"appending {x.manager1.name}")
|
|
if x.manager2 is not None:
|
|
a_mgr.append(x.manager2)
|
|
logger.info(f"appending {x.manager2.name}")
|
|
|
|
logger.info(f"a_mgr: {a_mgr}")
|
|
if active:
|
|
final_mgrs = [model_to_dict(y, recurse=not short_output) for y in a_mgr]
|
|
else:
|
|
logger.info(f"checking inactive")
|
|
for z in Manager.select():
|
|
logger.info(f"checking: {z.name}")
|
|
if z not in a_mgr:
|
|
logger.info(f"+inactive: {z.name}")
|
|
i_mgr.append(z)
|
|
final_mgrs = [model_to_dict(y, recurse=not short_output) for y in i_mgr]
|
|
|
|
return_managers = {"count": len(final_mgrs), "managers": final_mgrs}
|
|
|
|
else:
|
|
all_managers = Manager.select()
|
|
if name is not None:
|
|
name_list = [x.lower() for x in name]
|
|
all_managers = all_managers.where(fn.Lower(Manager.name) << name_list)
|
|
|
|
return_managers = {
|
|
"count": all_managers.count(),
|
|
"managers": [
|
|
model_to_dict(x, recurse=not short_output) for x in all_managers
|
|
],
|
|
}
|
|
|
|
db.close()
|
|
return return_managers
|
|
|
|
|
|
@router.get("/{manager_id}")
|
|
@handle_db_errors
|
|
async def get_one_manager(manager_id: int, short_output: Optional[bool] = False):
|
|
this_manager = Manager.get_or_none(Manager.id == manager_id)
|
|
if this_manager is not None:
|
|
r_manager = model_to_dict(this_manager, recurse=not short_output)
|
|
db.close()
|
|
return r_manager
|
|
else:
|
|
raise HTTPException(status_code=404, detail=f"Manager {manager_id} not found")
|
|
|
|
|
|
@router.patch("/{manager_id}", include_in_schema=PRIVATE_IN_SCHEMA)
|
|
@handle_db_errors
|
|
async def patch_manager(
|
|
manager_id: int,
|
|
name: Optional[str] = None,
|
|
image: Optional[str] = None,
|
|
headline: Optional[str] = None,
|
|
bio: Optional[str] = None,
|
|
token: str = Depends(oauth2_scheme),
|
|
):
|
|
if not valid_token(token):
|
|
logger.warning(f"patch_manager - Bad Token: {token}")
|
|
raise HTTPException(status_code=401, detail="Unauthorized")
|
|
|
|
this_manager = Manager.get_or_none(Manager.id == manager_id)
|
|
if this_manager is None:
|
|
db.close()
|
|
raise HTTPException(
|
|
status_code=404, detail=f"Manager ID {manager_id} not found"
|
|
)
|
|
|
|
if name is not None:
|
|
this_manager.name = name
|
|
if image is not None:
|
|
this_manager.image = image
|
|
if headline is not None:
|
|
this_manager.headline = headline
|
|
if bio is not None:
|
|
this_manager.bio = bio
|
|
|
|
if this_manager.save() == 1:
|
|
r_manager = model_to_dict(this_manager)
|
|
db.close()
|
|
return r_manager
|
|
else:
|
|
db.close()
|
|
raise HTTPException(
|
|
status_code=500, detail=f"Unable to patch manager {this_manager}"
|
|
)
|
|
|
|
|
|
@router.post("/", include_in_schema=PRIVATE_IN_SCHEMA)
|
|
@handle_db_errors
|
|
async def post_manager(new_manager: ManagerModel, token: str = Depends(oauth2_scheme)):
|
|
if not valid_token(token):
|
|
logger.warning(f"post_manager - Bad Token: {token}")
|
|
raise HTTPException(status_code=401, detail="Unauthorized")
|
|
|
|
this_manager = Manager(**new_manager.dict())
|
|
|
|
if this_manager.save():
|
|
r_manager = model_to_dict(this_manager)
|
|
db.close()
|
|
return r_manager
|
|
else:
|
|
db.close()
|
|
raise HTTPException(
|
|
status_code=500, detail=f"Unable to post manager {this_manager.name}"
|
|
)
|
|
|
|
|
|
@router.delete("/{manager_id}", include_in_schema=PRIVATE_IN_SCHEMA)
|
|
@handle_db_errors
|
|
async def delete_manager(manager_id: int, token: str = Depends(oauth2_scheme)):
|
|
if not valid_token(token):
|
|
logger.warning(f"delete_manager - Bad Token: {token}")
|
|
raise HTTPException(status_code=401, detail="Unauthorized")
|
|
|
|
this_manager = Manager.get_or_none(Manager.id == manager_id)
|
|
if this_manager is None:
|
|
db.close()
|
|
raise HTTPException(
|
|
status_code=404, detail=f"Manager ID {manager_id} not found"
|
|
)
|
|
|
|
count = this_manager.delete_instance()
|
|
db.close()
|
|
|
|
if count == 1:
|
|
return f"Manager {manager_id} has been deleted"
|
|
else:
|
|
raise HTTPException(
|
|
status_code=500, detail=f"Manager {manager_id} could not be deleted"
|
|
)
|