Spaces:
Paused
Paused
| import os | |
| import uuid | |
| import shutil | |
| from fastapi import FastAPI, UploadFile, File, HTTPException, BackgroundTasks | |
| from fastapi.responses import FileResponse | |
| from pipeline import AvatarExtractorPipeline | |
| app = FastAPI(title="SAM-3D-Body Avatar Extractor") | |
| pipeline = None | |
| def load_model(): | |
| global pipeline | |
| if pipeline is None: | |
| pipeline = AvatarExtractorPipeline() | |
| def cleanup_temp_dir(dir_path: str): | |
| """Safely removes the temporary directory after the response is sent.""" | |
| if os.path.exists(dir_path): | |
| shutil.rmtree(dir_path) | |
| async def extract_avatar(background_tasks: BackgroundTasks, file: UploadFile = File(...)): | |
| if not file.filename.lower().endswith(('png', 'jpg', 'jpeg')): | |
| raise HTTPException(status_code=400, detail="Only PNG and JPEG images are supported.") | |
| session_id = str(uuid.uuid4()) | |
| temp_dir = os.path.join("temp", session_id) | |
| os.makedirs(temp_dir, exist_ok=True) | |
| file_path = os.path.join(temp_dir, file.filename) | |
| try: | |
| # Save uploaded file | |
| with open(file_path, "wb") as buffer: | |
| shutil.copyfileobj(file.file, buffer) | |
| # Process image | |
| mesh_path, pkl_path = pipeline.extract_avatar(file_path) | |
| if not os.path.exists(mesh_path) or not os.path.exists(pkl_path): | |
| raise HTTPException(status_code=500, detail="Failed to generate 3D mesh.") | |
| # Register the cleanup task to run AFTER the file is sent | |
| background_tasks.add_task(cleanup_temp_dir, temp_dir) | |
| return FileResponse( | |
| path=mesh_path, | |
| filename="avatar.obj", | |
| media_type="application/octet-stream" | |
| ) | |
| except Exception as e: | |
| # If an error happens before returning, clean up immediately | |
| cleanup_temp_dir(temp_dir) | |
| raise HTTPException(status_code=500, detail=str(e)) | |