Spaces:
Sleeping
Sleeping
File size: 5,248 Bytes
508dbb9 4fcc94b 508dbb9 4fcc94b 508dbb9 4fcc94b 508dbb9 4fcc94b 508dbb9 4fcc94b 508dbb9 4fcc94b 3933765 4fcc94b 508dbb9 4fcc94b 508dbb9 4fcc94b 508dbb9 4fcc94b 508dbb9 4fcc94b 508dbb9 4fcc94b bdb708c 4fcc94b 508dbb9 4fcc94b 508dbb9 4fcc94b bdb708c 508dbb9 bdb708c 4fcc94b 508dbb9 bdb708c 4fcc94b 508dbb9 bdb708c 4fcc94b bdb708c 508dbb9 4fcc94b |
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 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
from fastapi import FastAPI, UploadFile, File, HTTPException, BackgroundTasks
from fastapi.responses import FileResponse, JSONResponse
from uuid import uuid4
from pathlib import Path
import shutil
import os
import json
from dotenv import load_dotenv
from tasks import process_image_task
load_dotenv()
# Directories
# Use /tmp for Hugging Face Spaces as it is writable
UPLOAD_DIR = Path("/tmp/uploads")
RESULT_DIR = Path("/tmp/results")
UPLOAD_DIR.mkdir(parents=True, exist_ok=True)
RESULT_DIR.mkdir(parents=True, exist_ok=True)
# In-memory job store (Global variable)
# Since HF Spaces (Free) runs 1 replica, this works for a demo.
JOBS = {}
app = FastAPI(title="Depth->STL processing service (Standalone)")
def update_job_status(job_id: str, state: str, detail: str = "", result: str = ""):
JOBS[job_id] = {
"state": state,
"detail": detail,
"result": result
}
@app.get("/health")
def health_check():
return {"status": "ok"}
@app.post("/upload/")
async def upload_image(background_tasks: BackgroundTasks, file: UploadFile = File(...)):
# Basic validation
if not file.content_type.startswith("image/"):
raise HTTPException(status_code=400, detail="File must be an image")
job_id = str(uuid4())
safe_name = Path(file.filename).name
fname = f"{job_id}_{safe_name}"
save_path = UPLOAD_DIR / fname
# Save uploaded file
try:
with save_path.open("wb") as buffer:
shutil.copyfileobj(file.file, buffer)
except Exception as e:
raise HTTPException(status_code=500, detail=f"Failed to save upload: {e}")
# Mark queued
update_job_status(job_id, "QUEUED", "Job received and queued")
# Add to background tasks
background_tasks.add_task(
process_image_task,
str(save_path),
str(RESULT_DIR),
job_id,
update_job_status
)
return {"job_id": job_id}
@app.get("/status/{job_id}")
def status(job_id: str):
from fastapi import FastAPI, UploadFile, File, HTTPException, BackgroundTasks
from fastapi.responses import FileResponse, JSONResponse
from uuid import uuid4
from pathlib import Path
import shutil
import os
import json
from dotenv import load_dotenv
from tasks import process_image_task
load_dotenv()
# Directories
# Use /tmp for Hugging Face Spaces as it is writable
UPLOAD_DIR = Path("/tmp/uploads")
RESULT_DIR = Path("/tmp/results")
UPLOAD_DIR.mkdir(parents=True, exist_ok=True)
RESULT_DIR.mkdir(parents=True, exist_ok=True)
# In-memory job store (Global variable)
# Since HF Spaces (Free) runs 1 replica, this works for a demo.
JOBS = {}
app = FastAPI(title="Depth->STL processing service (Standalone)")
def update_job_status(job_id: str, state: str, detail: str = "", result: str = ""):
JOBS[job_id] = {
"state": state,
"detail": detail,
"result": result
}
@app.get("/health")
def health_check():
return {"status": "ok"}
@app.post("/upload/")
async def upload_image(background_tasks: BackgroundTasks, file: UploadFile = File(...)):
# Basic validation
if not file.content_type.startswith("image/"):
raise HTTPException(status_code=400, detail="File must be an image")
job_id = str(uuid4())
safe_name = Path(file.filename).name
fname = f"{job_id}_{safe_name}"
save_path = UPLOAD_DIR / fname
# Save uploaded file
try:
with save_path.open("wb") as buffer:
shutil.copyfileobj(file.file, buffer)
except Exception as e:
raise HTTPException(status_code=500, detail=f"Failed to save upload: {e}")
# Mark queued
update_job_status(job_id, "QUEUED", "Job received and queued")
# Add to background tasks
background_tasks.add_task(
process_image_task,
str(save_path),
str(RESULT_DIR),
job_id,
update_job_status
)
return {"job_id": job_id}
@app.get("/status/{job_id}")
def status(job_id: str):
job = JOBS.get(job_id)
if not job:
return JSONResponse({"state": "UNKNOWN", "detail": "No such job_id"}, status_code=404)
return JSONResponse(job)
@app.get("/download/{job_id}")
def download(job_id: str):
print(f"[DEBUG] Download request for {job_id}")
job = JOBS.get(job_id)
if not job:
print(f"[DEBUG] Job {job_id} not found in JOBS: {list(JOBS.keys())}")
raise HTTPException(status_code=404, detail="No such job")
if job.get("state") != "SUCCESS":
print(f"[DEBUG] Job {job_id} state is {job.get('state')}")
raise HTTPException(status_code=404, detail="Result not ready")
stl_path = job.get("result")
print(f"[DEBUG] Checking file path: {stl_path}")
if not stl_path or not Path(stl_path).exists():
print(f"[DEBUG] File missing at {stl_path}")
# List dir to see what's there
try:
parent = Path(stl_path).parent
print(f"[DEBUG] Contents of {parent}: {list(parent.glob('*'))}")
except Exception as e:
print(f"[DEBUG] Failed to list dir: {e}")
raise HTTPException(status_code=404, detail=f"Result file missing at {stl_path}")
return FileResponse(path=stl_path, filename=Path(stl_path).name, media_type="application/sla") |