chuckfinca Claude Opus 4.6 (1M context) commited on
Commit
b32f935
·
1 Parent(s): d52caba

Fix file upload: use Gradio upload endpoint for actual file transfer

Browse files

Upload 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>

Files changed (1) hide show
  1. app.py +36 -10
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/call/upload', {
323
  method: 'POST',
324
- headers: { 'Content-Type': 'application/json' },
325
- body: JSON.stringify({ data: [tokenInput.value] })
 
 
 
 
 
 
 
 
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 (validates token, returns confirmation)
469
- upload_input = gr.Textbox(visible=False)
 
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
- return json.dumps({"ok": True})
 
 
 
 
476
 
477
  upload_btn = gr.Button(visible=False)
478
- upload_btn.click(api_upload, inputs=upload_input, outputs=upload_output, api_name="upload")
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)