Coverage for src/lexigram/graphql/module.py: 87%
15 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 module for dependency injection."""
3from __future__ import annotations
5from typing import Any
7from lexigram.contracts.graphql.protocols import GraphQLExecutorProtocol
8from lexigram.di.module import DynamicModule, Module, module
11@module()
12class GraphQLModule(Module):
13 """GraphQL layer (Strawberry): schema building, execution, federation, and subscriptions.
15 Call :meth:`configure` to configure and mount the GraphQL endpoint.
17 Usage::
19 import strawberry
21 @strawberry.type
22 class Query:
23 @strawberry.field
24 def hello(self) -> str:
25 return "world"
27 @module(
28 imports=[GraphQLModule.configure(query_class=Query)]
29 )
30 class AppModule(Module):
31 pass
32 """
34 @classmethod
35 def configure(
36 cls,
37 config: Any | None = None,
38 query_class: Any | None = None,
39 mutation_class: Any | None = None,
40 subscription_class: Any | None = None,
41 context_factory_class: Any | None = None,
42 ) -> DynamicModule:
43 """Create a GraphQLModule with explicit configuration.
45 Args:
46 config: :class:`~lexigram.graphql.config.GraphQLConfig` or ``None``
47 for framework defaults.
48 query_class: Optional root Strawberry ``Query`` type.
49 mutation_class: Optional root Strawberry ``Mutation`` type.
50 subscription_class: Optional root Strawberry ``Subscription`` type.
51 context_factory_class: Optional custom :class:`~lexigram.graphql.core.context.ContextFactory`
52 subclass. When ``None``, the framework's default ``ContextFactory`` is used.
53 Subclasses can override ``create_context()`` to attach application-specific
54 services to the GraphQL context.
56 Returns:
57 A :class:`~lexigram.di.module.DynamicModule` descriptor.
58 """
59 from lexigram.graphql.di.provider import GraphQLProvider
61 return DynamicModule(
62 module=cls,
63 providers=[
64 GraphQLProvider(
65 config=config,
66 query_class=query_class,
67 mutation_class=mutation_class,
68 subscription_class=subscription_class,
69 context_factory_class=context_factory_class,
70 )
71 ],
72 exports=[GraphQLExecutorProtocol],
73 is_global=True,
74 )
76 @classmethod
77 def stub(cls, config: Any = None) -> DynamicModule:
78 """Return a no-op GraphQLModule suitable for unit testing.
80 Registers a GraphQLProvider with no schema types configured.
81 Useful for testing application structure without a real GraphQL
82 executor.
84 Returns:
85 A DynamicModule with noop GraphQL configuration.
86 """
87 from lexigram.graphql.di.provider import GraphQLProvider
89 return DynamicModule(
90 module=cls,
91 providers=[GraphQLProvider()],
92 exports=[GraphQLExecutorProtocol],
93 is_global=True,
94 )
97__all__ = ["GraphQLModule"]