Coverage for src/lexigram/graphql/events.py: 100%
23 statements
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-25 04:37 +0800
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-25 04:37 +0800
1"""GraphQL lifecycle domain events.
3Typed :class:`~lexigram.contracts.domain.events.DomainEvent` subclasses
4published to the :class:`~lexigram.contracts.events.EventBusProtocol` during
5GraphQL operation execution and schema lifecycle. Consumers subscribe to
6specific event types via the bus rather than through ad-hoc hook registrations.
8Example::
10 from lexigram.contracts.events import EventBusProtocol
11 from lexigram.graphql.events import AfterExecuteEvent
13 class QueryLogger:
14 async def handle(self, event: AfterExecuteEvent) -> None:
15 logger.info("query_completed", operation=event.execution_context.operation_name)
17 bus.subscribe(AfterExecuteEvent, QueryLogger())
18"""
20from __future__ import annotations
22from dataclasses import dataclass
23from typing import TYPE_CHECKING, Any
25from lexigram.contracts.domain.events import DomainEvent
27if TYPE_CHECKING:
28 from lexigram.graphql.core.execution import ExecutionContextProtocol
31@dataclass(frozen=True, init=False)
32class BeforeExecuteEvent(DomainEvent):
33 """Emitted immediately before a GraphQL operation is sent to Strawberry.
35 Subscribers may inspect the execution context (query, variables, user) but
36 must NOT modify it — the event is immutable by design.
37 """
39 execution_context: ExecutionContextProtocol
42@dataclass(frozen=True, init=False)
43class AfterExecuteEvent(DomainEvent):
44 """Emitted after a GraphQL operation completes successfully.
46 Contains the execution context with timing information and the raw response.
47 """
49 execution_context: ExecutionContextProtocol
50 result: Any
53@dataclass(frozen=True, init=False)
54class OnErrorEvent(DomainEvent):
55 """Emitted when a GraphQL operation encounters an unhandled exception.
57 This is fired for infrastructure-level errors (timeouts, executor crashes),
58 not for user-facing field errors which are part of the normal GraphQL response.
59 """
61 execution_context: ExecutionContextProtocol
62 error: Exception
65@dataclass(frozen=True, init=False)
66class SchemaBuiltEvent(DomainEvent):
67 """Emitted after the GraphQL schema is successfully built.
69 Consumers may inspect type counts for observability and diagnostics.
70 """
72 type_count: int
75@dataclass(frozen=True, init=False)
76class SubscriptionStartedEvent(DomainEvent):
77 """Emitted when a GraphQL subscription is established.
79 Provides the subscription identifier and operation name for tracking
80 and auditing long-lived connections.
81 """
83 subscription_id: str
84 operation: str
87__all__ = [
88 "AfterExecuteEvent",
89 "BeforeExecuteEvent",
90 "OnErrorEvent",
91 "SchemaBuiltEvent",
92 "SubscriptionStartedEvent",
93]