Spaces:
Running
Running
Commit ·
b32f935
1
Parent(s): d52caba
Fix file upload: use Gradio upload endpoint for actual file transfer
Browse filesUpload files to /gradio_api/upload first to get server paths,
then pass those to the setup endpoint which creates the workspace.
Workspace path persists across questions in the session.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
app.py
CHANGED
|
@@ -316,25 +316,46 @@ CUSTOM_HTML = """
|
|
| 316 |
startBtn.disabled = true;
|
| 317 |
startBtn.textContent = 'Uploading...';
|
| 318 |
|
|
|
|
| 319 |
var formData = new FormData();
|
| 320 |
selectedFiles.forEach(function(f) { formData.append('files', f); });
|
| 321 |
|
| 322 |
-
fetch(API_BASE + '/gradio_api/
|
| 323 |
method: 'POST',
|
| 324 |
-
|
| 325 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 326 |
})
|
| 327 |
.then(function(r) { return r.json(); })
|
| 328 |
.then(function(result) {
|
| 329 |
return fetch(API_BASE + '/gradio_api/call/upload/' + result.event_id);
|
| 330 |
})
|
| 331 |
.then(function(r) { return r.text(); })
|
| 332 |
-
.then(function() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 333 |
setupPanel.style.display = 'none';
|
| 334 |
chatPanel.style.display = 'block';
|
| 335 |
chatInput.focus();
|
| 336 |
})
|
| 337 |
-
.catch(function() {
|
|
|
|
| 338 |
startBtn.disabled = false;
|
| 339 |
startBtn.textContent = 'Start exploring';
|
| 340 |
});
|
|
@@ -465,17 +486,22 @@ def build_app() -> gr.Blocks:
|
|
| 465 |
api_name="ask",
|
| 466 |
)
|
| 467 |
|
| 468 |
-
# Upload endpoint
|
| 469 |
-
|
|
|
|
| 470 |
upload_output = gr.Textbox(visible=False)
|
| 471 |
|
| 472 |
-
def api_upload(token):
|
| 473 |
if ACCESS_TOKEN and token != ACCESS_TOKEN:
|
| 474 |
return json.dumps({"error": "Invalid access token."})
|
| 475 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 476 |
|
| 477 |
upload_btn = gr.Button(visible=False)
|
| 478 |
-
upload_btn.click(api_upload, inputs=
|
| 479 |
|
| 480 |
# Document viewer endpoint
|
| 481 |
doc_input = gr.Textbox(visible=False)
|
|
|
|
| 316 |
startBtn.disabled = true;
|
| 317 |
startBtn.textContent = 'Uploading...';
|
| 318 |
|
| 319 |
+
// Step 1: Upload files to Gradio's file endpoint
|
| 320 |
var formData = new FormData();
|
| 321 |
selectedFiles.forEach(function(f) { formData.append('files', f); });
|
| 322 |
|
| 323 |
+
fetch(API_BASE + '/gradio_api/upload', {
|
| 324 |
method: 'POST',
|
| 325 |
+
body: formData
|
| 326 |
+
})
|
| 327 |
+
.then(function(r) { return r.json(); })
|
| 328 |
+
.then(function(uploadedPaths) {
|
| 329 |
+
// Step 2: Call our setup endpoint with the server file paths
|
| 330 |
+
return fetch(API_BASE + '/gradio_api/call/upload', {
|
| 331 |
+
method: 'POST',
|
| 332 |
+
headers: { 'Content-Type': 'application/json' },
|
| 333 |
+
body: JSON.stringify({ data: [tokenInput.value, uploadedPaths] })
|
| 334 |
+
});
|
| 335 |
})
|
| 336 |
.then(function(r) { return r.json(); })
|
| 337 |
.then(function(result) {
|
| 338 |
return fetch(API_BASE + '/gradio_api/call/upload/' + result.event_id);
|
| 339 |
})
|
| 340 |
.then(function(r) { return r.text(); })
|
| 341 |
+
.then(function(text) {
|
| 342 |
+
var lines = text.split('\\n');
|
| 343 |
+
var dataLine = lines.find(function(l) { return l.startsWith('data:'); });
|
| 344 |
+
var parsed = JSON.parse(dataLine.substring(5).trim());
|
| 345 |
+
var data = JSON.parse(Array.isArray(parsed) ? parsed[0] : parsed);
|
| 346 |
+
if (data.error) {
|
| 347 |
+
startBtn.disabled = false;
|
| 348 |
+
startBtn.textContent = 'Start exploring';
|
| 349 |
+
alert(data.error);
|
| 350 |
+
return;
|
| 351 |
+
}
|
| 352 |
+
workspacePath = data.workspace_path;
|
| 353 |
setupPanel.style.display = 'none';
|
| 354 |
chatPanel.style.display = 'block';
|
| 355 |
chatInput.focus();
|
| 356 |
})
|
| 357 |
+
.catch(function(err) {
|
| 358 |
+
console.error(err);
|
| 359 |
startBtn.disabled = false;
|
| 360 |
startBtn.textContent = 'Start exploring';
|
| 361 |
});
|
|
|
|
| 486 |
api_name="ask",
|
| 487 |
)
|
| 488 |
|
| 489 |
+
# Upload endpoint — accepts file paths from Gradio's /upload, creates workspace
|
| 490 |
+
upload_token_input = gr.Textbox(visible=False)
|
| 491 |
+
upload_files_input = gr.File(visible=False, file_count="multiple")
|
| 492 |
upload_output = gr.Textbox(visible=False)
|
| 493 |
|
| 494 |
+
def api_upload(token, files):
|
| 495 |
if ACCESS_TOKEN and token != ACCESS_TOKEN:
|
| 496 |
return json.dumps({"error": "Invalid access token."})
|
| 497 |
+
if not files:
|
| 498 |
+
return json.dumps({"error": "No files provided."})
|
| 499 |
+
file_paths = [f.name if hasattr(f, 'name') else str(f) for f in files]
|
| 500 |
+
workspace = save_uploaded_files(file_paths)
|
| 501 |
+
return json.dumps({"workspace_path": str(workspace), "file_count": len(file_paths)})
|
| 502 |
|
| 503 |
upload_btn = gr.Button(visible=False)
|
| 504 |
+
upload_btn.click(api_upload, inputs=[upload_token_input, upload_files_input], outputs=upload_output, api_name="upload")
|
| 505 |
|
| 506 |
# Document viewer endpoint
|
| 507 |
doc_input = gr.Textbox(visible=False)
|