Spaces:
Runtime error
Runtime error
Upload 33 files
Browse files- server.py +17 -7
- ui_kits/chan-compass/views.jsx +18 -3
server.py
CHANGED
|
@@ -311,10 +311,16 @@ async def export_dataset():
|
|
| 311 |
path = finetune_data.export()
|
| 312 |
if not path:
|
| 313 |
return JSONResponse({"path": "", "count": 0, "download": ""})
|
| 314 |
-
#
|
|
|
|
| 315 |
import shutil
|
| 316 |
-
|
| 317 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 318 |
fname = os.path.basename(path)
|
| 319 |
try:
|
| 320 |
shutil.copy(path, os.path.join(served_dir, fname))
|
|
@@ -326,10 +332,14 @@ async def export_dataset():
|
|
| 326 |
|
| 327 |
@app.get("/download/{fname}")
|
| 328 |
async def download_file(fname: str):
|
| 329 |
-
|
| 330 |
-
if
|
| 331 |
-
|
| 332 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 333 |
return JSONResponse({"error": "not found"}, status_code=404)
|
| 334 |
|
| 335 |
|
|
|
|
| 311 |
path = finetune_data.export()
|
| 312 |
if not path:
|
| 313 |
return JSONResponse({"path": "", "count": 0, "download": ""})
|
| 314 |
+
# Copy into a WRITABLE served dir. In Docker, /app is read-only for the
|
| 315 |
+
# non-root user, so use /data (persistent) when available, else the temp dir.
|
| 316 |
import shutil
|
| 317 |
+
import tempfile
|
| 318 |
+
base = paths.DATA_ROOT if paths.PERSISTENT else tempfile.gettempdir()
|
| 319 |
+
served_dir = os.path.join(base, "exports")
|
| 320 |
+
try:
|
| 321 |
+
os.makedirs(served_dir, exist_ok=True)
|
| 322 |
+
except OSError:
|
| 323 |
+
served_dir = tempfile.gettempdir()
|
| 324 |
fname = os.path.basename(path)
|
| 325 |
try:
|
| 326 |
shutil.copy(path, os.path.join(served_dir, fname))
|
|
|
|
| 332 |
|
| 333 |
@app.get("/download/{fname}")
|
| 334 |
async def download_file(fname: str):
|
| 335 |
+
import tempfile
|
| 336 |
+
base = paths.DATA_ROOT if paths.PERSISTENT else tempfile.gettempdir()
|
| 337 |
+
fname = os.path.basename(fname)
|
| 338 |
+
for d in (os.path.join(base, "exports"), os.path.join(tempfile.gettempdir(), "exports"),
|
| 339 |
+
tempfile.gettempdir()):
|
| 340 |
+
served = os.path.join(d, fname)
|
| 341 |
+
if os.path.exists(served):
|
| 342 |
+
return FileResponse(served, filename=fname, media_type="application/jsonl")
|
| 343 |
return JSONResponse({"error": "not found"}, status_code=404)
|
| 344 |
|
| 345 |
|
ui_kits/chan-compass/views.jsx
CHANGED
|
@@ -428,9 +428,24 @@ function ModelView() {
|
|
| 428 |
};
|
| 429 |
const [dlUrl, setDlUrl] = useState("");
|
| 430 |
const exportDs = async () => {
|
| 431 |
-
|
| 432 |
-
|
| 433 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 434 |
};
|
| 435 |
return (
|
| 436 |
<div style={{display:"flex", flexDirection:"column", gap:"var(--space-300)"}}>
|
|
|
|
| 428 |
};
|
| 429 |
const [dlUrl, setDlUrl] = useState("");
|
| 430 |
const exportDs = async () => {
|
| 431 |
+
setDl("⏳ Exporting…"); setDlUrl("");
|
| 432 |
+
try {
|
| 433 |
+
const r = await API.exportDataset();
|
| 434 |
+
if (r && r.download) {
|
| 435 |
+
setDl("✅ Exported " + r.count + " pairs.");
|
| 436 |
+
setDlUrl(r.download);
|
| 437 |
+
// also trigger the download immediately
|
| 438 |
+
const a = document.createElement("a");
|
| 439 |
+
a.href = r.download; a.download = "";
|
| 440 |
+
document.body.appendChild(a); a.click(); a.remove();
|
| 441 |
+
} else {
|
| 442 |
+
setDl("No pairs captured yet — run a few Signals AI interprets first.");
|
| 443 |
+
setDlUrl("");
|
| 444 |
+
}
|
| 445 |
+
} catch (e) {
|
| 446 |
+
setDl("❌ Export failed: " + e.message);
|
| 447 |
+
setDlUrl("");
|
| 448 |
+
}
|
| 449 |
};
|
| 450 |
return (
|
| 451 |
<div style={{display:"flex", flexDirection:"column", gap:"var(--space-300)"}}>
|