Skip to content

feat: add declarative reconnect flag with transport-factory auto-disable#720

Merged
GregHolmes merged 1 commit into
mainfrom
feat/reconnect-parity-hook
Jun 1, 2026
Merged

feat: add declarative reconnect flag with transport-factory auto-disable#720
GregHolmes merged 1 commit into
mainfrom
feat/reconnect-parity-hook

Conversation

@GregHolmes
Copy link
Copy Markdown
Contributor

@GregHolmes GregHolmes commented May 27, 2026

Summary

Adds a new reconnect: bool = True kwarg to DeepgramClient and AsyncDeepgramClient. When a custom transport_factory is provided, reconnect is auto-set to False to signal that the custom transport owns its own retry/reconnect lifecycle.

Why

Custom transports (e.g., the SageMaker transport in deepgram-python-sdk-transport-sagemaker) implement their own retry and reconnect logic — full-jitter backoff, retry-budget windows, replay buffers, etc. Stacking SDK-level retries on top of that would cause storm-on-storm behavior under burst load, which is the failure mode that motivated this parity work across the SDKs.

This adds an explicit, declarative way to express "the SDK is not responsible for reconnects." Today the Python SDK has no wrapper reconnect layer (the websockets library doesn't auto-reconnect; transports manage their own), so the flag is declarative only: it documents intent and reserves the slot for any future SDK-side reconnect logic.

Parity with other SDKs

Behavior

# Default — reconnect=True, no custom transport: SDK behaves as before
client = DeepgramClient(api_key="...")
assert client.reconnect is True

# Custom transport — reconnect auto-disabled to False
client = DeepgramClient(api_key="...", transport_factory=my_factory)
assert client.reconnect is False

# Explicit opt-in even with custom transport — caller takes responsibility
client = DeepgramClient(
    api_key="...",
    transport_factory=my_factory,
    reconnect=True,
)
assert client.reconnect is True

Test plan

Covered in tests/custom/test_transport.py:

  • Default state: client.reconnect == True
  • Explicit reconnect=False is respected
  • transport_factory auto-disables → reconnect == False
  • Explicit override transport_factory=..., reconnect=True is respected

Release impact

  • feat: → minor version bump per release-please conventions
  • Fully backwards-compatible — new optional kwarg with sensible default; existing callers need no change
  • No regen impact: hand-written patch to src/deepgram/client.py, already in .fernignore

Add `reconnect: bool = True` to DeepgramClient and AsyncDeepgramClient.
When a custom `transport_factory` is provided, `reconnect` is auto-set
to `False` to signal that the custom transport owns its own
retry/reconnect lifecycle. Stored on `self.reconnect` for inspection.

The Python SDK has no wrapper reconnect layer today (the `websockets`
library doesn't auto-reconnect; transports manage their own
reconnects), so this flag is declarative only — it documents intent
and is reserved for any future SDK-side reconnect logic. Custom
transports such as SageMaker already own their retry lifecycle, so
double-stacking SDK-side retries on top would cause storm-on-storm
under burst load.

Tests cover the default, explicit False, transport_factory
auto-disable, and the explicit-True override that opts back in.
@GregHolmes GregHolmes requested a review from lukeocodes as a code owner May 27, 2026 16:49
@GregHolmes GregHolmes merged commit b5d5905 into main Jun 1, 2026
2 checks passed
@GregHolmes GregHolmes deleted the feat/reconnect-parity-hook branch June 1, 2026 13:26
GregHolmes added a commit that referenced this pull request Jun 1, 2026
🤖 I have created a release *beep* *boop*
---


##
[7.3.0](v7.2.0...v7.3.0)
(2026-06-01)


### Features

* **client:** add a declarative `reconnect` flag with transport-factory
auto-disable. `DeepgramClient` / `AsyncDeepgramClient` now accept
`reconnect: bool = True` (exposed read-only as `client.reconnect`). When
a custom `transport_factory` is supplied, `reconnect` auto-sets to
`False` to signal that the transport owns its own retry/reconnect
lifecycle — e.g. the SageMaker transport's jittered backoff + replay
buffers — so SDK-level retries don't stack on top and cause
storm-on-storm under burst load. Pass `reconnect=True` explicitly to opt
back in. Declarative only for now (the Python SDK has no wrapper
reconnect layer; `websockets` doesn't auto-reconnect), fully
backwards-compatible, and parity with the same flag in the JS
([#492](deepgram/deepgram-js-sdk#492)) and
Java SDKs
([#720](#720))
([b5d5905](b5d5905))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Greg Holmes <greg.holmes@deepgram.com>
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.

2 participants