Сохранять каждый запуск датасета в отдельную папку и показывать прогресс генерации.
Файлы пишутся в sonar_dataset/дата-время-модель без удаления прошлых запусков; кнопка «Генерация…» заполняется по мере записи сцен через NDJSON-стрим. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+27
-16
@@ -11,14 +11,14 @@ from typing import Any
|
||||
|
||||
from fastapi import FastAPI, File, Form, HTTPException, UploadFile
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from fastapi.responses import FileResponse, Response
|
||||
from fastapi.responses import FileResponse, Response, StreamingResponse
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
from pydantic import BaseModel
|
||||
|
||||
from builtin_presets import BUILTIN_PRESETS, get_builtin_preset
|
||||
from demo_generator import DEMO_SURFACE_TYPES, demo_payload
|
||||
from pipeline_insights import compute_insights
|
||||
from dataset_generator import generate_dataset, load_object_points_from_obj_text, load_scene_preview
|
||||
from dataset_generator import iter_generate_dataset, load_object_points_from_obj_text, load_scene_preview
|
||||
from scene_generator import (
|
||||
catalog_payload as generator_catalog_payload,
|
||||
export_npy_float64,
|
||||
@@ -429,7 +429,7 @@ async def dataset_generate(
|
||||
beamCount: int = Form(45),
|
||||
lengthCount: int | None = Form(None),
|
||||
model: UploadFile = File(...),
|
||||
) -> dict[str, Any]:
|
||||
) -> StreamingResponse:
|
||||
filename = (model.filename or "").strip()
|
||||
if not filename.lower().endswith(".obj"):
|
||||
raise HTTPException(status_code=400, detail="Upload a .obj 3D model file.")
|
||||
@@ -437,21 +437,32 @@ async def dataset_generate(
|
||||
raw = await model.read()
|
||||
text = raw.decode("utf-8", errors="ignore")
|
||||
object_points = load_object_points_from_obj_text(text)
|
||||
return generate_dataset(
|
||||
count=count,
|
||||
seed=seed,
|
||||
output_dir=outputDir or "sonar_dataset",
|
||||
object_points=object_points,
|
||||
object_name=filename,
|
||||
object_scale=objectScale,
|
||||
object_scale_is_max=objectScaleIsMax,
|
||||
beam_count=beamCount,
|
||||
length_count=lengthCount,
|
||||
)
|
||||
except ValueError as exc:
|
||||
raise HTTPException(status_code=400, detail=str(exc)) from exc
|
||||
except OSError as exc:
|
||||
raise HTTPException(status_code=500, detail=f"Failed to write dataset: {exc}") from exc
|
||||
|
||||
def event_stream():
|
||||
try:
|
||||
for event in iter_generate_dataset(
|
||||
count=count,
|
||||
seed=seed,
|
||||
output_dir=outputDir or "sonar_dataset",
|
||||
object_points=object_points,
|
||||
object_name=filename,
|
||||
object_scale=objectScale,
|
||||
object_scale_is_max=objectScaleIsMax,
|
||||
beam_count=beamCount,
|
||||
length_count=lengthCount,
|
||||
):
|
||||
yield json.dumps(event, ensure_ascii=False) + "\n"
|
||||
except ValueError as exc:
|
||||
yield json.dumps({"type": "error", "detail": str(exc)}, ensure_ascii=False) + "\n"
|
||||
except OSError as exc:
|
||||
yield json.dumps(
|
||||
{"type": "error", "detail": f"Failed to write dataset: {exc}"},
|
||||
ensure_ascii=False,
|
||||
) + "\n"
|
||||
|
||||
return StreamingResponse(event_stream(), media_type="application/x-ndjson")
|
||||
|
||||
|
||||
@app.post("/api/dataset/preview")
|
||||
|
||||
Reference in New Issue
Block a user