EmilySun621 opened a new pull request, #5121:
URL: https://github.com/apache/texera/pull/5121
<h2 class="text-text-100 mt-3 -mb-1 text-[1.125rem] font-bold">The
Problem</h2>
<p class="font-claude-response-body break-words whitespace-normal
leading-[1.7]">You built an amazing diabetes prediction workflow. It works
perfectly. But now your hospital's patient intake system needs to call it in
real-time — and there's no way to expose your workflow as an API.</p>
<p class="font-claude-response-body break-words whitespace-normal
leading-[1.7]"><strong>Texera workflows are locked inside the browser.</strong>
No external system can call them.</p>
<h2 class="text-text-100 mt-3 -mb-1 text-[1.125rem] font-bold">The
Solution</h2>
<p class="font-claude-response-body break-words whitespace-normal
leading-[1.7]"><strong>One click turns any workflow into a REST
endpoint.</strong></p>
<div role="group" aria-label="Code" tabindex="0" class="relative group/copy
bg-bg-000/50 border-0.5 border-border-400 rounded-lg focus:outline-none
focus-visible:ring-2 focus-visible:ring-accent-100"><div class="sticky
opacity-0 group-hover/copy:opacity-100 group-focus-within/copy:opacity-100
top-2 py-2 h-12 w-0 float-right"><div class="absolute right-0 h-8 px-2
items-center inline-flex z-10"><button class="inline-flex
items-center
justify-center
relative
isolate
shrink-0
can-focus
select-none
disabled:pointer-events-none
disabled:opacity-50
disabled:shadow-none
disabled:drop-shadow-none border-transparent
transition
font-base
duration-300
ease-[cubic-bezier(0.165,0.85,0.45,1)] h-8 w-8 rounded-md
backdrop-blur-md _fill_10ocf_9 _ghost_10ocf_96" type="button" aria-label="Copy
to clipboard" data-state="closed"><div class="relative"><div
class="transition-all opacity-100 scale-100" style="width: 20px; height: 20px;
display: flex; align-items: center; justify-content: center;"><svg width="20"
height="20" viewBox="0 0 20 20" fill="currentColor"
xmlns="http://www.w3.org/2000/svg" class="transition-all opacity-100 scale-100"
aria-hidden="true" style="flex-shrink: 0;"><path d="M12.5 3A1.5 1.5 0 0 1 14
4.5V6h1.5A1.5 1.5 0 0 1 17 7.5v8a1.5 1.5 0 0 1-1.5 1.5h-8A1.5 1.5 0 0 1 6
15.5V14H4.5A1.5 1.5 0 0 1 3 12.5v-8A1.5 1.5 0 0 1 4.5 3zm1.5 9.5a1.5 1.5 0 0
1-1.5 1.5H7v1.5a.5.5 0 0 0 .5.5h8a.5.5 0 0 0 .5-.5v-8a.5.5 0 0 0-.5-.5H14zM4.5
4a.5.5 0 0 0-.5.5v8a.5.5 0 0 0 .5.5h8a.5.5 0 0 0 .5-.5v-8a.5.5 0 0
0-.5-.5z"></path></svg></div><div class="absolute inset-0 flex items-center
justify-center"><div class="transition-all opaci
ty-0 scale-50" style="width: 20px; height: 20px; display: flex; align-items:
center; justify-content: center;"><svg width="20" height="20" viewBox="0 0 20
20" fill="currentColor" xmlns="http://www.w3.org/2000/svg"
class="transition-all opacity-0 scale-50" aria-hidden="true"
style="flex-shrink: 0;"><path d="M15.188 5.11a.5.5 0 0 1 .752.626l-.056.084-7.5
9a.5.5 0 0 1-.738.033l-3.5-3.5-.064-.078a.501.501 0 0 1 .693-.693l.078.064
3.113 3.113
7.15-8.58z"></path></svg></div></div></div></button></div></div><div
class="overflow-x-auto"><pre class="code-block__code !my-0 !rounded-lg !text-sm
!leading-relaxed p-3.5" style="color: rgb(234, 236, 240); background:
transparent; font-family: var(--font-mono);"><code style="color: rgb(234, 236,
240); background: transparent; font-family: var(--font-mono); white-space:
pre-wrap;"><span><span>┌────────────────────────────────────────────────────
─────┐
</span></span><span>│ Workflow Editor
│
</span><span>│ │
</span><span>│ [CSV] → [Clean] → [Split] → [Model] → [Eval] │
</span><span>│ │
</span><span>│ Click: 🌐 Publish as API │
</span><span>└──────────────────────────────┬──────────────────────────┘
</span><span> │
</span><span> ▼
</span><span>┌─────────────────────────────────────────────────────────┐
</span><span>│ Published API │
</span><span>│ │
</span><span>│ POST /api/published/7/run │
</span><span>│ X-API-Key: tex_bbfe69fb... │
</span><span>│ │
</span><span>│ → Returns cached execution results as JSON │
</span><span>└─────────────────────────────────────────────────────────┘</span></code></pre></div></div>
<h2 class="text-text-100 mt-3 -mb-1 text-[1.125rem] font-bold">How It
Works</h2>
<ol class="[li_&]:mb-0 [li_&]:mt-1 [li_&]:gap-1
[&:not(:last-child)_ul]:pb-1 [&:not(:last-child)_ol]:pb-1 list-decimal
flex flex-col gap-1 pl-8 mb-3">
<li class="font-claude-response-body whitespace-normal break-words
pl-2"><strong>Run your workflow</strong> — execute it once to cache results</li>
<li class="font-claude-response-body whitespace-normal break-words
pl-2"><strong>Click 🌐 Publish as API</strong> — generates endpoint URL + API
key</li>
<li class="font-claude-response-body whitespace-normal break-words
pl-2"><strong>Share the curl command</strong> — any external system can fetch
your results</li>
</ol>
<div role="group" aria-label="bash code" tabindex="0" class="relative
group/copy bg-bg-000/50 border-0.5 border-border-400 rounded-lg
focus:outline-none focus-visible:ring-2 focus-visible:ring-accent-100"><div
class="sticky opacity-0 group-hover/copy:opacity-100
group-focus-within/copy:opacity-100 top-2 py-2 h-12 w-0 float-right"><div
class="absolute right-0 h-8 px-2 items-center inline-flex z-10"><button
class="inline-flex
items-center
justify-center
relative
isolate
shrink-0
can-focus
select-none
disabled:pointer-events-none
disabled:opacity-50
disabled:shadow-none
disabled:drop-shadow-none border-transparent
transition
font-base
duration-300
ease-[cubic-bezier(0.165,0.85,0.45,1)] h-8 w-8 rounded-md
backdrop-blur-md _fill_10ocf_9 _ghost_10ocf_96" type="button" aria-label="Copy
to clipboard" data-state="closed"><div class="relative"><div
class="transition-all opacity-100 scale-100" style="width: 20px; height: 20px;
display: flex; align-items: center; justify-content: center;"><svg width="20"
height="20" viewBox="0 0 20 20" fill="currentColor"
xmlns="http://www.w3.org/2000/svg" class="transition-all opacity-100 scale-100"
aria-hidden="true" style="flex-shrink: 0;"><path d="M12.5 3A1.5 1.5 0 0 1 14
4.5V6h1.5A1.5 1.5 0 0 1 17 7.5v8a1.5 1.5 0 0 1-1.5 1.5h-8A1.5 1.5 0 0 1 6
15.5V14H4.5A1.5 1.5 0 0 1 3 12.5v-8A1.5 1.5 0 0 1 4.5 3zm1.5 9.5a1.5 1.5 0 0
1-1.5 1.5H7v1.5a.5.5 0 0 0 .5.5h8a.5.5 0 0 0 .5-.5v-8a.5.5 0 0 0-.5-.5H14zM4.5
4a.5.5 0 0 0-.5.5v8a.5.5 0 0 0 .5.5h8a.5.5 0 0 0 .5-.5v-8a.5.5 0 0
0-.5-.5z"></path></svg></div><div class="absolute inset-0 flex items-center
justify-center"><div class="transition-all opaci
ty-0 scale-50" style="width: 20px; height: 20px; display: flex; align-items:
center; justify-content: center;"><svg width="20" height="20" viewBox="0 0 20
20" fill="currentColor" xmlns="http://www.w3.org/2000/svg"
class="transition-all opacity-0 scale-50" aria-hidden="true"
style="flex-shrink: 0;"><path d="M15.188 5.11a.5.5 0 0 1 .752.626l-.056.084-7.5
9a.5.5 0 0 1-.738.033l-3.5-3.5-.064-.078a.501.501 0 0 1 .693-.693l.078.064
3.113 3.113
7.15-8.58z"></path></svg></div></div></div></button></div></div><div
class="text-text-500 font-small p-3.5 pb-0">bash</div><div
class="overflow-x-auto"><pre class="code-block__code !my-0 !rounded-lg !text-sm
!leading-relaxed p-3.5" style="color: rgb(234, 236, 240); background:
transparent; font-family: var(--font-mono);"><code class="language-bash"
style="color: rgb(234, 236, 240); background: transparent; font-family:
var(--font-mono); white-space: pre;"><span><span class="token token"
style="color: rgb(112, 184, 255);">curl</span><span> -X POST </
span><span class="token token" style="color: rgb(155, 233,
99);">'http://localhost:4200/api/published/7/run'</span><span> </span><span
class="token token" style="color: rgb(211, 215, 222);">\</span><span>
</span></span><span><span> -H </span><span class="token token"
style="color: rgb(155, 233, 99);">'X-API-Key: tex_bbfe69fb...'</span><span>
</span><span class="token token" style="color: rgb(211, 215,
222);">\</span><span>
</span></span><span><span> -H </span><span class="token token"
style="color: rgb(155, 233, 99);">'Content-Type:
application/json'</span></span></code></pre></div></div>
<p class="font-claude-response-body break-words whitespace-normal
leading-[1.7]"><strong>Response:</strong></p>
<div role="group" aria-label="json code" tabindex="0" class="relative
group/copy bg-bg-000/50 border-0.5 border-border-400 rounded-lg
focus:outline-none focus-visible:ring-2 focus-visible:ring-accent-100"><div
class="sticky opacity-0 group-hover/copy:opacity-100
group-focus-within/copy:opacity-100 top-2 py-2 h-12 w-0 float-right"><div
class="absolute right-0 h-8 px-2 items-center inline-flex z-10"><button
class="inline-flex
items-center
justify-center
relative
isolate
shrink-0
can-focus
select-none
disabled:pointer-events-none
disabled:opacity-50
disabled:shadow-none
disabled:drop-shadow-none border-transparent
transition
font-base
duration-300
ease-[cubic-bezier(0.165,0.85,0.45,1)] h-8 w-8 rounded-md
backdrop-blur-md _fill_10ocf_9 _ghost_10ocf_96" type="button" aria-label="Copy
to clipboard" data-state="closed"><div class="relative"><div
class="transition-all opacity-100 scale-100" style="width: 20px; height: 20px;
display: flex; align-items: center; justify-content: center;"><svg width="20"
height="20" viewBox="0 0 20 20" fill="currentColor"
xmlns="http://www.w3.org/2000/svg" class="transition-all opacity-100 scale-100"
aria-hidden="true" style="flex-shrink: 0;"><path d="M12.5 3A1.5 1.5 0 0 1 14
4.5V6h1.5A1.5 1.5 0 0 1 17 7.5v8a1.5 1.5 0 0 1-1.5 1.5h-8A1.5 1.5 0 0 1 6
15.5V14H4.5A1.5 1.5 0 0 1 3 12.5v-8A1.5 1.5 0 0 1 4.5 3zm1.5 9.5a1.5 1.5 0 0
1-1.5 1.5H7v1.5a.5.5 0 0 0 .5.5h8a.5.5 0 0 0 .5-.5v-8a.5.5 0 0 0-.5-.5H14zM4.5
4a.5.5 0 0 0-.5.5v8a.5.5 0 0 0 .5.5h8a.5.5 0 0 0 .5-.5v-8a.5.5 0 0
0-.5-.5z"></path></svg></div><div class="absolute inset-0 flex items-center
justify-center"><div class="transition-all opaci
ty-0 scale-50" style="width: 20px; height: 20px; display: flex; align-items:
center; justify-content: center;"><svg width="20" height="20" viewBox="0 0 20
20" fill="currentColor" xmlns="http://www.w3.org/2000/svg"
class="transition-all opacity-0 scale-50" aria-hidden="true"
style="flex-shrink: 0;"><path d="M15.188 5.11a.5.5 0 0 1 .752.626l-.056.084-7.5
9a.5.5 0 0 1-.738.033l-3.5-3.5-.064-.078a.501.501 0 0 1 .693-.693l.078.064
3.113 3.113
7.15-8.58z"></path></svg></div></div></div></button></div></div><div
class="text-text-500 font-small p-3.5 pb-0">json</div><div
class="overflow-x-auto"><pre class="code-block__code !my-0 !rounded-lg !text-sm
!leading-relaxed p-3.5" style="color: rgb(234, 236, 240); background:
transparent; font-family: var(--font-mono);"><code class="language-json"
style="color: rgb(234, 236, 240); background: transparent; font-family:
var(--font-mono); white-space: pre;"><span><span class="token token"
style="color: rgb(211, 215, 222);">{</span><span>
</span></span><span><span> </span><span class="token token" style="color:
rgb(244, 123, 133);">"workflowId"</span><span class="token token" style="color:
rgb(234, 236, 240);">:</span><span> </span><span class="token token"
style="color: rgb(94, 237, 237);">7</span><span class="token token"
style="color: rgb(211, 215, 222);">,</span><span>
</span></span><span><span> </span><span class="token token" style="color:
rgb(244, 123, 133);">"workflowName"</span><span class="token token"
style="color: rgb(234, 236, 240);">:</span><span> </span><span class="token
token" style="color: rgb(155, 233, 99);">"[Example] Data Exploration on Movies
Dataset"</span><span class="token token" style="color: rgb(211, 215,
222);">,</span><span>
</span></span><span><span> </span><span class="token token" style="color:
rgb(244, 123, 133);">"executedAt"</span><span class="token token" style="color:
rgb(234, 236, 240);">:</span><span> </span><span class="token token"
style="color: rgb(155, 233, 99);">"2026-05-17T05:47:29.799Z"</span><span
class="token token" style="color: rgb(211, 215, 222);">,</span><span>
</span></span><span><span> </span><span class="token token" style="color:
rgb(244, 123, 133);">"results"</span><span class="token token" style="color:
rgb(234, 236, 240);">:</span><span> </span><span class="token token"
style="color: rgb(211, 215, 222);">{</span><span> ... </span><span class="token
token" style="color: rgb(211, 215, 222);">}</span><span>
</span></span><span><span></span><span class="token token" style="color:
rgb(211, 215, 222);">}</span></span></code></pre></div></div>
<h2 class="text-text-100 mt-3 -mb-1 text-[1.125rem] font-bold">Key Design
Decisions</h2>
<div class="overflow-x-auto w-full px-2 mb-6">
Decision | Choice | Why
-- | -- | --
Execution model | Return cached results | No long-running HTTP requests;
instant response
Auth | Per-workflow API key | Simple, stateless, no OAuth complexity
Storage | In-memory + localStorage | Hackathon speed; production would use DB
Scope | Read-only | Safe — external clients can't modify workflows
</div>
<h2 class="text-text-100 mt-3 -mb-1 text-[1.125rem] font-bold">What's
Included</h2>
<p class="font-claude-response-body break-words whitespace-normal
leading-[1.7]"><strong>Backend (agent-service):</strong></p>
<ul class="[li_&]:mb-0 [li_&]:mt-1 [li_&]:gap-1
[&:not(:last-child)_ul]:pb-1 [&:not(:last-child)_ol]:pb-1 list-disc
flex flex-col gap-1 pl-8 mb-3">
<li class="font-claude-response-body whitespace-normal break-words
pl-2"><code class="bg-text-200/5 border border-0.5 border-border-300
text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px
text-[0.9rem]">published-workflow-api.ts</code> — POST <code
class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000
whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">/register</code>
+ POST <code class="bg-text-200/5 border border-0.5 border-border-300
text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px
text-[0.9rem]">/:workflowId/run</code></li>
<li class="font-claude-response-body whitespace-normal break-words pl-2">API
key validation (401 missing / 403 mismatch / 404 unpublished)</li>
<li class="font-claude-response-body whitespace-normal break-words pl-2">5
unit tests, all passing</li>
</ul>
<p class="font-claude-response-body break-words whitespace-normal
leading-[1.7]"><strong>Frontend:</strong></p>
<ul class="[li_&]:mb-0 [li_&]:mt-1 [li_&]:gap-1
[&:not(:last-child)_ul]:pb-1 [&:not(:last-child)_ol]:pb-1 list-disc
flex flex-col gap-1 pl-8 mb-3">
<li class="font-claude-response-body whitespace-normal break-words pl-2">🌐
icon button in workflow editor toolbar</li>
<li class="font-claude-response-body whitespace-normal break-words
pl-2">Publish dialog: endpoint URL, masked API key (show/hide + copy), sample
curl</li>
<li class="font-claude-response-body whitespace-normal break-words
pl-2">Refuses to publish if no cached results exist</li>
</ul>
<h2 class="text-text-100 mt-3 -mb-1 text-[1.125rem] font-bold">Use Cases</h2>
<ul class="[li_&]:mb-0 [li_&]:mt-1 [li_&]:gap-1
[&:not(:last-child)_ul]:pb-1 [&:not(:last-child)_ol]:pb-1 list-disc
flex flex-col gap-1 pl-8 mb-3">
<li class="font-claude-response-body whitespace-normal break-words pl-2">🏥
Hospital system calls your prediction workflow for real-time patient risk
scoring</li>
<li class="font-claude-response-body whitespace-normal break-words pl-2">📱
Mobile app calls your NLP workflow to analyze user-reported symptoms</li>
<li class="font-claude-response-body whitespace-normal break-words pl-2">🔄
Another team's pipeline calls your data cleaning workflow</li>
<li class="font-claude-response-body whitespace-normal break-words pl-2">⏰
Cron job curls your workflow daily for automated reporting</li>
</ul>
<p class="font-claude-response-body break-words whitespace-normal
leading-[1.7]"><strong>Any workflow becomes a microservice.</strong></p>
<h2 class="text-text-100 mt-3 -mb-1 text-[1.125rem] font-bold">Demo</h2>
<ol class="[li_&]:mb-0 [li_&]:mt-1 [li_&]:gap-1
[&:not(:last-child)_ul]:pb-1 [&:not(:last-child)_ol]:pb-1 list-decimal
flex flex-col gap-1 pl-8 mb-3">
<li class="font-claude-response-body whitespace-normal break-words
pl-2">Open a workflow that has been executed → toolbar shows 🌐 button</li>
<li class="font-claude-response-body whitespace-normal break-words
pl-2">Click 🌐 → dialog with endpoint, API key, curl command</li>
<li class="font-claude-response-body whitespace-normal break-words
pl-2">Copy curl → run in terminal → JSON results returned instantly</li></ol>
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]