t29mato Claude Opus 4.6 commited on
Commit
cd3f7fd
·
1 Parent(s): d868632

Add base64 API endpoint for programmatic access

Browse files

- digitize_chart now accepts both PIL Image and base64 strings
- Add /api/digitize_base64 endpoint using gr.Textbox inputs
so external clients can send base64 without Gradio file upload

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Files changed (1) hide show
  1. api_server.py +35 -2
api_server.py CHANGED
@@ -33,10 +33,12 @@ import cv2
33
  import numpy as np
34
  import json
35
  import io
 
36
  import zipfile
37
  import urllib.request
38
  import ssl
39
  import gradio as gr
 
40
  from datetime import datetime, timezone
41
 
42
  # ============================================================
@@ -323,8 +325,17 @@ def digitize_chart(
323
  if image is None:
324
  return json.dumps({"error": "No image provided"})
325
 
326
- # Convert PIL Image to BGR numpy array
327
- img_rgb = np.array(image)
 
 
 
 
 
 
 
 
 
328
  img_bgr = cv2.cvtColor(img_rgb, cv2.COLOR_RGB2BGR)
329
 
330
  # Extract lines
@@ -433,6 +444,28 @@ def create_app():
433
  outputs=[output, file_output],
434
  )
435
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
436
  return demo
437
 
438
 
 
33
  import numpy as np
34
  import json
35
  import io
36
+ import base64
37
  import zipfile
38
  import urllib.request
39
  import ssl
40
  import gradio as gr
41
+ from PIL import Image
42
  from datetime import datetime, timezone
43
 
44
  # ============================================================
 
325
  if image is None:
326
  return json.dumps({"error": "No image provided"})
327
 
328
+ # Accept both PIL Image and base64 string
329
+ if isinstance(image, str):
330
+ # Strip data URI prefix if present (e.g. "data:image/png;base64,...")
331
+ if "," in image:
332
+ image = image.split(",", 1)[1]
333
+ img_bytes = base64.b64decode(image)
334
+ pil_img = Image.open(io.BytesIO(img_bytes)).convert("RGB")
335
+ img_rgb = np.array(pil_img)
336
+ else:
337
+ img_rgb = np.array(image)
338
+
339
  img_bgr = cv2.cvtColor(img_rgb, cv2.COLOR_RGB2BGR)
340
 
341
  # Extract lines
 
444
  outputs=[output, file_output],
445
  )
446
 
447
+ # Programmatic API endpoint that accepts base64 string directly
448
+ # This avoids Gradio's file upload requirement for gr.Image
449
+ api_image_input = gr.Textbox(visible=False)
450
+ api_auto_axis = gr.Checkbox(value=True, visible=False)
451
+ api_downsample = gr.Textbox(value="arc_length", visible=False)
452
+ api_max_pts = gr.Number(value=20, visible=False)
453
+ api_fixed_stp = gr.Number(value=10, visible=False)
454
+ api_sort = gr.Textbox(value="mean_y_desc", visible=False)
455
+ api_out_fmt = gr.Textbox(value="starry_digitizer_json", visible=False)
456
+ api_output = gr.Textbox(visible=False)
457
+
458
+ def api_digitize(image_base64, auto_axis, downsample, max_pts, fixed_stp, sort, out_fmt):
459
+ return digitize_chart(image_base64, auto_axis, downsample, int(max_pts), int(fixed_stp), sort, out_fmt)
460
+
461
+ api_btn = gr.Button(visible=False, elem_id="api_btn")
462
+ api_btn.click(
463
+ fn=api_digitize,
464
+ inputs=[api_image_input, api_auto_axis, api_downsample, api_max_pts, api_fixed_stp, api_sort, api_out_fmt],
465
+ outputs=[api_output],
466
+ api_name="digitize_base64",
467
+ )
468
+
469
  return demo
470
 
471