feat(reverb): Channel types, BroadcastEvent, auth registry, Broadcaster, ReverbProvider#116
Closed
bedus-creation wants to merge 2 commits into
Closed
feat(reverb): Channel types, BroadcastEvent, auth registry, Broadcaster, ReverbProvider#116bedus-creation wants to merge 2 commits into
bedus-creation wants to merge 2 commits into
Conversation
…caster, and ReverbProvider
Implements tasks #147, #148, #149 — the core Reverb broadcasting module:
- reverb/channels.py: Channel, PrivateChannel (private- prefix), PresenceChannel
(presence- prefix) with __eq__/__hash__ for testability
- reverb/event.py: BroadcastEvent ABC with payload dict, optional name
(defaults to class.__name__), and async emit() shortcut
- reverb/registry.py: ChannelAuthRegistry — pattern-to-regex compiler with
{name} wildcards, type-hint casting, async/sync callback support, and
default deny-for-private/allow-for-public policy
- reverb/broadcaster.py: Broadcaster with dispatch(), emit(), and channel()
decorator bound as "broadcast"/"reverb" in the container
- reverb/provider.py: ReverbProvider — register() binds all services; boot()
auto-loads routes/channels.py (silent skip), mounts the WebSocket endpoint,
and mounts POST /broadcasting/auth (200/403 from registry callbacks)
- facades/Broadcast.pyi: updated stub with dispatch(), emit(), channel()
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
3 tasks
Contributor
Author
Review — Superseded by PR #112 (close this PR)Thank you for the implementation! This PR contains a well-designed Conflicts with agreed architecture
Good ideas from this PR cherry-picked into #112The following ideas from #116 are valuable and have been flagged for inclusion in PR #112:
Recommendation: Close this PR and let PR #112 (once the blocking issues are fixed) be the merge target. The good ideas above are being tracked as required fixes on #112. |
Contributor
Author
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Summary
Implements tasks #147, #148, and #149 — the full Reverb broadcasting core module under
fastapi_startkit/src/fastapi_startkit/reverb/.Task #147 — BroadcastEvent + Channel types (
reverb/channels.py,reverb/event.py)Channel— public channel, no auth check;__eq__/__hash__for easy comparison in testsPrivateChannel— automatically prefixes name withprivate-; stores_raw_namePresenceChannel— automatically prefixes name withpresence-; stores_raw_name(member tracking is v2)BroadcastEvent— abstract base withpayload: dict,name: str | None(defaults toclass.__name__at dispatch time), abstractbroadcast_on(), and asyncemit()shortcut that delegates toBroadcast.dispatch(self)Task #148 — Broadcast facade + auth registry (
reverb/registry.py,reverb/broadcaster.py,facades/Broadcast.pyi)ChannelAuthRegistry— compilesorders.{order_id}patterns to named-group regexes; stripsprivate-/presence-prefix before matching; casts wildcard values to callback type hints; supports both sync and async callbacks; default policy: deny private/presence, allow publicBroadcaster— bound as"broadcast"and"reverb"in the container:dispatch(event)— primary path, resolvesevent.name, iteratesbroadcast_on()channelsemit(channel, event_name, payload)— escape hatch for dynamic one-off broadcastschannel(pattern)— decorator factory that registers auth callbacks in the registryfacades/Broadcast.pyi— updated type stub withdispatch(),emit(),channel()signaturesTask #149 — ReverbProvider (
reverb/provider.py)register()— createsReverbServer,ChannelAuthRegistry,Broadcaster; binds all under"reverb","broadcast","reverb.server","reverb.registry"boot()— auto-loadsroutes/channels.pyviaimportlib(silent skip if absent or erroring); mounts WebSocket atREVERB_PATH(default/__reverb); mountsPOST /broadcasting/authsupporting both form-encoded and JSON bodies, returning200 {"auth": "..."}or403 {"message": "Forbidden"}Test plan
tests/broadcasting/tests pass unchanged🤖 Generated with Claude Code