From 29de5036e40d69c4666b18d3d8cbb3cb704c039e Mon Sep 17 00:00:00 2001 From: Devansh Singh Date: Mon, 17 Jun 2024 21:59:24 +0530 Subject: [PATCH] Add routes/presets.py Create endpoints for presets Signed-off-by: Devansh Singh --- src/teuthology_api/main.py | 3 +- src/teuthology_api/routes/presets.py | 96 ++++++++++++++++++++++++++ src/teuthology_api/services/presets.py | 10 ++- start_container.sh | 2 + 4 files changed, 107 insertions(+), 4 deletions(-) create mode 100644 src/teuthology_api/routes/presets.py diff --git a/src/teuthology_api/main.py b/src/teuthology_api/main.py index 93e0678..ac9a9aa 100644 --- a/src/teuthology_api/main.py +++ b/src/teuthology_api/main.py @@ -5,7 +5,7 @@ from starlette.middleware.sessions import SessionMiddleware from teuthology_api.config import settings -from teuthology_api.routes import suite, kill, login, logout +from teuthology_api.routes import suite, kill, login, logout, presets DEPLOYMENT = settings.deployment @@ -39,3 +39,4 @@ def read_root(request: Request): app.include_router(kill.router) app.include_router(login.router) app.include_router(logout.router) +app.include_router(presets.router) diff --git a/src/teuthology_api/routes/presets.py b/src/teuthology_api/routes/presets.py new file mode 100644 index 0000000..b6cb32e --- /dev/null +++ b/src/teuthology_api/routes/presets.py @@ -0,0 +1,96 @@ +import logging + +from fastapi import status, APIRouter, HTTPException, Depends +from sqlmodel import Session + +from teuthology_api.services.helpers import get_token +from teuthology_api.models import get_db, Presets +from teuthology_api.services.presets import PresetsDatabaseException, PresetsService + +logger = logging.getLogger(__name__) + +router = APIRouter(prefix="/presets", tags=["presets"]) + + +@router.get("/", status_code=status.HTTP_200_OK) +def read_preset(username: str, name: str, db: Session = Depends(get_db)): + db_preset = PresetsService(db).get_by_username_and_name(username, name) + if db_preset is None: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail=f"{name} preset does not exist.", + ) + return db_preset + + +@router.get("/list", status_code=status.HTTP_200_OK) +def read_all_presets(username: str, db: Session = Depends(get_db)): + db_presets = PresetsService(db).get_by_username(username) + if not db_presets: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail="User has not presets saved.", + ) + return db_presets + + +@router.post("/add", status_code=status.HTTP_201_CREATED) +def add_preset( + preset: Presets, + db: Session = Depends(get_db), + access_token: str = Depends(get_token), +): + if not access_token: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail="You need to be logged in", + headers={"WWW-Authenticate": "Bearer"}, + ) + db_preset_exists = PresetsService(db).get_by_username_and_name( + preset.username, preset.name + ) + if db_preset_exists: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=f"Preset with name {preset.name} exists", + ) + return PresetsService(db).create(preset) + + +@router.put("/edit/{preset_id}", status_code=status.HTTP_200_OK) +def update_preset( + preset_id: int, + updated_preset: Presets, + db: Session = Depends(get_db), + access_token: str = Depends(get_token), +): + if not access_token: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail="You need to be logged in", + headers={"WWW-Authenticate": "Bearer"}, + ) + try: + return PresetsService(db).update( + preset_id, updated_preset.model_dump(exclude_unset=True) + ) + except PresetsDatabaseException as exc: + raise HTTPException(status_code=exc.code, detail=str(exc)) + + +@router.delete("/delete/{preset_id}", status_code=status.HTTP_204_NO_CONTENT) +def delete_preset( + preset_id: int, + db: Session = Depends(get_db), + access_token: str = Depends(get_token), +): + if not access_token: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail="You need to be logged in", + headers={"WWW-Authenticate": "Bearer"}, + ) + try: + PresetsService(db).delete(preset_id) + except PresetsDatabaseException as exc: + raise HTTPException(status_code=exc.code, detail=str(exc)) diff --git a/src/teuthology_api/services/presets.py b/src/teuthology_api/services/presets.py index ab85639..5136ea6 100644 --- a/src/teuthology_api/services/presets.py +++ b/src/teuthology_api/services/presets.py @@ -1,3 +1,5 @@ +from typing import Union + from sqlmodel import select, Session from teuthology_api.models.presets import Presets @@ -18,14 +20,16 @@ def get_by_username(self, username: str): db_presets = self.db.exec(statement).all() return db_presets - def get_by_username_and_name(self, username: str, preset_name: str): + def get_by_username_and_name( + self, username: str, preset_name: str + ) -> Union[Presets, None]: statement = select(Presets).where( Presets.username == username, Presets.name == preset_name ) db_preset = self.db.exec(statement).first() return db_preset - def get_by_id(self, preset_id: int): + def get_by_id(self, preset_id: int) -> Union[Presets, None]: statement = select(Presets).where(Presets.id == preset_id) db_preset = self.db.exec(statement).first() return db_preset @@ -46,7 +50,7 @@ def update(self, preset_id: int, updated_data: dict) -> Presets: db_preset.sqlmodel_update(updated_data) return self.create(db_preset) - def delete(self, preset_id: int): + def delete(self, preset_id: int) -> None: db_preset = self.get_by_id(preset_id) if db_preset is None: raise PresetsDatabaseException( diff --git a/start_container.sh b/start_container.sh index 2d9919c..7f6af77 100755 --- a/start_container.sh +++ b/start_container.sh @@ -9,6 +9,8 @@ VENV=${VENV:-"venv"} source ${VENV}/bin/activate cd /teuthology_api/src/ +alembic -x verbose=1 upgrade head + if [ "$DEPLOYMENT" = "development" ]; then uvicorn teuthology_api.main:app --reload --port $PORT --host $HOST else