""" References Router - Reference image upload """ from fastapi import APIRouter, HTTPException from models.requests import ReferenceUploadRequest from models.responses import ReferenceUploadResponse, ErrorResponse from services.whisk_client import WhiskClient import json router = APIRouter(tags=["References"]) @router.post( "/references/upload", response_model=ReferenceUploadResponse, responses={ 400: {"model": ErrorResponse}, 401: {"model": ErrorResponse}, 500: {"model": ErrorResponse} } ) async def upload_reference(request: ReferenceUploadRequest): """ Upload a reference image for Whisk generation. - **imageBase64**: Base64 encoded image data - **mimeType**: Image MIME type (image/jpeg, image/png, image/webp, image/gif) - **category**: Reference category (subject, scene, style) - **cookies**: Whisk authentication cookies """ # Validate MIME type allowed_types = ['image/jpeg', 'image/png', 'image/webp', 'image/gif'] if request.mimeType not in allowed_types: raise HTTPException( status_code=400, detail=f"Unsupported file type: {request.mimeType}. Please use JPG, PNG, or WEBP." ) # Normalize cookies valid_cookies = request.cookies.strip() is_json = False trimmed = valid_cookies.strip() if trimmed.startswith('[') or trimmed.startswith('{'): is_json = True try: cookie_array = json.loads(trimmed) if isinstance(cookie_array, list): valid_cookies = "; ".join( f"{c['name']}={c['value']}" for c in cookie_array ) print(f"[API] Successfully parsed {len(cookie_array)} cookies from JSON.") elif isinstance(cookie_array, dict) and 'name' in cookie_array and 'value' in cookie_array: valid_cookies = f"{cookie_array['name']}={cookie_array['value']}" except Exception as e: print(f"[API] Failed to parse cookie JSON, falling back to raw value: {e}") # Validate cookie format if '=' not in valid_cookies: raise HTTPException( status_code=400, detail='Invalid Cookie Format. Cookies must be in "name=value" format or a JSON list.' ) print(f"[API] Uploading reference image ({request.category}, {request.mimeType})...") print(f"[API] Using cookies (first 100 chars): {valid_cookies[:100]}...") print(f"[API] Cookie was JSON: {is_json}") try: client = WhiskClient(valid_cookies) # Remove data URI header if present raw_base64 = request.imageBase64 if raw_base64.startswith('data:'): raw_base64 = raw_base64.split(',', 1)[1] if ',' in raw_base64 else raw_base64 media_id = await client.upload_reference_image( raw_base64, request.mimeType, request.category ) if not media_id: raise HTTPException(status_code=500, detail="Upload returned no ID") return ReferenceUploadResponse(success=True, id=media_id) except ValueError as e: raise HTTPException(status_code=400, detail=str(e)) except Exception as e: print(f"Reference Upload API failed: {e}") raise HTTPException(status_code=500, detail=str(e))