Сохранять каждый запуск датасета в отдельную папку и показывать прогресс генерации.

Файлы пишутся в sonar_dataset/дата-время-модель без удаления прошлых запусков; кнопка «Генерация…» заполняется по мере записи сцен через NDJSON-стрим.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-17 15:30:07 +03:00
co-authored by Cursor
parent 643d834ba7
commit 8b248e1d54
5 changed files with 258 additions and 42 deletions
+27 -16
View File
@@ -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")