Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: deepgram/deepgram-python-sdk
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: main
Choose a base ref
...
head repository: deepgram/deepgram-python-sdk
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v5
Choose a head ref
Checking mergeability… Don’t worry, you can still create the pull request.
  • 4 commits
  • 13 files changed
  • 5 contributors

Commits on Feb 24, 2026

  1. fix(websockets): tolerate unknown message types from API (#671)

    ## Summary
    - Backport of the v6.0.1 `construct_type` fix to the v5 maintenance
    branch
    - Adds `unchecked_base_model.py` (from v6) with `construct_type` which
    does best-effort union coercion instead of strict Pydantic validation
    - Switches all 4 socket clients (listen v1, listen v2, speak v1, agent
    v1) from `parse_obj_as` to `construct_type`
    - Unknown WebSocket message types (e.g. `ConfigureSuccess`) now pass
    through without crashing the listener
    
    ## Test plan
    - [x] 853 unit/integration tests pass
    - [x] Verified against live Deepgram API with Listen V2 (Flux) —
    `ConfigureSuccess` unknown message type coerced cleanly as
    `ListenV2ConnectedEvent`
    - [x] Verify no regressions in existing v5 consumers
    lukeocodes authored Feb 24, 2026
    Configuration menu
    Copy the full SHA
    7deb302 View commit details
    Browse the repository at this point in the history
  2. Configuration menu
    Copy the full SHA
    0378dfd View commit details
    Browse the repository at this point in the history

Commits on Jun 26, 2026

  1. fix(listen/v2): allow extra fields on TurnInfo models (5.3.x) (#736)

    ## Problem
    
    The v2 listen (Flux) `TurnInfo` message can include additional
    **per-word fields `start` and `end`** (type `double`) beyond the
    `word`/`confidence` the 5.3.x models declare. This was observed
    intermittently against the live API (roughly 1 in 6 connections in
    testing); I have not confirmed the full server-side rollout scope.
    
    The model `ListenV2TurnInfoEventWordsItem` declares only `word` +
    `confidence` with `extra = "forbid"`, so any frame carrying extra fields
    fails pydantic validation in `listen/v2/socket_client.py`
    (`parse_obj_as(V2SocketClientResponse, ...)`).
    
    Observed impact on the released 5.3.x line:
    - **5.3.0**: uncaught `ValidationError` propagates out of
    `start_listening()` (which only catches `WebSocketException` /
    `JSONDecodeError`) and tears down the listen loop; it never reaches the
    `EventType.ERROR` handler.
    - **5.3.2 / 5.3.3**: `construct_type` doesn't raise, but the strict word
    model still fails the union's validated pass, so the frame is silently
    mis-resolved to `ListenV2ConnectedEvent` — transcript and words dropped,
    no error (silent data loss).
    
    ## Fix
    
    Relax `extra` from `"forbid"` to `"allow"` on
    `ListenV2TurnInfoEventWordsItem` and `ListenV2TurnInfoEvent`, so unknown
    additive fields are tolerated and retained. Model-agnostic — it doesn't
    assume which model or which fields. Verified: a frame with `start`/`end`
    then parses as `ListenV2TurnInfoEvent` with the fields preserved.
    
    ```diff
         class Config:
             frozen = True
    -        extra = "forbid"
    +        extra = "allow"
    ```
    (applied to both models in the file)
    
    ## Safety / side-effect analysis
    
    - **No code-execution risk.** Pydantic `extra="allow"` only stores
    unknown JSON values as data attributes (`__pydantic_extra__`); it does
    not eval/import/instantiate types. Not pickle/YAML-style gadget
    deserialization. Inbound data also comes from the Deepgram API over TLS,
    not arbitrary user input.
    - **Union resolution stays correct (tested).** `V2SocketClientResponse =
    Union[Connected, TurnInfo, FatalError]`. `TurnInfo` has required fields
    that `Connected`/`FatalError` lack, and those two keep `extra="forbid"`,
    so a permissive `TurnInfo` cannot greedily capture them. Verified:
    `Connected` → `ListenV2ConnectedEvent`, `Error` →
    `ListenV2FatalErrorEvent`, `TurnInfo+start/end` →
    `ListenV2TurnInfoEvent`.
    - **Required-field validation preserved (tested).** A `TurnInfo` frame
    missing a required field (e.g. `transcript`) still raises
    `ValidationError`. Only *unknown additive* fields are now tolerated.
    - **Memory:** negligible — `json.loads` already materializes the full
    payload before pydantic runs; `allow` just retains references (bounded
    by message size).
    - **Tradeoff:** loses the loud failure on unexpected additive fields (a
    contract-drift signal) — but that brittleness is exactly the bug, and
    this matches `main`'s posture.
    
    ### `allow` vs `ignore`
    - **`allow`** (chosen): tolerates **and exposes** the new fields, so
    callers can read `word.start` / `word.end`. Matches `main` (6.x/7.x).
    - **`ignore`**: also fixes the crash/mis-typing but **discards** extras
    — more conservative (nothing unvalidated retained or re-serialized), at
    the cost of the timestamps being unavailable.
    
    Happy to switch to `ignore` if the team prefers minimal surface.
    
    ## Notes for reviewers
    - `main` (6.x/7.x) already ships `extra="allow"` on the equivalent
    model, so this only affects the released **5.3.x** line — hence
    targeting `v5`.
    - This file is **Fern-generated** (`# auto-generated by Fern from our
    API Definition`); if `v5` is regenerated the proper fix belongs in the
    API definition. This is a direct patch on the frozen maintenance branch.
    
    🤖 Generated with [Claude Code](https://claude.com/claude-code)
    
    Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    andreyas1337 and claude authored Jun 26, 2026
    Configuration menu
    Copy the full SHA
    be07aa6 View commit details
    Browse the repository at this point in the history
  2. chore(release): release 5.3.4 (#737)

    Maintenance release of the 5.3.x line.
    
    Bumps the version `5.3.3` → `5.3.4` (manifest, `pyproject.toml`,
    `client_wrapper.py` SDK header) and adds the CHANGELOG entry for #736.
    
    ### Included
    - #736 — fix(listen/v2): allow extra fields on Flux `TurnInfo` models
    (`extra="forbid"` → `"allow"`), preventing the crash (5.3.0) / silent
    transcript drop (5.3.2/5.3.3) when Flux emits per-word `start`/`end`.
    
    ### Release mechanism
    After this merges, pushing tag `v5.3.4` triggers
    `.github/workflows/maintenance-release.yml`, which compiles, tests,
    builds, and publishes to PyPI. A GitHub Release will be created with
    `--latest=false` so `7.3.1` keeps the repo "Latest" badge.
    
    🤖 Generated with [Claude Code](https://claude.com/claude-code)
    
    Co-authored-by: Corey Weathers <coreyweathers@coreys-mbp.mynetworksettings.com>
    Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    3 people authored Jun 26, 2026
    Configuration menu
    Copy the full SHA
    24b1e02 View commit details
    Browse the repository at this point in the history
Loading