Skip to content

docs: add production-grade live transcription reconnection example - #776

Open
dg-coreylweathers wants to merge 1 commit into
mainfrom
gh/example-live-reconnect
Open

docs: add production-grade live transcription reconnection example#776
dg-coreylweathers wants to merge 1 commit into
mainfrom
gh/example-live-reconnect

Conversation

@dg-coreylweathers

Copy link
Copy Markdown
Contributor

What

Adds examples/17-transcription-live-reconnect.py — the canonical production-grade reconnection example for streaming speech-to-text, intended to back the upcoming speech-to-text/streaming/guides/production docs page. Also adds the previously missing README entry for example 16.

What it demonstrates

  • Exponential backoff with full jitter and a retry cap
  • Reconnect-worthy close codes (1006/1011/1012/1013) distinguished from normal (1000/1001) and fatal closure
  • Audio buffered in a producer thread during the disconnect gap, drained after reconnect (with a bounded buffer)
  • Original connection options stored once and re-applied verbatim on every reconnect
  • Continuous timestamps across sessions via an offset
  • Clean shutdown via CloseStream
  • A clearly fenced DEMO-ONLY fault injector (SIMULATE_DROP=0 disables it) that severs the TCP socket mid-stream to demonstrate recovery

Uses only this SDK's listen v1 socket client; every method and event name verified against source.

Validation (live against api.deepgram.com, in Docker)

  • Transcribes real audio, survives a forced mid-stream disconnect (classified close code 1006), resumes with continuous timestamps, exits 0
  • Bad-key run exits 1 with a one-line message; the key never appears in output
  • Live probe confirmed the documented silence timeout: server closes 1011 with the NET-0001 reason
  • ruff and mypy clean

Review

Passed devrel-review: initial pass found 1 blocking (deque-iteration race in buffer telemetry) and 3 should-fixes — all fixed and re-verified live. Final verdict: approve, two accepted nits (fenced _websocket access in the demo fault injector; Ctrl-C during backoff tracebacks).

Related finding (not addressed here)

The review's bad-key probe surfaced a pre-existing SDK bug: core/websocket_compat.py binds the legacy InvalidStatusCode while the sync client raises the distinct InvalidStatus, so rejected websocket handshakes never become the documented ApiError on any connect path (websockets 12–15). This example tolerates both exception shapes; the SDK-side fix is routed to Greg (generator fix vs hand-patch + .fernignore freeze).

🤖 Generated with Claude Code

Adds examples/17-transcription-live-reconnect.py demonstrating the
resilience patterns recommended for production streaming STT:
exponential backoff with full jitter and a retry cap, reconnect-worthy
close codes distinguished from normal/fatal closure, audio buffered
across the disconnect gap and resumed on reconnect, original connection
options re-applied, continuous timestamps across sessions, and clean
shutdown via CloseStream. Includes a demo-only fault injector that
severs the TCP socket mid-stream to show recovery; validated live
against api.deepgram.com.

Also lists the previously missing example 16 in examples/README.md.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

Code Coverage

Package Line Rate Branch Rate Complexity Health
src.deepgram 96% 92% 0
src.deepgram.agent 100% 100% 0
src.deepgram.agent.v1 98% 100% 0
src.deepgram.agent.v1.settings 100% 100% 0
src.deepgram.agent.v1.settings.think 100% 100% 0
src.deepgram.agent.v1.settings.think.models 97% 100% 0
src.deepgram.auth 100% 100% 0
src.deepgram.auth.v1 100% 100% 0
src.deepgram.auth.v1.tokens 97% 100% 0
src.deepgram.core 88% 81% 0
src.deepgram.errors 100% 100% 0
src.deepgram.helpers 100% 95% 0
src.deepgram.listen 100% 100% 0
src.deepgram.listen.v1 98% 93% 0
src.deepgram.listen.v1.media 97% 100% 0
src.deepgram.listen.v2 98% 93% 0
src.deepgram.manage 100% 100% 0
src.deepgram.manage.v1 100% 100% 0
src.deepgram.manage.v1.models 96% 100% 0
src.deepgram.manage.v1.projects 97% 100% 0
src.deepgram.manage.v1.projects.billing 100% 100% 0
src.deepgram.manage.v1.projects.billing.balances 96% 100% 0
src.deepgram.manage.v1.projects.billing.breakdown 97% 100% 0
src.deepgram.manage.v1.projects.billing.fields 97% 100% 0
src.deepgram.manage.v1.projects.billing.purchases 97% 100% 0
src.deepgram.manage.v1.projects.keys 96% 100% 0
src.deepgram.manage.v1.projects.members 97% 100% 0
src.deepgram.manage.v1.projects.members.invites 96% 100% 0
src.deepgram.manage.v1.projects.members.scopes 96% 100% 0
src.deepgram.manage.v1.projects.models 96% 100% 0
src.deepgram.manage.v1.projects.usage 98% 100% 0
src.deepgram.manage.v1.projects.usage.breakdown 97% 100% 0
src.deepgram.manage.v1.projects.usage.fields 97% 100% 0
src.deepgram.read 100% 100% 0
src.deepgram.read.v1 100% 100% 0
src.deepgram.read.v1.text 98% 100% 0
src.deepgram.self_hosted 100% 100% 0
src.deepgram.self_hosted.v1 100% 100% 0
src.deepgram.self_hosted.v1.distribution_credentials 96% 100% 0
src.deepgram.speak 100% 100% 0
src.deepgram.speak.v1 98% 97% 0
src.deepgram.speak.v1.audio 91% 80% 0
src.deepgram.speak.v2 98% 93% 0
src.deepgram.speak.v2.audio 100% 100% 0
src.deepgram.voice_agent 100% 100% 0
src.deepgram.voice_agent.configurations 95% 100% 0
src.deepgram.voice_agent.variables 95% 100% 0
Summary 95% (6486 / 6803) 91% (1411 / 1546) 0

Scope: hand-maintained SDK logic. Fern-generated data models (types/, requests/), package __init__.py files, version.py, and the unused core/http_sse/ scaffolding are excluded — see .coveragerc. Unscoped whole-package coverage is ~70%.

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