breakpointsoftware/document-parser
0
1name: Call Orchestrator Endpoint2 3on:4 workflow_dispatch:5 inputs:6 model:7 description: OpenAI model name8 required: false9 default: gpt-4o10 include_subfolders:11 description: Include subfolders in Drive scan12 required: false13 default: "true"14 send_to_sheet:15 description: Send rows to Google Sheets16 required: false17 default: "false"18 schedule:19 - cron: '*/5 * * * *'20jobs:21 call-orchestrator:22 runs-on: ubuntu-latest23 timeout-minutes: 124 env:25 ORCHESTRATOR_BASE_URL: ${{ secrets.ORCHESTRATOR_BASE_URL }}26 ORCHESTRATOR_API_KEY: ${{ secrets.ORCHESTRATOR_API_KEY }}27 MODEL_INPUT: ${{ github.event.inputs.model || 'gpt-4o' }}28 INCLUDE_SUBFOLDERS_INPUT: ${{ github.event.inputs.include_subfolders || 'true' }}29 SEND_TO_SHEET_INPUT: ${{ github.event.inputs.send_to_sheet || 'false' }}30 31 steps:32 - name: Validate required secrets33 run: |34 set -euo pipefail35 if [ -z "${ORCHESTRATOR_BASE_URL}" ]; then36 echo "Missing secret: ORCHESTRATOR_BASE_URL"37 exit 138 fi39 if [ -z "${ORCHESTRATOR_API_KEY}" ]; then40 echo "Missing secret: ORCHESTRATOR_API_KEY"41 exit 142 fi43 44 - name: Start orchestrator job (POST)45 id: start46 shell: bash47 run: |48 set -euo pipefail49 python - <<'PY'50 import json51 import os52 import urllib.request53 54 base_url = os.environ["ORCHESTRATOR_BASE_URL"].rstrip("/")55 payload = {56 "data": [57 os.environ["MODEL_INPUT"],58 os.environ["INCLUDE_SUBFOLDERS_INPUT"].lower() == "true",59 os.environ["SEND_TO_SHEET_INPUT"].lower() == "true",60 os.environ["ORCHESTRATOR_API_KEY"],61 ]62 }63 64 req = urllib.request.Request(65 url=f"{base_url}/gradio_api/call/orchestrate_drive_documents",66 data=json.dumps(payload).encode("utf-8"),67 headers={"Content-Type": "application/json"},68 method="POST",69 )70 71 with urllib.request.urlopen(req, timeout=60) as resp:72 body = resp.read().decode("utf-8")73 74 parsed = json.loads(body)75 event_id = parsed.get("event_id")76 if not event_id:77 raise SystemExit(f"POST succeeded but event_id missing. Response: {body}")78 79 with open(os.environ["GITHUB_OUTPUT"], "a", encoding="utf-8") as fh:80 fh.write(f"event_id={event_id}\n")81 82 print("Orchestrator job started.")83 PY84 85 - name: Read orchestrator stream result86 shell: bash87 run: |88 set -euo pipefail89 STREAM_URL="${ORCHESTRATOR_BASE_URL%/}/gradio_api/call/orchestrate_drive_documents/${{ steps.start.outputs.event_id }}"90 curl -sS --max-time 900 -N "$STREAM_URL" > stream.txt91 echo "Stream captured in stream.txt"92 id: stream93 94 - name: Validate orchestrator response95 shell: bash96 run: |97 set -euo pipefail98 python - <<'PY'99 import json100 101 with open("stream.txt", "r", encoding="utf-8") as fh:102 lines = [line.rstrip("\n") for line in fh]103 104 data_lines = [line[6:] for line in lines if line.startswith("data: ")]105 non_null = [line for line in data_lines if line and line != "null"]106 if not non_null:107 raise SystemExit("No non-null data payload found in stream.")108 109 payload = json.loads(non_null[-1])110 if not isinstance(payload, list) or not payload:111 raise SystemExit(f"Unexpected payload shape: {payload}")112 113 result = payload[0]114 ok = bool(result.get("ok")) if isinstance(result, dict) else False115 if not ok:116 raise SystemExit(f"Orchestrator failed: {json.dumps(result, ensure_ascii=False)}")117 118 summary = {119 "ok": result.get("ok"),120 "scanned": result.get("scanned"),121 "to_process": result.get("to_process"),122 "skipped": result.get("skipped"),123 "parsed": result.get("parsed"),124 "modified": result.get("modified"),125 "sent": result.get("sent"),126 "errors_count": len(result.get("errors", [])) if isinstance(result.get("errors"), list) else None,127 }128 print(json.dumps(summary, ensure_ascii=False))129 PY130 