Repository navigation
Expand file tree
/
Copy pathmain.py
More file actions
76 lines (61 loc) · 2.45 KB
/
Copy pathmain.py
File metadata and controls
76 lines (61 loc) · 2.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
from pathlib import Path
import numpy as np
from fastapi import FastAPI, File, Form, HTTPException, UploadFile
from fastapi.responses import FileResponse, Response
from fastapi.staticfiles import StaticFiles
from neuron.inference import MaterialHeroInference, PromptError
ROOT = Path(__file__).resolve().parent
CHECKPOINT = ROOT / "train" / "outputs" / "material-hero-v0-final" / "material_hero_v0.pt"
MAX_PIXELS = 1024 * 1024
engine = MaterialHeroInference(CHECKPOINT)
app = FastAPI()
@app.get("/api/status")
async def status():
return {
"status": "ready",
"model": "material_hero_v0",
"checkpoint_step": engine.step,
"device": str(engine.device),
"scope": "sculpted_rubber_toy/cam_001",
}
async def read_float_buffer(upload: UploadFile, expected_values: int) -> np.ndarray:
content = await upload.read()
if len(content) != expected_values * 4:
raise HTTPException(status_code=422, detail=f"{upload.filename} has the wrong size.")
return np.frombuffer(content, dtype="<f4").copy()
@app.post("/api/render")
async def render(
prompt: str = Form(...),
width: int = Form(...),
height: int = Form(...),
position: UploadFile = File(...),
normal: UploadFile = File(...),
view: UploadFile = File(...),
coverage: UploadFile = File(...),
):
if width <= 0 or height <= 0 or width * height > MAX_PIXELS:
raise HTTPException(status_code=422, detail="Resolution exceeds the v0 limit.")
pixels = width * height
try:
png, normalized_prompt = engine.render_png(
prompt,
(await read_float_buffer(position, pixels * 3)).reshape(pixels, 3),
(await read_float_buffer(normal, pixels * 3)).reshape(pixels, 3),
(await read_float_buffer(view, pixels * 3)).reshape(pixels, 3),
await read_float_buffer(coverage, pixels),
width,
height,
)
except PromptError as error:
raise HTTPException(status_code=422, detail=str(error)) from error
except ValueError as error:
raise HTTPException(status_code=422, detail=str(error)) from error
return Response(
content=png,
media_type="image/png",
headers={"X-Normalized-Prompt": normalized_prompt},
)
app.mount("/", StaticFiles(directory=ROOT / "dist", html=True), name="static")
@app.exception_handler(404)
async def not_found_exception_handler(request, exc):
return FileResponse(ROOT / "dist" / "index.html")