You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
refactor(realtime): replace the remaining TypedDict payloads with pydantic models - #1980
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.
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
supabase/supabase-py#1979: Both changes modify explicit package exports, including the Auth and Realtime exports touched here.
supabase/supabase-py#1908: Both changes update Realtime Postgres-change error arrays and validate those payloads.
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.
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
deleted the
lukasklingsbo/sdk-2703-realtime-replace-the-remaining-typeddict-types-with-models
branch
November 4, 2026 16:03
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Replaces the remaining
TypedDictpayloads in realtime with pydantic models, matching the other packages (point 2 of #1251). Also drops auth's lastTypedDict.Realtime
These are now
BaseModels:PostgresChangesColumn,PostgresChangesData,PostgresChangesPayload,BroadcastMeta,BroadcastPayload,Presence,PresenceMeta,RawPresenceStateEntry,RawPresenceDiff,PresenceDiff,RealtimePresenceJoinPayloadandRealtimePresenceLeavePayload.message.payload.event,message.payload.data.record,message.payload.meta.replayed.PostgresChangesData.schemais nowschema_(aliasschema), the same asPostgresRowChange, becauseschemaclashes with aBaseModelattribute.PresenceandPresenceMetaallow extra fields. The tracked user state is inpresence.model_extra.PostgresChangesData.errorsis nowlist[str] | None. The server sends a list, for example["Error 413: Payload Too Large"], which failed validation before.presence_refalways comes fromphx_ref, even when the tracked state has its ownpresence_refkey. Before, building the model raised aTypeErrorin that case.PresenceMeta.phx_refis required. The old code already raised aKeyErrorwhen it was missing.PostgresChangesBindingDictandPostgresChangesBinding.as_dict()are removed.RealtimeChannelConfig.postgres_changesholds thePostgresChangesBindingdataclasses directly.idis excluded from serialization, so the join payload does not change.Auth
AMREntryDict.JWTPayload.amris nowlist[AMREntry], andget_authenticator_assurance_levelno longer converts each entry.Not changed
FunctionsApiErrorDictin functions stays. It is the return type ofFunctionsError.to_dict(), which returns a real dict, so aTypedDictis the right type there.Breaking changes
PostgresChangesBindingDict,PostgresChangesBinding.as_dict()andAMREntryDictare removed.Tests
presence_diffmessage into models.presence_refkey.JWTPayloadparsingamrintoAMREntry.SDK-2703