From c1931fae20a959cf05327f451259c09f6a5eadaa Mon Sep 17 00:00:00 2001 From: Mabe Date: Fri, 28 Aug 2026 21:02:25 +0200 Subject: [PATCH] Implement CRUD operations for luggage items: add, update, delete, and fetch functionalities; enhance logging and error handling --- api/db.py | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++ api/query.py | 75 +++++++++++++++++++++++++++++++++++++++++ api_server.py | 6 ++-- cli.py | 43 ++++++++++++------------ db.py | 39 +++++++++++---------- 5 files changed, 216 insertions(+), 40 deletions(-) create mode 100644 api/db.py create mode 100644 api/query.py diff --git a/api/db.py b/api/db.py new file mode 100644 index 0000000..23d43c9 --- /dev/null +++ b/api/db.py @@ -0,0 +1,93 @@ +from fastapi import APIRouter, HTTPException +import logging +import db +from pydantic import BaseModel + + +#Logging + +logging.basicConfig( + filename='api.log', # Log to a file + level=logging.DEBUG, # Log everything (DEBUG and above) + format='%(asctime)s %(levelname)s %(message)s' +) + +logging.info('Application started') +try: + logging.debug('Debug info here') +except Exception as e: + logging.exception('An error occurred') + +router = APIRouter(prefix="/db", tags=["db"]) + +@router.get("/help") +def get_help(): + return {"name of clothes": "example", + "weight": "sample weight (only floats)", + "pieces": "sample pieces (only ints)"} + + + + +class Item_name(BaseModel): + name_of_clothes: str + class Config: + fields = { + "name_of_clothes": "name of clothes" + } + +class Item_weight(BaseModel): + weight: float + +class Item_piece(BaseModel): + pieces: int + +@router.post("/insert", status_code=201) +def insert(item_name: Item_name, item_weight: Item_weight, item_pieces: Item_piece): + name = item_name.name_of_clothes.upper() + weight = item_weight.weight + pieces = item_pieces.pieces + db.new_part(name, weight, pieces) + logging.info("new Item created in DB") + return {"message": "Item inserted"} + + + +@router.put("/update/{clothe_name}/pieces", status_code=202) +def update_pieces(clothe_name: str, item_pieces: Item_piece): + name = clothe_name.upper() + pieces = item_pieces.pieces + if db.check_clothe(name) != None: + db.update_pieces(name, pieces) + logging.info(f"Item {name} was set a new count") + return {"message": "pieces updated"} + else: + logging.error(f"Item {name} not found") + raise HTTPException(status_code=404, detail=f"Item {name} not found") + + + +@router.put("/update/{clothe_name}/weight", status_code=202) +def update_weight(clothe_name: str, item: Item_weight): + name = clothe_name.upper() + weight = item.weight + if db.check_clothe(name) != None: + db.update_weight(name, weight) + logging.info(f"Item {name} was set a new weight") + return {"message": "weight updated"} + else: + logging.error(f"Item {name} not found") + raise HTTPException(status_code=404, detail=f"Item {name} not found") + + + +@router.delete("/{clothe_name}/delete", status_code=204) +def delete(clothe_name: str): + name = clothe_name.upper() + if db.check_clothe(name) != None: + db.delete(name) + logging.critical(f"Item {name} was deleted") + return {"message": "Item was deleted"} + else: + logging.error(f"Item {name} not found") + raise HTTPException(status_code=404, detail=f"Item {name} not found") \ No newline at end of file diff --git a/api/query.py b/api/query.py new file mode 100644 index 0000000..a03f5f7 --- /dev/null +++ b/api/query.py @@ -0,0 +1,75 @@ +from fastapi import APIRouter, HTTPException +import logging +import db +from pydantic import BaseModel + + +#Logging + +logging.basicConfig( + filename='api.log', # Log to a file + level=logging.DEBUG, # Log everything (DEBUG and above) + format='%(asctime)s %(levelname)s %(message)s' +) + +logging.info('Application started') +try: + logging.debug('Debug info here') +except Exception as e: + logging.exception('An error occurred') + +router = APIRouter(prefix="/query", tags=["query"]) + +@router.get("/help", status_code=200) +def get_help(): + return {"name of clothes": "example"} + +@router.get("/{clothe_name}/weight", status_code=206) +def get_weight(clothe_name: str): + name = clothe_name.upper() + if db.check_clothe(name) != None: + weight = db.fetch_weight(name) + return {"weight": weight} + else: + logging.error(f"Item {name} not found") + raise HTTPException(status_code=404, detail=f"Item {name} not found") + +@router.get("/weight", status_code=200) +def get_luggage_weight(): + weight = db.fetch_luggage_weight() + return {"weight": weight} + +@router.get("/{clothe_name}/pieces",status_code=206) +def get_pieces(clothe_name: str): + name = clothe_name.upper() + if db.check_clothe(name) != None: + pieces = db.fetch_piece(name) + return {"pieces": pieces} + else: + logging.error(f"Item {name} not found") + raise HTTPException(status_code=404, detail=f"Item {name} not found") + +@router.get("/pieces", status_code=200) +def get_all_pieces(): + pieces = db.fetch_all_pieces() + return {"pieces": pieces} + +@router.get("/clothes") +def get_clothes(): + clothes = db.fetch_clothes() + return {"clothes": clothes} + +@router.get("/{clothe_name}/all", status_code=102) +def get_all(clothe_name: str): + name = clothe_name.upper() + if db.check_clothe(name) != None: + weight = db.fetch_weight(name) + pieces = db.fetch_piece(name) + return{ + "clothe": name, + "weight": weight, + "pieces": pieces + } + else: + logging.error(f"Item {name} not found") + raise HTTPException(status_code=404, detail=f"Item {name} not found") \ No newline at end of file diff --git a/api_server.py b/api_server.py index e57a19b..c30f77e 100644 --- a/api_server.py +++ b/api_server.py @@ -1,5 +1,7 @@ from fastapi import FastAPI -from api import health +from api import health, db, query app =FastAPI() -app.include_router(health.router) \ No newline at end of file +app.include_router(health.router) +app.include_router(db.router) +app.include_router(query.router) \ No newline at end of file diff --git a/cli.py b/cli.py index fec9cc0..56c27c1 100644 --- a/cli.py +++ b/cli.py @@ -25,9 +25,9 @@ except Exception as e: def insert(): clothe = input("How is the clothe called? ").upper() - weigth = float(input("The weigth please? ")) + weight = float(input("The weight please? ")) pieces = int(input("How many pieces? ints only ")) - db.new_part(clothe, weigth, pieces) + db.new_part(clothe, weight, pieces) print("it is inserted") time.sleep(3) os.system('cls' if os.name == 'nt' else 'clear') @@ -35,9 +35,9 @@ def insert(): def insert(): clothe = input("How is the clothe called? ").upper() - weigth = float(input("The weigth please? ")) + weight = float(input("The weight please? ")) pieces = int(input("How many pieces? ints only ")) - db.new_part(clothe, weigth, pieces) + db.new_part(clothe, weight, pieces) print("it is inserted") time.sleep(3) os.system('cls' if os.name == 'nt' else 'clear') @@ -45,26 +45,26 @@ def insert(): def update(): clothe = input("How is the clothe called? ").upper() - weigth = input("The weigth please? ") + weight = input("The weight please? ") pieces = input("How many pieces? ints only ") - db.update_weigth(clothe, weigth) + db.update_weight(clothe, weight) db.update_pieces(clothe, pieces) print("it is updated") time.sleep(3) os.system('cls' if os.name == 'nt' else 'clear') menu() -def get_weigth(): +def get_weight(): clothe = input("How is the clothe called? ").upper() - weigth = db.fetch_weigth(clothe) - print(weigth) + weight = db.fetch_weight(clothe) + print(weight) time.sleep(3) os.system('cls' if os.name == 'nt' else 'clear') menu() -def get_luggage_weigth(): - weigth = db.fetch_luggage_weigth() - print(f"The luggage has a weigth of {weigth}g") +def get_luggage_weight(): + weight = db.fetch_luggage_weight() + print(f"The luggage has a weight of {weight}g") time.sleep(3) os.system('cls' if os.name == 'nt' else 'clear') menu() @@ -92,11 +92,11 @@ def get_clothes(): os.system('cls' if os.name == 'nt' else 'clear') menu() -def get_weigth_pieces(): +def get_weight_pieces(): clothe = input("How is the clothe called? ").upper() - weigth = db.fetch_weigth(clothe) + weight = db.fetch_weight(clothe) pieces = db.fetch_piece(clothe) - print(f"You have {pieces} of {clothe}. The weigth is {weigth}") + print(f"You have {pieces} of {clothe}. The weight is {weight}") time.sleep(3) os.system('cls' if os.name == 'nt' else 'clear') menu() @@ -133,17 +133,18 @@ def exit_programm(): time.sleep(0.75) os.system('cls' if os.name == 'nt' else 'clear') sys.exit() + os._exit(1) def menu(): print("Menu") print("1: Insert Item") print("2: Update Item") - print("3: Get weigth of clothe") - print("4: Get weigth of luggage") + print("3: Get weight of clothe") + print("4: Get weight of luggage") print("5: Get pieces of clothe") print("6: Get pieces of luggage") print("7: Get clothes") - print("8: Get weigth and pieces of clothes") + print("8: Get weight and pieces of clothes") print("9: Delete Item") print("0: EXIT") choice = input("Type number here ") @@ -155,9 +156,9 @@ def menu(): if choice == "2": update() if choice == "3": - get_weigth() + get_weight() if choice == "4": - get_luggage_weigth() + get_luggage_weight() if choice == "5": get_pieces() if choice == "6": @@ -165,7 +166,7 @@ def menu(): if choice == "7": get_clothes() if choice == "8": - get_weigth_pieces() + get_weight_pieces() if choice == "0": exit_programm() if choice == "9": diff --git a/db.py b/db.py index a77dc4d..3051972 100644 --- a/db.py +++ b/db.py @@ -34,14 +34,14 @@ def connect(db_user, db_psswd, db_host, db_port, db_name): logging.error("Error connecting") logging.debug(f"Error connecting to DB: {e}") -def new_part(cloth_type, weigth, pieces): +def new_part(cloth_type, weight, pieces): if type(pieces) is not int: print("only ints allowed") logging.error("only ints allowed") else: cursor = connection.cursor() - executed = "INSERT INTO luggage (clothes, weigth, pieces) VALUES (?, ?, ?)" - executed_data = (cloth_type, weigth, pieces) + executed = "INSERT INTO luggage (clothes, weight, pieces) VALUES (?, ?, ?)" + executed_data = (cloth_type, weight, pieces) cursor.execute(executed, executed_data) connection.commit() logging.info("new Insert is in DB") @@ -53,13 +53,13 @@ def fetch_clothes(): logging.info("fetched clothes") return clothes -def update_weigth(cloth_type, weigth): +def update_weight(cloth_type, weight): cursor = connection.cursor() - executed = "UPDATE luggage SET weigth = ? WHERE clothes = ?" - executed_data = (weigth, cloth_type) + executed = "UPDATE luggage SET weight = ? WHERE clothes = ?" + executed_data = (weight, cloth_type) cursor.execute(executed, executed_data) connection.commit() - logging.info("weigth updated") + logging.info("weight updated") def update_pieces(cloth_type, pieces): if type(pieces) is not int: @@ -72,19 +72,19 @@ def update_pieces(cloth_type, pieces): connection.commit() logging.info("pieces updated") -def fetch_weigth(cloth_type): +def fetch_weight(cloth_type): cursor = connection.cursor() - cursor.execute("SELECT weigth FROM luggage WHERE clothes = ?", (cloth_type,)) - weigth = cursor.fetchone()[0] - logging.info("fetched weigth") - return weigth + cursor.execute("SELECT weight FROM luggage WHERE clothes = ?", (cloth_type,)) + weight = cursor.fetchone()[0] + logging.info("fetched weight") + return weight -def fetch_luggage_weigth(): +def fetch_luggage_weight(): cursor = connection.cursor() - cursor.execute("SELECT sum(weigth) FROM luggage") - weigth = cursor.fetchone()[0] - logging.info("fetched luggage weigth") - return weigth + cursor.execute("SELECT sum(weight) FROM luggage") + weight = cursor.fetchone()[0] + logging.info("fetched luggage weight") + return weight def fetch_piece(cloth_type): cursor = connection.cursor() @@ -106,6 +106,11 @@ def delete(cloth_type): logging.critical(f"{cloth_type} was deleted") connection.commit() +def check_clothe(clothe_type): + cursor = connection.cursor() + cursor.execute("SELECT (SELECT clothes FROM luggage WHERE clothes = ? LIMIT 1) AS clothes", (clothe_type,)) + check = cursor.fetchone()[0] + return check #using .env