Skip to content

fix(listen/v2): restore subscript access on typed responses - #769

Merged
deepgram-kiley merged 4 commits into
mainfrom
gh/fix-listen-v2-dict-compat
Aug 21, 2026
Merged

fix(listen/v2): restore subscript access on typed responses#769
deepgram-kiley merged 4 commits into
mainfrom
gh/fix-listen-v2-dict-compat

Conversation

@GregHolmes

@GregHolmes GregHolmes commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Summary

  • restore read-only response["field"] access only on the seven Listen V2 response and nested-response model classes affected by the 7.7.0 retype
  • preserve canonical attribute access, nested word subscripting, unknown fields, wire aliases, and KeyError for omitted fields
  • leave all unrelated generated models unchanged
  • freeze the hand-written compatibility base and seven generated response classes for future regens

Why

SDK 7.7.0 removed the typing.Any member from V2SocketClientResponse, correctly restoring typed Listen V2 responses. Through 7.6, that member caused every Listen V2 response to be returned as a raw dictionary, so callers using response["field"] broke when upgrading.

This surfaced while reviewing deepgram-docs#1130. The docs should continue teaching typed attribute access; this narrow shim protects the previously working subscript syntax.

Both styles now work:

message.words[0].confidence
message["words"][0]["confidence"]
message.words[0]["confidence"]

This PR intentionally does not turn Pydantic models into full dictionaries or Mapping objects. It restores only the subscript access that triggered the customer-facing regression. Models remain immutable and attribute access remains canonical.

Verification

  • pytest: 985 passed, 1 skipped
  • mypy src/: clean
  • mypy tests/typecheck: clean
  • ruff check src/deepgram tests/custom/test_model_dict_compat.py: clean
  • targeted compatibility tests pass with Pydantic 1.10.18 and Pydantic 2.x
  • sync and async receive paths, all Listen V2 response variants, nested response objects, unknown fields, omitted declared fields, and unrelated-model isolation are covered
  • standalone probe passes on this branch and fails on main with TypeError: ListenV2TurnInfo object is not subscriptable

@github-actions

github-actions Bot commented Aug 21, 2026

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% 92% 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% (6478 / 6793) 91% (1410 / 1544) 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%.

@dg-edcharbeneau
dg-edcharbeneau self-requested a review August 21, 2026 15:43

@dg-edcharbeneau dg-edcharbeneau 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.

Greg's fix addresses the removes the TypeError. #1130 should now be closed, not merged

@GregHolmes GregHolmes changed the title fix: preserve dict access on typed response models fix(listen/v2): restore subscript access on typed responses Aug 21, 2026

@deepgram-kiley deepgram-kiley left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Approving based on @dg-edcharbeneau's previous review.

@deepgram-kiley
deepgram-kiley merged commit c4d2580 into main Aug 21, 2026
11 checks passed
@deepgram-kiley
deepgram-kiley deleted the gh/fix-listen-v2-dict-compat branch August 21, 2026 20:18
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.

3 participants