Skip to content

[Feature] create_and_wait helpers for Flows generations and template runs - #889

Open
brandonrule11 wants to merge 2 commits into
mainfrom
brandonrule/flo-350-sdk-create_and_wait-helpers-for-flows-generations-and
Open

brandonrule11 wants to merge 2 commits into
mainfrom
brandonrule/flo-350-sdk-create_and_wait-helpers-for-flows-generations-and

Conversation

@brandonrule11

Copy link
Copy Markdown

FLO-350: quickstarts should get a Flows result in one call, without a hand-written poll loop or webhook plumbing (like OpenAI's create_and_poll). _should_retry only covers 408/409/429/5xx, so an in-progress 200 returns straight away. JS counterpart: elevenlabs/elevenlabs-js#469.

Usage

gen = client.flows.image.create_and_wait(request=ImageGenerationRequest_BytedanceSeedream5Lite(prompt="a corgi"))
run = client.flows.templates.runs.create_and_wait("template_id", inputs={}, timeout=600)

Design

  • New src/elevenlabs/flows_custom.py, added to .fernignore. Subclasses of the generated flows, templates, runs, image, video and TTS clients, sync and async. client.py sets self._flows to the wrapper, the same pattern as music/STT/speech engine.
  • Create and every GET go through with_raw_response, so the create response's Retry-After (FLO-349 sets it on creates too) sets the first wait.
  • Delay uses the existing core.http_client._parse_retry_after and _add_positive_jitter: max(Retry-After or min, min) × (1 + 0–20%). A missing, unparseable or 0 header falls back to min_poll_interval (default 1s). Transport retries still handle 429s.
  • completed/failed are terminal. A failed result is returned, not raised.
  • With timeout (seconds), the last sleep is cut short at the deadline and one final GET runs. If the work still isn't finished, it raises FlowsWaitTimeoutError (id, template_id, last_response). With no timeout set, it waits indefinitely, like OpenAI.
  • The docstrings point production users to webhooks.

Notes

  • FlowsWaitTimeoutError is a plain Exception, not ApiError, because no HTTP status applies. Import it from elevenlabs.flows_custom, since the package __init__ is generated.
  • I didn't run ruff format on the test file: ruff rewrites it to parenthesized context managers, which aren't valid on Python 3.8 (python = "^3.8").
  • Generation docstrings don't name a webhook event. Only flows_template_run appears in the API definition.

Testing

  • tests/test_flows_create_and_wait.py: covers Retry-After pacing and jitter, the min fallback, failed generations returned rather than raised, timeout errors carrying the id (and template_id for runs), the no-poll path when create returns a terminal status, and the async image and run paths. Uses httpx MockTransport with sleeps patched.
  • pytest tests/test_flows_create_and_wait.py: 10/10 pass. mypy on the new and changed files is clean.
  • Not run against the live API. FLO-349 hasn't shipped, so until it does the helper polls at the minimum interval.

🤖 Generated with Claude Code

client.flows.{image,video,text_to_speech}.create_and_wait and
client.flows.templates.runs.create_and_wait (sync and async) start the
work, then poll the GET endpoint, waiting the server's Retry-After (with
a minimum interval and jitter) between checks, until the status is
completed or failed. An optional timeout raises FlowsWaitTimeoutError
carrying the id so callers can resume with get.

FLO-350

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

cursor Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

PR Summary

Low Risk
SDK-only convenience layer over existing Flows APIs; polling and error semantics are covered by unit tests with no auth or billing changes.

Overview
Adds client.flows on sync and async ElevenLabs clients, backed by a new flows_custom.py wrapper (listed in .fernignore) that subclasses the generated Flows clients.

The main capability is create_and_wait on flows image, video, text_to_speech, and templates.runs: it creates the job, then polls get until status is completed or failed, honoring Retry-After (with jitter and a minimum interval) from create and poll responses. Optional timeout raises FlowsWaitTimeoutError with ids so callers can resume; failed results are returned, not raised. Docstrings steer production use toward webhooks.

tests/test_flows_create_and_wait.py exercises polling, jitter/min fallback, timeouts, terminal-on-create, sync/async paths, and failed generations via httpx MockTransport.

Reviewed by Cursor Bugbot for commit 3782630. Bugbot is set up for automated code reviews on this repo. Configure here.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit dd0db64. Configure here.

Comment thread src/elevenlabs/client.py Outdated
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant