Skip to content

refactor(realtime): replace the remaining TypedDict payloads with pydantic models - #1980

Merged
spydon merged 2 commits into
mainfrom
lukasklingsbo/sdk-2703-realtime-replace-the-remaining-typeddict-types-with-models
Nov 4, 2026
Merged

spydon merged 2 commits into
mainfrom
lukasklingsbo/sdk-2703-realtime-replace-the-remaining-typeddict-types-with-models

Conversation

@spydon

@spydon spydon commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

What

Replaces the remaining TypedDict payloads in realtime with pydantic models, matching the other packages (point 2 of #1251). Also drops auth's last TypedDict.

Realtime

These are now BaseModels: PostgresChangesColumn, PostgresChangesData, PostgresChangesPayload, BroadcastMeta, BroadcastPayload, Presence, PresenceMeta, RawPresenceStateEntry, RawPresenceDiff, PresenceDiff, RealtimePresenceJoinPayload and RealtimePresenceLeavePayload.

  • Server messages are validated into these models, so payloads use attribute access: message.payload.event, message.payload.data.record, message.payload.meta.replayed.
  • PostgresChangesData.schema is now schema_ (alias schema), the same as PostgresRowChange, because schema clashes with a BaseModel attribute.
  • Presence and PresenceMeta allow extra fields. The tracked user state is in presence.model_extra.
  • PostgresChangesData.errors is now list[str] | None. The server sends a list, for example ["Error 413: Payload Too Large"], which failed validation before.
  • presence_ref always comes from phx_ref, even when the tracked state has its own presence_ref key. Before, building the model raised a TypeError in that case.
  • PresenceMeta.phx_ref is required. The old code already raised a KeyError when it was missing.
  • PostgresChangesBindingDict and PostgresChangesBinding.as_dict() are removed. RealtimeChannelConfig.postgres_changes holds the PostgresChangesBinding dataclasses directly. id is excluded from serialization, so the join payload does not change.

Auth

  • Removed AMREntryDict. JWTPayload.amr is now list[AMREntry], and get_authenticator_assurance_level no longer converts each entry.

Not changed

  • FunctionsApiErrorDict in functions stays. It is the return type of FunctionsError.to_dict(), which returns a real dict, so a TypedDict is the right type there.

Breaking changes

  • Realtime payloads use attribute access instead of key access.
  • PostgresChangesBindingDict, PostgresChangesBinding.as_dict() and AMREntryDict are removed.

Tests

  • Presence unit tests now build validated models, and there is a new test that validates a presence_diff message into models.
  • The realtime integration tests use attribute access.
  • New tests for a list of postgres change errors and a tracked presence_ref key.
  • New auth test for JWTPayload parsing amr into AMREntry.
  • Ran locally: realtime (44 passed) and auth (220 passed) against local infra, plus pyrefly and ruff.

SDK-2703

@coderabbitai

coderabbitai Bot commented Nov 4, 2026 •

Copy link
Copy Markdown

Explain Change →

No actionable comments were generated in the recent review.

Summary

Summary by CodeRabbit

  • Improvements
    • Realtime messages and presence updates now use validated, structured data, with extra presence fields retained.
    • Postgres change messages support lists of errors and optional record data.
    • Authentication assurance data is validated into structured entries.
  • Compatibility
    • Removed the AMREntryDict and PostgresChangesBindingDict exports; use the remaining model types instead.

Auth JWT AMR entries and Realtime payload and configuration types now use Pydantic models. Authenticator assurance retrieval uses the parsed AMR entries directly. Realtime channel payloads pass binding models, and presence conversion and synchronization use model attributes. Tests now validate and inspect these models.

Possibly related PRs

Change: Refactor

Merge Risk: Minimal · up to aba2a

The payload-model migration has no established merge-blocking defect. Binding IDs remain excluded from join requests; merge after normal checks.

- [ ] Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share
Recent review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 2dbbf73f-cc0e-423e-a0b8-279781b1ce3b
Commits

Reviewing files that changed from the base of the PR and between efad263 and aba2ac3.

Files selected for processing: 11
  • sdk-compliance.yaml
  • src/auth/src/supabase_auth/__init__.py
  • src/auth/src/supabase_auth/mfa.py
  • src/auth/src/supabase_auth/types.py
  • src/auth/tests/test_helpers.py
  • src/realtime/src/realtime/__init__.py
  • src/realtime/src/realtime/channel.py
  • src/realtime/src/realtime/presence.py
  • src/realtime/src/realtime/types.py
  • src/realtime/tests/test_connection.py
  • src/realtime/tests/test_presence.py

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 1 remain after this review.

@spydon
spydon force-pushed the lukasklingsbo/sdk-2703-realtime-replace-the-remaining-typeddict-types-with-models branch from 5d2f3f5 to aba2ac3 Compare November 4, 2026 15:26
@spydon
spydon merged commit cadbdfe into main Nov 4, 2026
32 checks passed
@spydon
spydon deleted the lukasklingsbo/sdk-2703-realtime-replace-the-remaining-typeddict-types-with-models branch November 4, 2026 16:03
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