import os import shutil import tempfile import asyncio from fastapi import APIRouter, UploadFile, File, HTTPException from fastapi.responses import JSONResponse from typing import List os.environ["HF_HOME"] = "/tmp" os.environ["HUGGINGFACE_HUB_CACHE"] = "/tmp/huggingface_cache" os.makedirs("/tmp/huggingface_cache", exist_ok=True) # Ensure these imports are correct from lettersController import detectFromImage from wordsController import detectWords from glossController import translateGloss router = APIRouter(prefix="/handsUPApi/sign") @router.post("/processLetters") async def process_letters(frames: List[UploadFile] = File(...)): """Processes a sequence of frames to detect sign language letters.""" sequence_num = 20 if len(frames) != sequence_num: raise HTTPException(status_code=400, detail=f"Exactly {sequence_num} frames are required") # CRITICAL: Read the binary content of each file # We will pass a list of image bytes (memory buffers), NOT UploadFile objects. image_bytes_list = [] try: for frame in frames: # frame.file is an async context manager, read() returns bytes contents = await frame.read() image_bytes_list.append(contents) except Exception as e: # Handle potential file read errors raise HTTPException(status_code=500, detail=f"Error reading uploaded file contents: {e}") # Pass the list of image bytes to the controller result = detectFromImage(image_bytes_list) return JSONResponse(content=result) @router.post("/processWords") async def process_words(frames: List[UploadFile] = File(...)): """Processes a sequence of frames to detect sign language words.""" sequence_num = 90 if len(frames) != sequence_num: raise HTTPException(status_code=400, detail=f"Exactly {sequence_num} frames are required") # CRITICAL: Read the binary content of each file image_bytes_list = [] try: for frame in frames: contents = await frame.read() image_bytes_list.append(contents) except Exception as e: raise HTTPException(status_code=500, detail=f"Error reading uploaded file contents: {e}") # Call the imported function directly result = detectWords(image_bytes_list) return JSONResponse(content=result) @router.post("/sentence") async def sign_sentence(data: dict): """Generates a signed sentence from a given gloss.""" gloss_input = data.get("gloss") if not gloss_input: raise HTTPException(status_code=400, detail="No gloss provided") # Call the imported function directly result = translateGloss(gloss_input) return JSONResponse(content={"translation": result})