from fastapi import APIRouter, Depends, HTTPException, UploadFile, File, status from sqlalchemy.orm import Session from typing import List from pathlib import Path from app.db.session import get_db from app.db.crud_tomato import tomato_image from app.schemas.tomato import TomatoImage, TomatoImageCreate, UploadResponse from app.utils.image import save_uploaded_image from app.core.config import settings router = APIRouter() @router.post("/upload", response_model=UploadResponse, status_code=status.HTTP_201_CREATED) async def upload_tomato_image( file: UploadFile = File(...), db: Session = Depends(get_db) ): """ Upload a tomato image for analysis. The image will be saved and registered in the database. It can then be analyzed using the analysis endpoint. """ # Validate file type if file.content_type not in settings.ALLOWED_IMAGE_TYPES: raise HTTPException( status_code=status.HTTP_415_UNSUPPORTED_MEDIA_TYPE, detail=f"Unsupported file type: {file.content_type}. Allowed types: {', '.join(settings.ALLOWED_IMAGE_TYPES)}" ) # Read file content contents = await file.read() # Validate file size if len(contents) > settings.MAX_IMAGE_SIZE: raise HTTPException( status_code=status.HTTP_413_REQUEST_ENTITY_TOO_LARGE, detail=f"File too large. Maximum size allowed: {settings.MAX_IMAGE_SIZE / (1024 * 1024)}MB" ) # Save file and get metadata image_data = save_uploaded_image(contents, file.filename) # Create database record image_in = TomatoImageCreate(**image_data) db_image = tomato_image.create(db=db, obj_in=image_in) return UploadResponse( image=db_image, message="Image uploaded successfully" ) @router.get("/", response_model=List[TomatoImage]) def list_tomato_images( skip: int = 0, limit: int = 100, db: Session = Depends(get_db) ): """ List all uploaded tomato images. """ images = tomato_image.get_multi(db=db, skip=skip, limit=limit) return images @router.get("/{image_id}", response_model=TomatoImage) def get_tomato_image( image_id: str, db: Session = Depends(get_db) ): """ Get a specific tomato image by ID. """ db_image = tomato_image.get(db=db, id=image_id) if db_image is None: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Image not found" ) return db_image @router.delete("/{image_id}", status_code=status.HTTP_204_NO_CONTENT, response_model=None) def delete_tomato_image( image_id: str, db: Session = Depends(get_db) ): """ Delete a tomato image and its associated data. """ db_image = tomato_image.get(db=db, id=image_id) if db_image is None: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Image not found" ) # Delete the image file try: if db_image.file_path and Path(db_image.file_path).exists(): Path(db_image.file_path).unlink() except Exception: # Log error but continue with database deletion pass # Delete database record (cascade will handle related records) tomato_image.remove(db=db, id=image_id) return None