86 lines
2.9 KiB
Python
86 lines
2.9 KiB
Python
import os
|
|
import sys
|
|
import uvicorn
|
|
from fastapi import FastAPI, HTTPException
|
|
from pydantic import BaseModel, Field
|
|
from typing import List, Optional
|
|
|
|
# Ensure the project root is in sys.path
|
|
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
|
|
|
try:
|
|
# Attempt to import the entrypoint from the existing script
|
|
# This assumes the environment is set up correctly with all dependencies
|
|
from embodied_gen.scripts.imageto3d import entrypoint
|
|
except ImportError as e:
|
|
print(f"Error importing embodied_gen: {e}")
|
|
print("Please ensure you are running this script from the project root and environment is configured.")
|
|
sys.exit(1)
|
|
|
|
app = FastAPI(title="Image to 3D Service")
|
|
|
|
class ImageTo3DRequest(BaseModel):
|
|
image_paths: List[str] = Field(..., description="Path to the input images (e.g. apps/assets/example_image/sample_00.jpg)")
|
|
output_root: str = Field(..., description="Root directory for saving outputs (e.g. outputs/imageto3d)")
|
|
n_retry: int = Field(2, description="Number of retries")
|
|
|
|
# Optional parameters mirroring the CLI arguments
|
|
height_range: Optional[str] = None
|
|
mass_range: Optional[str] = None
|
|
asset_type: Optional[List[str]] = None
|
|
skip_exists: bool = False
|
|
version: Optional[str] = None
|
|
keep_intermediate: bool = False
|
|
seed: int = 0
|
|
disable_decompose_convex: bool = False
|
|
texture_size: int = 2048
|
|
|
|
@app.post("/process")
|
|
async def process_images(request: ImageTo3DRequest):
|
|
"""
|
|
HTTP wrapper for img3d-cli.
|
|
"""
|
|
# 1. Validate inputs
|
|
for path in request.image_paths:
|
|
if not os.path.exists(path):
|
|
raise HTTPException(status_code=400, detail=f"Image path does not exist: {path}")
|
|
|
|
# 2. Invoke the processing logic
|
|
try:
|
|
# entrypoint() in imageto3d.py accepts **kwargs to override parsed args
|
|
entrypoint(
|
|
image_path=request.image_paths,
|
|
output_root=request.output_root,
|
|
n_retry=request.n_retry,
|
|
|
|
# Optional args
|
|
height_range=request.height_range,
|
|
mass_range=request.mass_range,
|
|
asset_type=request.asset_type,
|
|
skip_exists=request.skip_exists,
|
|
version=request.version,
|
|
keep_intermediate=request.keep_intermediate,
|
|
seed=request.seed,
|
|
disable_decompose_convex=request.disable_decompose_convex,
|
|
texture_size=request.texture_size
|
|
)
|
|
|
|
return {
|
|
"status": "success",
|
|
"message": "Processing completed.",
|
|
"output_root": request.output_root,
|
|
"inputs": request.image_paths
|
|
}
|
|
|
|
except Exception as e:
|
|
# Catch errors from the processing pipeline
|
|
raise HTTPException(status_code=500, detail=f"Processing failed: {str(e)}")
|
|
|
|
@app.get("/health")
|
|
def health():
|
|
return {"status": "ok"}
|
|
|
|
if __name__ == "__main__":
|
|
# Run server on port 8000
|
|
uvicorn.run(app, host="0.0.0.0", port=8000)
|