|
| 1 | +from fastapi import APIRouter, Depends, HTTPException, Response |
| 2 | +from sqlalchemy.ext.asyncio import AsyncSession |
| 3 | +from typing import List |
| 4 | +from .. import crud, schemas, database, utils |
| 5 | + |
| 6 | +router = APIRouter() |
| 7 | + |
| 8 | +@router.get("/boxes/{box_id}/qrcode") |
| 9 | +async def get_box_qrcode(box_id: int, db: AsyncSession = Depends(database.get_db)): |
| 10 | + db_box = await crud.get_box(db, box_id=box_id) |
| 11 | + if db_box is None: |
| 12 | + raise HTTPException(status_code=404, detail="Box not found") |
| 13 | + |
| 14 | + # URL structure: /api/hassio_ingress/{slug}/#/box/{slug} |
| 15 | + # Note: Ingress path handling might require adjustment based on actual deployment |
| 16 | + # For now, we generate a relative URL or a full URL if domain is known |
| 17 | + # Using the box slug for the URL |
| 18 | + qr_data = f"/hassio/ingress/whereisit/#/box/{db_box.slug}" |
| 19 | + |
| 20 | + img_bytes = utils.generate_qr_code(qr_data) |
| 21 | + return Response(content=img_bytes, media_type="image/png") |
| 22 | + |
| 23 | +@router.post("/units", response_model=schemas.UnitResponse) |
| 24 | +async def create_unit(unit: schemas.UnitCreate, db: AsyncSession = Depends(database.get_db)): |
| 25 | + db_unit = await crud.create_unit(db=db, unit=unit) |
| 26 | + # Return explicit dict to avoid ANY lazy loading risk during Pydantic validation |
| 27 | + return {"id": db_unit.id, "name": db_unit.name, "description": db_unit.description} |
| 28 | + |
| 29 | +@router.get("/units", response_model=List[schemas.Unit]) |
| 30 | +async def read_units(skip: int = 0, limit: int = 100, db: AsyncSession = Depends(database.get_db)): |
| 31 | + return await crud.get_units(db, skip=skip, limit=limit) |
| 32 | + |
| 33 | +@router.get("/units/{unit_id}", response_model=schemas.Unit) |
| 34 | +async def read_unit(unit_id: int, db: AsyncSession = Depends(database.get_db)): |
| 35 | + db_unit = await crud.get_unit(db, unit_id=unit_id) |
| 36 | + if db_unit is None: |
| 37 | + raise HTTPException(status_code=404, detail="Unit not found") |
| 38 | + return db_unit |
| 39 | + |
| 40 | +@router.put("/units/{unit_id}", response_model=schemas.UnitResponse) |
| 41 | +async def update_unit(unit_id: int, unit_update: schemas.UnitUpdate, db: AsyncSession = Depends(database.get_db)): |
| 42 | + db_unit = await crud.update_unit(db, unit_id=unit_id, unit_update=unit_update) |
| 43 | + if not db_unit: |
| 44 | + raise HTTPException(status_code=404, detail="Unit not found") |
| 45 | + return {"id": db_unit.id, "name": db_unit.name, "description": db_unit.description} |
| 46 | + |
| 47 | +@router.delete("/units/{unit_id}") |
| 48 | +async def delete_unit(unit_id: int, db: AsyncSession = Depends(database.get_db)): |
| 49 | + db_unit = await crud.delete_unit(db, unit_id=unit_id) |
| 50 | + if not db_unit: |
| 51 | + raise HTTPException(status_code=404, detail="Unit not found") |
| 52 | + return {"message": "Unit deleted successfully"} |
| 53 | + |
| 54 | +@router.post("/boxes", response_model=schemas.BoxSummary) |
| 55 | +async def create_box(box: schemas.BoxCreate, db: AsyncSession = Depends(database.get_db)): |
| 56 | + db_box = await crud.create_box(db=db, box=box) |
| 57 | + # Return explicit dict to avoid Pydantic trying to lazily load the un-fetched db_box.items relationship |
| 58 | + return {"id": db_box.id, "name": db_box.name, "description": db_box.description, "slug": db_box.slug, "unit_id": db_box.unit_id} |
| 59 | + |
| 60 | +@router.put("/boxes/{box_id}", response_model=schemas.BoxSummary) |
| 61 | +async def update_box(box_id: int, box_update: schemas.BoxUpdate, db: AsyncSession = Depends(database.get_db)): |
| 62 | + db_box = await crud.update_box(db, box_id=box_id, box_update=box_update) |
| 63 | + if not db_box: |
| 64 | + raise HTTPException(status_code=404, detail="Box not found") |
| 65 | + return {"id": db_box.id, "name": db_box.name, "description": db_box.description, "slug": db_box.slug, "unit_id": db_box.unit_id} |
| 66 | + |
| 67 | +@router.delete("/boxes/{box_id}") |
| 68 | +async def delete_box(box_id: int, db: AsyncSession = Depends(database.get_db)): |
| 69 | + db_box = await crud.delete_box(db, box_id=box_id) |
| 70 | + if not db_box: |
| 71 | + raise HTTPException(status_code=404, detail="Box not found") |
| 72 | + return {"message": "Box deleted successfully"} |
| 73 | + |
| 74 | +@router.get("/boxes/{box_id}", response_model=schemas.Box) |
| 75 | +async def read_box(box_id: int, db: AsyncSession = Depends(database.get_db)): |
| 76 | + db_box = await crud.get_box(db, box_id=box_id) |
| 77 | + if db_box is None: |
| 78 | + raise HTTPException(status_code=404, detail="Box not found") |
| 79 | + return db_box |
| 80 | + |
| 81 | +@router.get("/boxes/slug/{slug}", response_model=schemas.Box) |
| 82 | +async def read_box_by_slug(slug: str, db: AsyncSession = Depends(database.get_db)): |
| 83 | + db_box = await crud.get_box_by_slug(db, slug=slug) |
| 84 | + if db_box is None: |
| 85 | + raise HTTPException(status_code=404, detail="Box not found") |
| 86 | + return db_box |
| 87 | + |
| 88 | +@router.post("/boxes/{box_id}/items", response_model=schemas.Item) |
| 89 | +async def create_item(box_id: int, item: schemas.ItemCreate, db: AsyncSession = Depends(database.get_db)): |
| 90 | + return await crud.create_item(db=db, item=item, box_id=box_id) |
| 91 | + |
| 92 | +@router.put("/items/{item_id}", response_model=schemas.Item) |
| 93 | +async def update_item(item_id: int, item_update: schemas.ItemUpdate, db: AsyncSession = Depends(database.get_db)): |
| 94 | + db_item = await crud.update_item(db, item_id=item_id, item_update=item_update) |
| 95 | + if not db_item: |
| 96 | + raise HTTPException(status_code=404, detail="Item not found") |
| 97 | + return db_item |
| 98 | + |
| 99 | +@router.delete("/items/{item_id}") |
| 100 | +async def delete_item(item_id: int, db: AsyncSession = Depends(database.get_db)): |
| 101 | + db_item = await crud.delete_item(db, item_id=item_id) |
| 102 | + if not db_item: |
| 103 | + raise HTTPException(status_code=404, detail="Item not found") |
| 104 | + return {"message": "Item deleted successfully"} |
| 105 | + |
| 106 | +@router.get("/search") |
| 107 | +async def search(q: str, db: AsyncSession = Depends(database.get_db)): |
| 108 | + return await crud.search_storage(db, q) |
0 commit comments