Centralized session URL generation for commands and events.
CI / Formatting (push) Successful in 5s
CI / Linting (push) Successful in 5s
CI / Tests (Python 3.12) (push) Successful in 2m45s
CI / Tests (Python 3.13) (push) Successful in 2m53s
CI / Tests (Python 3.14) (push) Successful in 2m39s
CI / Type Checking (push) Successful in 9s
CI / Spelling (push) Successful in 5s

This commit is contained in:
2026-05-04 21:48:25 -04:00
parent 5443aa86ce
commit 9ac4a17ac8
10 changed files with 226 additions and 98 deletions
+12 -5
View File
@@ -123,6 +123,9 @@ class EventContext[E]:
# Shared services for this module.
module: ModuleContext
# Event-scoped protected-route URL builder. Present for user-bearing events.
_session_url_for: Callable[[str], str] | None = field(default=None, repr=False)
# Shared state for propagation control.
# All handlers for a single event dispatch share the same instance.
_propagation: PropagationState = field(default_factory=PropagationState, repr=False)
@@ -162,6 +165,13 @@ class EventContext[E]:
"""Module-scoped route API for URL building and route introspection."""
return self.module.routes
def session_url_for(self, path: str) -> str:
"""Build a connect URL for a module route for this event's user."""
if self._session_url_for is None:
msg = "session URLs are only available for events with a user"
raise RuntimeError(msg)
return self._session_url_for(path)
@property
def logger(self) -> logging.Logger:
"""Module-scoped logger."""
@@ -222,9 +232,6 @@ class CommandContext:
# Shared services for this module.
module: ModuleContext
# Command-invocation-scoped protected-route URL builder.
_session_url_for: Callable[[str], str] = field(repr=False)
@property
def command(self) -> str:
"""The command name that was invoked (canonical name, not alias)."""
@@ -311,8 +318,8 @@ class CommandContext:
return self.module.admin_client
def session_url_for(self, path: str) -> str:
"""Build a connect URL for a module route for this user."""
return self._session_url_for(path)
"""Build a connect URL for a module route for this command's user."""
return self.event_context.session_url_for(path)
@dataclass(slots=True)