trip33 / app.py
vish85521's picture
Create app.py
7c994e3 verified
Raw
History Blame Contribute Delete
2.65 kB
import os
import sys
import uuid
import io
from fastapi import FastAPI, UploadFile, File, HTTPException
from fastapi.responses import FileResponse
from fastapi.middleware.cors import CORSMiddleware
from PIL import Image
# Route Python to the cloned TripoSR repository
sys.path.append("/app/TripoSR")
import torch
from tsr.system import TSR
from tsr.utils import remove_background, resize_foreground
app = FastAPI(title="TripoSR CPU Free API")
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
model = None
OUTPUT_DIR = "/app/outputs"
@app.on_event("startup")
async def startup_event():
global model
print("Loading TripoSR model to CPU...")
try:
# Load the model and explicitly map it to the CPU
model = TSR.from_pretrained(
"stabilityai/TripoSR",
config_name="config.yaml",
weight_name="model.ckpt"
)
# Lower chunk size to protect the 16GB RAM limit
model.renderer.set_chunk_size(131072)
model.to("cpu")
print("TripoSR successfully loaded and running on CPU!")
except Exception as e:
print(f"Error loading model: {e}")
@app.post("/generate-3d")
async def generate_3d_model(image: UploadFile = File(...)):
"""
Endpoint that accepts 1 image, removes the background, and generates a 3D model.
"""
if model is None:
raise HTTPException(status_code=503, detail="Model is still loading.")
try:
# 1. Read the uploaded image
contents = await image.read()
pil_img = Image.open(io.BytesIO(contents)).convert("RGB")
# 2. Pre-process: Remove background and center the object
print("Removing background...")
img_nobg = remove_background(pil_img, rembg_session=None)
img_resized = resize_foreground(img_nobg, 0.85)
# 3. Generate 3D Model (This takes 2-5 minutes on a CPU)
print("Generating 3D model on CPU...")
with torch.no_grad():
scene_codes = model.get_scene_codes(img_resized)
mesh = model.extract_mesh(scene_codes)[0]
# 4. Save and return the file
job_id = str(uuid.uuid4())
output_path = os.path.join(OUTPUT_DIR, f"{job_id}.obj")
mesh.export(output_path)
return FileResponse(
path=output_path,
media_type="application/octet-stream",
filename=f"{job_id}.obj"
)
except Exception as e:
raise HTTPException(status_code=500, detail=f"Generation failed: {str(e)}")