Skip to content
GitHubDiscord

API Reference

Store for persisted query mappings.

Implement this protocol to provide custom storage for persisted queries.

async def get(hash: str) -> str | None

Get a query by its hash.

Parameters
ParameterTypeDescription
`hash`strSHA256 hash of the query.
Returns
TypeDescription
str | NoneThe query string if found, None otherwise.
async def put(
    hash: str,
    query: str
) -> None

Store a query with its hash.

Parameters
ParameterTypeDescription
`hash`strSHA256 hash of the query.
`query`strThe full query string.

Handler for Automatic Persisted Queries.

Implements the APQ protocol:

  1. Client sends query hash → Server looks up full query
  2. If not found, client sends hash + full query → Server stores
  3. Subsequent requests use just the hash
def __init__(
    store: PersistedQueryStore,
    enabled: bool = True
)

Initialize the APQ handler.

Parameters
ParameterTypeDescription
`store`PersistedQueryStorePersisted query store implementation.
`enabled`boolWhether APQ is enabled.
property enabled() -> bool

Check if APQ is enabled.

async def resolve_query(
    query: str | None,
    extensions: dict | None = None
) -> APQResult

Resolve the full query using APQ.

Parameters
ParameterTypeDescription
`query`str | NoneThe query from the request (may be None for hash-only).
`extensions`dict | NoneThe extensions from the GraphQL request.
Returns
TypeDescription
APQResultAPQResult with the resolved query.
def create_extension_response(hash: str) -> dict

Create the APQ extension response.

Parameters
ParameterTypeDescription
`hash`strThe query hash.
Returns
TypeDescription
dictExtension dict for the GraphQL response.

Result of APQ lookup.

Attributes: query: The full query string (if found). is_persisted: Whether the query was found in the store. hash: The hash used for lookup.


Base class for GraphQL permissions.

Permission classes control access to GraphQL fields. They are checked before field resolution and can raise exceptions or return False to deny access.

Attributes: message: Error message when permission is denied.

Example

class IsAuthenticated(AbstractPermission):
message = "Authentication required"
async def has_permission(self, source, info, **kwargs):
return info.context.user is not None
@strawberry.type
class User:
@field(permission_classes=[IsAuthenticated])
async def email(self) -> str:
return self._email
async def has_permission(
    source: Any,
    info: Info,
    **kwargs: Any
) -> bool

Check if the permission is granted.

Parameters
ParameterTypeDescription
`source`AnyThe source object (parent resolver result).
`info`InfoGraphQL resolver info containing context. **kwargs: Additional arguments passed to the field.
Returns
TypeDescription
boolTrue if permission is granted, False otherwise.
Raises
ExceptionDescription
ExceptionIf permission is denied with a custom error.

Emitted after a GraphQL operation completes successfully.

Contains the execution context with timing information and the raw response.


Validate query alias count against a limit.

Analyzes GraphQL queries to count aliases and validates against a configured maximum.

Example

validator = AliasLimitValidator(max_aliases=10)
count = validator.count_aliases(document)
validator.validate(document) # Raises if too many
def __init__(max_aliases: int = 10) -> None

Initialize the validator.

Parameters
ParameterTypeDescription
`max_aliases`intMaximum allowed aliases.
property max_aliases() -> int

Get maximum alias limit.

def count_aliases(document: DocumentNode) -> int

Count the number of aliases in a query.

Parameters
ParameterTypeDescription
`document`DocumentNodeParsed GraphQL document.
Returns
TypeDescription
intNumber of aliases.
def validate(document: DocumentNode) -> None

Validate alias count.

Parameters
ParameterTypeDescription
`document`DocumentNodeParsed GraphQL document.
Raises
ExceptionDescription
SecurityErrorIf query has too many aliases.

Permission that allows any access (no restrictions).
async def has_permission(
    source: Any,
    info: Info[Any, Any],
    **kwargs: Any
) -> bool

Always allow access.


Emitted immediately before a GraphQL operation is sent to Strawberry.

Subscribers may inspect the execution context (query, variables, user) but must NOT modify it — the event is immutable by design.


CacheBackendProtocol-backed APQ store for multi-process deployments.

Uses the platform’s CacheBackendProtocol abstraction rather than a raw Redis client — compatible with any configured cache provider (Redis, Memcached, etc.) without coupling this package to a specific driver.

Suitable for production use with multiple application instances.

def __init__(
    cache: Any,
    key_prefix: str = 'graphql:apq:',
    ttl_seconds: int = 86400
) -> None

Initialize the store.

Parameters
ParameterTypeDescription
`cache`AnyA CacheBackendProtocol instance.
`key_prefix`strPrefix applied to all cache keys.
`ttl_seconds`intTime-to-live for stored entries in seconds.
async def get(hash: str) -> str | None

Get a query by its hash.

async def put(
    hash: str,
    query: str
) -> None

Store a query with its hash.


Cache configuration for GraphQL responses.

Attributes: enabled: Whether caching is enabled. default_max_age: Default cache duration in seconds. default_scope: Default cache scope (PUBLIC/PRIVATE). vary_headers: Headers to vary cache on.


Cache control settings for a field or type.
def to_header() -> str

Generate Cache-Control header value.


Cache control scope for responses.

GraphQL Connection type template for cursor-based pagination.

This is a generic template. Use create_connection_type() to create concrete Connection types for your node types.

Attributes: edges: List of edges containing nodes. page_info: Pagination information. total_count: Total number of items.


Factory for creating GraphQL contexts.

Provides a standardized way to create execution contexts with proper initialization and DataLoaderProtocol setup.

def __init__(
    config: GraphQLConfig | None = None,
    dataloader_factories: dict[str, Any] | None = None,
    enable_identity_resolution: bool | None = None,
    resolver: Any | None = None
) -> None

Initialize the context factory.

Parameters
ParameterTypeDescription
`config`GraphQLConfig | NoneGraphQL configuration.
`dataloader_factories`dict[str, Any] | NoneFactory functions for DataLoaders.
`enable_identity_resolution`bool | NoneWhether to automatically resolve OAuth IDs to UUIDs. If not provided, reads from config if available, otherwise defaults to False (opt-in).
`resolver`Any | NoneOptional DI resolver to use for identity resolution.
async def create_context(
    request: GraphQLRequest | None = None,
    user: Any | None = None,
    metadata: dict[str, Any] | None = None,
    raw_request: Any | None = None
) -> GraphQLContext

Create a new GraphQL context.

This async version properly resolves OAuth external IDs to internal UUIDs if the OAuthIdentityStore is available in the container, and optionally authenticates and resolves a principal.

Authentication flow:

  1. If user is provided, use it directly (middleware-authenticated)
  2. If no user but raw_request is available, optionally authenticate
  3. Resolve principal via GraphQLPrincipalResolverProtocol
  4. If no resolver exists but user is present, create fallback principal
Parameters
ParameterTypeDescription
`request`GraphQLRequest | NoneThe GraphQL request.
`user`Any | NoneCurrent user (from middleware or previous auth).
`metadata`dict[str, Any] | NoneAdditional metadata.
`raw_request`Any | NoneThe raw HTTP request.
Returns
TypeDescription
GraphQLContextA new GraphQLContext instance with resolved user ID and principal.
def create_context_sync(
    request: GraphQLRequest | None = None,
    user: Any | None = None,
    metadata: dict[str, Any] | None = None,
    raw_request: Any | None = None
) -> GraphQLContext

Create a GraphQL context synchronously (testing/sync-bridge only).

Warning Prefer create_context in production code. This method does not perform async identity resolution or principal resolution — the user object is passed through as-is and principal is set to None. Use only in test environments or sync integration points that cannot await.

Parameters
ParameterTypeDescription
`request`GraphQLRequest | NoneThe GraphQL request.
`user`Any | NoneCurrent user (no async identity resolution performed).
`metadata`dict[str, Any] | NoneAdditional metadata.
`raw_request`Any | NoneThe raw HTTP request.
Returns
TypeDescription
GraphQLContextA new GraphQLContext instance without async identity or principal resolution.
def register_dataloader(
    name: str,
    factory: Any
) -> None

Register a DataLoaderProtocol factory.

Parameters
ParameterTypeDescription
`name`strDataLoaderProtocol name.
`factory`AnyFactory function that creates the DataLoaderProtocol.
def from_dict(
    data: dict[str, Any],
    request: GraphQLRequest | None = None
) -> GraphQLContext

Create a GraphQLContext from a plain dictionary.

A convenience factory for callers that previously passed dict directly to GraphQLExecutorProtocol.execute. Extracts user, metadata, and optionally request from data.

Parameters
ParameterTypeDescription
`data`dict[str, Any]Mapping with optional keys ``user``, ``metadata``, and ``request``.
`request`GraphQLRequest | NoneExplicit request object; overrides ``data["request"]`` when provided.
Returns
TypeDescription
GraphQLContextA fully initialised GraphQLContext.

Example

context = ContextFactory.from_dict(
{"user": current_user, "metadata": {"source": "api"}},
)
result = await executor.execute(query, context=context)

A connection for cursor-based pagination.

Input for cursor-based pagination.

Attributes: first: Number of items to fetch from the start. after: Cursor to fetch items after. last: Number of items to fetch from the end. before: Cursor to fetch items before.


DataLoaderProtocol configuration.

Attributes: enabled: Whether DataLoaderProtocol integration is enabled. batch_enabled: Whether batching is enabled. cache_enabled: Whether per-request caching is enabled. max_batch_size: Maximum batch size for DataLoaderProtocol. batch_schedule_fn: How to schedule batch execution.


DataLoaderProtocol for batching and caching.

DataLoaderProtocol is a utility for batching and caching data fetches to efficiently resolve GraphQL queries and avoid the N+1 problem.

Example

async def batch_load_users(ids: list[str]) -> list[User | None]:
users = await db.get_users_by_ids(ids)
# Return in same order as input ids
user_map = {u.id: u for u in users}
return list(map(lambda id: user_map.get(id), ids))
loader = DataLoaderProtocol(batch_load_users)
# These will be batched into a single call
user1 = await loader.load("1")
user2 = await loader.load("2")
def __init__(
    batch_fn: Callable[[list[K]], Awaitable[list[V | None]]],
    config: DataLoaderConfig | None = None,
    cache: LoaderCache[K, V] | None = None
) -> None

Initialize the DataLoaderProtocol.

Parameters
ParameterTypeDescription
`batch_fn`Callable[[list[K]], Awaitable[list[V | None]]]Function that loads a batch of values by keys.
`config`DataLoaderConfig | NoneDataLoaderProtocol configuration.
`cache`LoaderCache[K, V] | NoneOptional cache implementation.
property config() -> DataLoaderConfig

Get configuration.

async def load(key: K) -> V | None

Load a value by key.

The load will be batched with other loads that occur in the same tick of the event loop.

Parameters
ParameterTypeDescription
`key`KThe key to load.
Returns
TypeDescription
V | NoneThe loaded value or None if not found.
Raises
ExceptionDescription
DataLoaderErrorIf loading fails.
async def load_many(keys: Sequence[K]) -> list[V | None]

Load multiple values by keys.

Parameters
ParameterTypeDescription
`keys`Sequence[K]List of keys to load.
Returns
TypeDescription
list[V | None]List of values in the same order as keys.
def prime(
    key: K,
    value: V
) -> None

Prime the cache with a value.

Use this to add values to the cache that were loaded through other means.

Parameters
ParameterTypeDescription
`key`KThe key.
`value`VThe value to cache.
def clear(key: K) -> None

Clear a cached value.

Parameters
ParameterTypeDescription
`key`KThe key to clear.
def clear_all() -> None

Clear all cached values.


Statistics for a DataLoaderProtocol instance.
property cache_hit_ratio() -> float

Calculate cache hit ratio.


Result of a delete mutation.

Attributes: success: Whether deletion succeeded. id: ID of deleted item. message: Optional message.


Permission that denies all access.
async def has_permission(
    source: Any,
    info: Info[Any, Any],
    **kwargs: Any
) -> bool

Always deny access.


Marks targets as deprecated using the ``@deprecated`` directive.

Adds a __deprecated__ attribute with the deprecation reason to any target object that supports attribute assignment.

def apply_directive(
    directive_name: str,
    args: dict[str, Any],
    target: Any
) -> Any

Apply @deprecated by setting __deprecated__ on target.

Parameters
ParameterTypeDescription
`directive_name`strExpected to be ``"deprecated"``.
`args`dict[str, Any]May contain ``"reason"`` (str).
`target`AnyAny object.
Returns
TypeDescription
AnyThe *target* with ``__deprecated__`` set.

Query depth limiting configuration.

Attributes: enabled: Whether depth limiting is enabled. max_depth: Maximum allowed query depth. ignore_introspection: Ignore introspection queries.


Strawberry extension for query depth limiting.

Add this extension to your schema to automatically validate query depth before execution.

Example

from lexigram.graphql.security import DepthLimitExtension
schema = strawberry.Schema(
query=Query,
extensions=[DepthLimitExtension(max_depth=10)],
)
def __init__(
    max_depth: int = 10,
    ignore_introspection: bool = True
) -> None

Initialize the extension.

Parameters
ParameterTypeDescription
`max_depth`intMaximum allowed query depth.
`ignore_introspection`boolSkip introspection queries.
def on_operation() -> Iterator[None]

Hook called during operation execution.


Validate query depth against a limit.

Analyzes GraphQL queries to determine their depth and validates against a configured maximum depth.

Example

validator = DepthLimitValidator(max_depth=10)
# Validate a parsed document
depth = validator.get_depth(document)
validator.validate(document) # Raises if too deep
def __init__(
    max_depth: int = 10,
    ignore_introspection: bool = True
) -> None

Initialize the validator.

Parameters
ParameterTypeDescription
`max_depth`intMaximum allowed query depth.
`ignore_introspection`boolSkip depth check for introspection queries.
property max_depth() -> int

Get maximum depth limit.

def get_depth(document: DocumentNode) -> int

Calculate the maximum depth of a query.

Parameters
ParameterTypeDescription
`document`DocumentNodeParsed GraphQL document.
Returns
TypeDescription
intMaximum depth of the query.
def validate(document: DocumentNode) -> None

Validate query depth.

Parameters
ParameterTypeDescription
`document`DocumentNodeParsed GraphQL document.
Raises
ExceptionDescription
DepthLimitErrorIf query exceeds depth limit.

GraphQL directive locations.

Registry-based implementation of DirectiveHandler.

Maps directive names to handler callables via on (decorator syntax or explicit register call). When apply_directive is invoked with an unknown directive name, the target is returned unchanged if no default handler is registered, or the default handler is called.

Parameters
ParameterTypeDescription
`default_handler`Optional fallback for unrecognised directives. Receives the same ``(directive_name, args, target)`` signature. When ``None`` (default), unknown directives are silently ignored.
def __init__(default_handler: Any | None = None) -> None
def register(
    directive_name: str,
    handler: Any
) -> None

Register a handler callable for a directive.

Parameters
ParameterTypeDescription
`directive_name`strName of the GraphQL directive (without ``@``).
`handler`AnyCallable ``(directive_name, args, target) -> target``.
def on(directive_name: str) -> Any

Decorator that registers a handler for directive_name.

Example

@registry.on("auth")
def apply_auth(name, args, target):
target.__roles__ = args.get("roles", [])
return target
Parameters
ParameterTypeDescription
`directive_name`strName of the directive.
Returns
TypeDescription
AnyDecorator that registers the decorated function.
def apply_directive(
    directive_name: str,
    args: dict[str, Any],
    target: Any
) -> Any

Apply a registered directive handler to target.

If no handler is registered under directive_name the default handler is called if one was supplied; otherwise target is returned as-is.

Parameters
ParameterTypeDescription
`directive_name`strDirective to apply (without ``@``).
`args`dict[str, Any]Directive arguments from the schema.
`target`AnySchema element to transform.
Returns
TypeDescription
AnyThe (possibly transformed) *target*.

An edge in a connection.

Error handling configuration.

Attributes: mask_errors: Whether to mask internal errors in production. include_stacktrace: Whether to include stacktrace in errors. debug_mode: Whether debug mode is enabled. log_errors: Whether to log errors.


Context for a single query execution.

Tracks execution state, metrics, and provides hooks for middleware and extensions.

Attributes: context: The GraphQL context. operation_type: Type of operation being executed. start_time: Execution start time. end_time: Execution end time. errors: Errors encountered during execution. extensions: Execution extensions data.

def mark_complete() -> None

Mark execution as complete.

property duration_ms() -> float

Get execution duration in milliseconds.

def add_error(error: Exception) -> None

Add an error to the execution context.

property has_errors() -> bool

Check if execution has errors.


Complete execution trace.

Attributes: operation_name: Name of the operation. start_time: Execution start time. end_time: Execution end time. total_duration_ms: Total duration. root_span: Root span of the trace. resolver_count: Number of resolvers called.

def end() -> None

End the trace.

def to_dict() -> dict[str, Any]

Convert to dictionary.

Returns
TypeDescription
dict[str, Any]Dictionary representation (Apollo tracing format).

Information about a GraphQL field.

Hierarchical root configuration for Lexigram GraphQL.

Attributes: name: Configuration name (default: “graphql”) enabled: Whether GraphQL module is enabled path: GraphQL endpoint path debug: Platform debug flag (aligns with ObservabilityConfig.debug). Propagates to errors.debug_mode. enable_identity_resolution: Resolve OAuth IDs to internal UUIDs cache: Response caching settings depth_limit: Query depth limiting complexity: Query complexity settings persisted_queries: Persisted queries settings batch: Batch query settings introspection: Introspection settings playground: GraphQL playground settings subscriptions: WebSocket subscription settings dataloader: DataLoaderProtocol settings tracing: Tracing settings metrics: Metrics settings error: Error handling settings rate_limit: Rate limiting settings

def development(cls) -> GraphQLConfig

Create development configuration with debugging enabled.

def production(cls) -> GraphQLConfig

Create production configuration with security hardening.


GraphQL execution context.

Provides context for GraphQL operations including request information, user data, and configuration.

Attributes: request_id: Unique request identifier. user: Current user (if authenticated). principal: Resolved principal for identity access across resolvers. request: The GraphQL request. config: GraphQL configuration. started_at: Request start time. metadata: Additional context metadata. dataloaders: DataLoaderProtocol instances by name.

def get_dataloader(name: str) -> Any | None

Get a DataLoaderProtocol by name.

Parameters
ParameterTypeDescription
`name`strDataLoaderProtocol name.
Returns
TypeDescription
Any | NoneThe DataLoaderProtocol instance or None.
def set_dataloader(
    name: str,
    loader: Any
) -> None

Set a DataLoaderProtocol.

Parameters
ParameterTypeDescription
`name`strDataLoaderProtocol name.
`loader`AnyDataLoaderProtocol instance.
def get_metadata(
    key: str,
    default: Any = None
) -> Any

Get metadata value.

Parameters
ParameterTypeDescription
`key`strMetadata key.
`default`AnyDefault value if not found.
Returns
TypeDescription
AnyThe metadata value.
def set_metadata(
    key: str,
    value: Any
) -> None

Set metadata value.

Parameters
ParameterTypeDescription
`key`strMetadata key.
`value`AnyMetadata value.
property operation_name() -> str | None

Get the operation name from request.

property variables() -> dict[str, Any]

Get variables from request.

property elapsed_ms() -> float

Get elapsed time in milliseconds.

async def dispose_scope() -> None

Dispose the per-request DI scope, releasing all scoped services.

No-op when no scope was created for this context. The GraphQL executor calls this automatically; application code should not normally need to call it directly.


GraphQL HTTP endpoint controller.

This controller exposes GraphQL queries and mutations via HTTP POST at the configured path (default: /graphql).

Example

Registration is handled automatically by the GraphQL provider. To mount the controller manually, resolve the web application via the HTTPApplicationProtocol from contracts — do not import from lexigram.web directly

from lexigram.contracts.web.protocols import HTTPApplicationProtocol
# app = await container.resolve(HTTPApplicationProtocol)
# app.mount("/graphql", graphql_view)
def __init__(provider: GraphQLProvider | None = None) -> None

Initialize the GraphQL controller.

Parameters
ParameterTypeDescription
`provider`GraphQLProvider | NoneGraphQL provider instance. If None, will be resolved from the DI container at request time.
def collect_routes(cls) -> list[dict[str, Any]]

Collect routes from controller methods.

async def execute(request: GraphQLRequestProtocol) -> JSONResponse

Execute a GraphQL query.

Parameters
ParameterTypeDescription
`request`GraphQLRequestProtocolHTTP request containing the GraphQL query.
Returns
TypeDescription
JSONResponseJSON response with query results or errors.

Standard GraphQL error codes.

Structured GraphQL error data.
def to_dict() -> dict[str, Any]

Convert to standard GraphQL error format.


Extended error information.
def to_dict() -> dict[str, Any]

Convert to dictionary for JSON serialization.


GraphQL query executor.

Provides a high-level interface for executing GraphQL operations with proper error handling, timeout support, and metrics collection.

Example

from strawberry import Schema
from lexigram.graphql.core import GraphQLExecutorProtocol
schema = Schema(query=Query)
executor = GraphQLExecutorProtocol(schema)
response = await executor.execute(
query="{ hello }",
variables={},
)
def __init__(
    schema: StrawberrySchema,
    timeout_secs: float | None = None,
    middleware: list[Callable[Ellipsis, Any]] | None = None,
    error_config: ErrorConfig | None = None,
    event_bus: EventBusProtocol | None = None
) -> None

Initialize the executor.

Parameters
ParameterTypeDescription
`schema`StrawberrySchemaStrawberry GraphQL schema.
`timeout_secs`float | NoneDefault timeout in seconds.
`middleware`list[Callable[Ellipsis, Any]] | NoneList of middleware functions.
`error_config`ErrorConfig | NoneError configuration for formatting.
`event_bus`EventBusProtocol | NoneOptional EventBusProtocol for lifecycle event publishing. Subscribers receive BeforeExecuteEvent, AfterExecuteEvent, and OnErrorEvent.
property schema() -> StrawberrySchema

Get the GraphQL schema.

async def execute(
    query: str,
    variables: dict[str, Any] | None = None,
    operation_name: str | None = None,
    context: GraphQLContext | None = None,
    timeout_secs: float | None = None
) -> Result[GraphQLResponse[Any], Exception]

Execute a GraphQL query.

Parameters
ParameterTypeDescription
`query`strGraphQL query string.
`variables`dict[str, Any] | NoneQuery variables.
`operation_name`str | NoneOperation name to execute.
`context`GraphQLContext | NoneGraphQL context. Use ContextFactory.from_dict to convert a plain dictionary before passing it here.
`timeout`Timeout in seconds (overrides default).
Returns
TypeDescription
Result[GraphQLResponse, Exception]Result wrapping the response or an infrastructure error.
Raises
ExceptionDescription
NoneInfrastructure errors are wrapped in Err.
def get_metrics(execution_context: ExecutionContextProtocol) -> QueryMetrics

Get execution metrics.

Parameters
ParameterTypeDescription
`execution_context`ExecutionContextProtocolExecution context.
Returns
TypeDescription
QueryMetricsQuery metrics.

Location in a GraphQL document.

Aggregated GraphQL metrics.

Attributes: total_requests: Total number of requests. successful_requests: Number of successful requests. failed_requests: Number of failed requests. total_duration_ms: Total execution time. avg_duration_ms: Average execution time. operations_by_type: Count by operation type. operations_by_name: Count by operation name. errors_by_type: Error count by type.

def record_request(stats: QueryStats) -> None

Record a request’s statistics.

Parameters
ParameterTypeDescription
`stats`QueryStatsQuery statistics.
def record_error(error_type: str) -> None

Record an error.

Parameters
ParameterTypeDescription
`error_type`strType of error.
def to_dict() -> dict[str, Any]

Convert to dictionary.

Returns
TypeDescription
dict[str, Any]Dictionary representation.

GraphQL layer (Strawberry): schema building, execution, federation, and subscriptions.

Call configure to configure and mount the GraphQL endpoint.

Usage

import strawberry
@strawberry.type
class Query:
@strawberry.field
def hello(self) -> str:
return "world"
@module(
imports=[GraphQLModule.configure(query_class=Query)]
)
class AppModule(Module):
pass
def configure(
    cls,
    config: Any | None = None,
    query_class: Any | None = None,
    mutation_class: Any | None = None,
    subscription_class: Any | None = None
) -> DynamicModule

Create a GraphQLModule with explicit configuration.

Parameters
ParameterTypeDescription
`config`Any | NoneGraphQLConfig or ``None`` for framework defaults.
`query_class`Any | NoneOptional root Strawberry ``Query`` type.
`mutation_class`Any | NoneOptional root Strawberry ``Mutation`` type.
`subscription_class`Any | NoneOptional root Strawberry ``Subscription`` type.
Returns
TypeDescription
DynamicModuleA DynamicModule descriptor.
def stub(cls) -> DynamicModule

Return a no-op GraphQLModule suitable for unit testing.

Registers a GraphQLProvider with no schema types configured. Useful for testing application structure without a real GraphQL executor.

Returns
TypeDescription
DynamicModuleA DynamicModule with noop GraphQL configuration.

Provider for GraphQL functionality.

This provider integrates GraphQL capabilities into the Lexigram Framework, including schema building, execution, federation, and monitoring.

Features:

  • GraphQL schema management and execution
  • Apollo Federation support (subgraph)
  • DataLoaderProtocol for batching and caching
  • Query validation and depth limiting
  • Metrics collection and tracing
  • Subscription support
  • Security features (rate limiting, auth)

Configuration: The provider is configured via GraphQLConfig in the application configuration. If no config is provided, sensible defaults are used.

Usage

app = Application()
app.add_provider(GraphQLProvider())
def __init__(
    config: GraphQLConfig | None = None,
    query_class: Any | None = None,
    mutation_class: Any | None = None,
    subscription_class: Any | None = None,
    priority: ProviderPriority = ProviderPriority.PRESENTATION
) -> None

Initialize the GraphQL provider.

Parameters
ParameterTypeDescription
`config`GraphQLConfig | NoneGraphQL configuration. If None, uses defaults.
`query_class`Any | NoneOptional GraphQL Query class.
`mutation_class`Any | NoneOptional GraphQL Mutation class.
`subscription_class`Any | NoneOptional GraphQL Subscription class.
`priority`ProviderPriorityProvider priority for initialization order.
def from_config(
    cls,
    config: GraphQLConfig,
    **context: Any
) -> GraphQLProvider

Create a GraphQLProvider from config.

Context kwargs may include query_class, mutation_class, subscription_class.

def auto_discover(
    cls,
    *packages: str,
    config: GraphQLConfig | None = None,
    **kwargs: Any
) -> GraphQLProvider

Create a GraphQLProvider by scanning packages for Strawberry types.

Scans each package recursively for classes decorated with @strawberry.type whose name is Query, Mutation, or Subscription. Use @strawberry.type plus the naming convention or explicitly set __graphql_role__ = "query" / "mutation" / "subscription" on the class to override the name-based detection.

Parameters
ParameterTypeDescription
`config`GraphQLConfig | NoneOptional GraphQLConfig. Falls back to framework defaults when not provided. **kwargs: Extra keyword arguments forwarded to GraphQLProvider.__init__.
Returns
TypeDescription
GraphQLProviderA configured GraphQLProvider instance.

Example

app.add_provider(GraphQLProvider.auto_discover("my_app.graphql"))

In my_app/graphql/schema.py

import strawberry
@strawberry.type
class Query:
@strawberry.field
async def hello(self) -> str:
return "world"
@strawberry.type
class Mutation:
@strawberry.mutation
async def set_name(self, name: str) -> str:
return name
async def register(container: ContainerRegistrarProtocol) -> None

Register GraphQL services with the DI container.

Parameters
ParameterTypeDescription
`container`ContainerRegistrarProtocolThe dependency injection container registrar.
async def boot(container: BootContainerProtocol) -> None

Initialize GraphQL components.

Parameters
ParameterTypeDescription
`container`BootContainerProtocolThe application container resolver.
def executor() -> GraphQLExecutorProtocol | None

Get the GraphQL executor instance.

property context_factory() -> ContextFactory | None

Get the GraphQL context factory instance.

async def shutdown() -> None

Shutdown GraphQL components.

async def health_check(timeout: float = 5.0) -> HealthCheckResult

Check the health of GraphQL components.

Returns
TypeDescription
HealthCheckResultHealth check results.

GraphQL request model.

Represents an incoming GraphQL request with query, variables, and operation name.

Attributes: query: The GraphQL query string. variables: Variables for the query. operation_name: Name of the operation to execute. extensions: Optional extensions data.


Payload fired when a GraphQL operation request is received.

Attributes: operation_type: "query", "mutation", or "subscription". operation_name: Named operation, if present in the document.


GraphQL response model.

Represents a GraphQL response with data and/or errors.

Attributes: data: The result data. errors: List of errors if any occurred. extensions: Optional response extensions.

property has_errors() -> bool

Check if response has errors.

property is_successful() -> bool

Check if response is successful.

def add_error(
    message: str,
    path: list[str | int] | None = None,
    extensions: dict[str, Any] | None = None
) -> None

Add an error to the response.

Parameters
ParameterTypeDescription
`message`strError message.
`path`list[str | int] | NonePath to the error.
`extensions`dict[str, Any] | NoneAdditional error data.

Payload fired after a GraphQL response has been assembled.

Attributes: operation_type: "query", "mutation", or "subscription". has_errors: True if the response contains any GraphQL errors.


Payload fired after the GraphQL schema has been compiled and is ready.

GraphQL WebSocket subscription controller.

This controller handles GraphQL subscriptions via WebSocket at the configured path (default: /graphql/subscriptions).

def __init__(provider: GraphQLProvider | None = None) -> None

Initialize the subscription controller.

Parameters
ParameterTypeDescription
`provider`GraphQLProvider | NoneGraphQL provider instance. If None, will be resolved from the DI container at request time.
def collect_routes(cls) -> list[dict[str, Any]]

Collect routes from controller methods.


In-memory cache implementation.

Simple in-memory cache with optional TTL support. Suitable for single-request caching in DataLoaders.

Example

cache = InMemoryCache[str, User](ttl_seconds=60)
cache.set("user:1", user)
user = cache.get("user:1")
def __init__(
    ttl_seconds: float = 0,
    max_size: int = 0
) -> None

Initialize the cache.

Parameters
ParameterTypeDescription
`ttl_seconds`floatTime-to-live in seconds (0 for no TTL).
`max_size`intMaximum cache size (0 for unlimited).
property size() -> int

Get current cache size.

def get(key: K) -> V | None

Get a cached value.

Parameters
ParameterTypeDescription
`key`KCache key.
Returns
TypeDescription
V | NoneCached value or None if not found or expired.
def set(
    key: K,
    value: V
) -> None

Set a cached value.

Parameters
ParameterTypeDescription
`key`KCache key.
`value`VValue to cache.
def has(key: K) -> bool

Check if key exists and is not expired.

Parameters
ParameterTypeDescription
`key`KCache key.
Returns
TypeDescription
boolTrue if key exists and is valid.
def delete(key: K) -> None

Delete a cached value.

Parameters
ParameterTypeDescription
`key`KCache key.
def clear() -> None

Clear all cached values.

def cleanup_expired() -> int

Remove expired entries.

Returns
TypeDescription
intNumber of entries removed.

In-memory implementation of PersistedQueryStore.

Warning: Not suitable for production use with multiple instances. Use RedisPersistedQueryStore for production deployments.

def __init__(ttl_seconds: int | None = None)

Initialize the store.

Parameters
ParameterTypeDescription
`ttl_seconds`int | NoneOptional time-to-live for entries in seconds.
async def get(hash: str) -> str | None

Get a query by its hash.

async def put(
    hash: str,
    query: str
) -> None

Store a query with its hash.

def clear() -> None

Clear all stored queries.


GraphQL introspection configuration.

Attributes: enabled: Whether introspection is enabled. Defaults to True but the executor automatically disables it in environments not listed in allowed_environments. allowed_environments: Set of environment names (matched against LEX_ENV or the app environment) where introspection is permitted. Defaults to {"development", "testing"}; production is intentionally excluded.


Handle GraphQL schema introspection.

Provides utilities for introspecting GraphQL schemas, extracting type information, and generating schema documentation.

Example

handler = IntrospectionHandler(schema)
# Get all types
types = await handler.get_types()
# Get fields for a type
fields = await handler.get_type_fields("User")
def __init__(
    schema: Schema,
    enabled: bool = True
) -> None

Initialize the handler.

Parameters
ParameterTypeDescription
`schema`SchemaStrawberry GraphQL schema.
`enabled`boolWhether introspection is enabled.
property enabled() -> bool

Check if introspection is enabled.

def enable() -> None

Enable introspection.

def disable() -> None

Disable introspection.

async def introspect(simplified: bool = False) -> dict[str, Any]

Run introspection query.

Parameters
ParameterTypeDescription
`simplified`boolUse simplified query.
Returns
TypeDescription
dict[str, Any]Introspection result data.
async def get_types() -> list[dict[str, Any]]

Get all types in the schema.

Returns
TypeDescription
list[dict[str, Any]]List of type definitions.
async def get_type_fields(type_name: str) -> list[dict[str, Any]]

Get fields for a type.

Parameters
ParameterTypeDescription
`type_name`strName of the type.
Returns
TypeDescription
list[dict[str, Any]]List of field definitions.
async def get_query_type() -> dict[str, Any] | None

Get the query type.

Returns
TypeDescription
dict[str, Any] | NoneQuery type definition or None.
async def get_mutation_type() -> dict[str, Any] | None

Get the mutation type.

Returns
TypeDescription
dict[str, Any] | NoneMutation type definition or None.
async def get_subscription_type() -> dict[str, Any] | None

Get the subscription type.

Returns
TypeDescription
dict[str, Any] | NoneSubscription type definition or None.
def clear_cache() -> None

Clear the introspection cache.

async def generate_sdl() -> str

Generate SDL (Schema Definition Language) from schema.

Returns
TypeDescription
strSchema as SDL string.

Permission that requires admin role.
async def has_permission(
    source: Any,
    info: Info[Any, Any],
    **kwargs: Any
) -> bool

Check if user has admin role.


Permission that requires user authentication.
async def has_permission(
    source: Any,
    info: Info[Any, Any],
    **kwargs: Any
) -> bool

Check if user is authenticated.


Permission that requires ownership of the resource.
async def has_permission(
    source: Any,
    info: Info[Any, Any],
    **kwargs: Any
) -> bool

Check if user owns the resource.


Permission that requires ownership or admin role.
async def has_permission(
    source: Any,
    info: Info[Any, Any],
    **kwargs: Any
) -> bool

Check if user owns the resource or is admin.


Abstract base class for DataLoaderProtocol caches.

Implement this interface to provide custom caching behavior for DataLoaders.

def get(key: K) -> V | None

Get a cached value.

Parameters
ParameterTypeDescription
`key`KCache key.
Returns
TypeDescription
V | NoneCached value or None.
def set(
    key: K,
    value: V
) -> None

Set a cached value.

Parameters
ParameterTypeDescription
`key`KCache key.
`value`VValue to cache.
def has(key: K) -> bool

Check if key exists in cache.

Parameters
ParameterTypeDescription
`key`KCache key.
Returns
TypeDescription
boolTrue if key exists.
def delete(key: K) -> None

Delete a cached value.

Parameters
ParameterTypeDescription
`key`KCache key.
def clear() -> None

Clear all cached values.


Collector for GraphQL metrics.

Collects and aggregates metrics from GraphQL operations. When a MetricsRecorderProtocol is provided (resolved from the DI container) every recorded query stat is forwarded to the kernel-level unified metrics pipeline so GraphQL telemetry lands alongside infra metrics.

Example

from lexigram.contracts.observability.metrics import MetricsRecorderProtocol
collector = MetricsCollectorProtocol(recorder=recorder)
collector.record(QueryStats(operation_name="GetUser", duration_ms=50.0))
def __init__(
    max_history: int = 1000,
    recorder: MetricsRecorderProtocol | None = None
) -> None

Initialize the collector.

Parameters
ParameterTypeDescription
`max_history`intMaximum number of stats to keep in the rolling history.
`recorder`MetricsRecorderProtocol | NoneOptional kernel MetricsRecorderProtocol for unified observability.
def record(stats: QueryStats) -> None

Record query statistics and forward to the kernel MetricsRecorderProtocol.

Parameters
ParameterTypeDescription
`stats`QueryStatsQuery statistics.
def record_error(error: Exception) -> None

Record an error.

Parameters
ParameterTypeDescription
`error`ExceptionThe exception.
def get_metrics() -> GraphQLMetrics

Get current metrics.

Returns
TypeDescription
GraphQLMetricsCurrent metrics.
def get_recent_stats(limit: int = 100) -> list[QueryStats]

Get recent query statistics.

Parameters
ParameterTypeDescription
`limit`intMaximum number of stats to return.
Returns
TypeDescription
list[QueryStats]List of recent stats.
def reset() -> None

Reset all metrics.

async def close() -> None

Async close hook for the collector (no-op).

Provides symmetry with other resources that expose async close so callers can await shutdown without conditional checks.


Metrics collection configuration.

Attributes: enabled: Whether metrics are enabled. namespace: Metrics namespace/prefix. include_labels: Labels to include in metrics. histogram_buckets: Buckets for duration histograms.


Strawberry extension for metrics collection.

Automatically collects metrics for all GraphQL operations.

Example

from lexigram.graphql.monitoring import MetricsExtension
schema = strawberry.Schema(
query=Query,
extensions=[MetricsExtension()],
)
def __init__(collector: MetricsCollectorProtocol | None = None) -> None

Initialize the extension.

Parameters
ParameterTypeDescription
`collector`MetricsCollectorProtocol | NoneMetrics collector to use.
async def on_operation() -> AsyncGenerator[None, None]

Hook called during operation execution.


Standard mutation result type.

Attributes: success: Whether the mutation succeeded. data: Result data if successful. errors: Error messages if failed.


No-operation cache (disables caching).

Use this when you want to disable DataLoaderProtocol caching while keeping the batching behavior.

def get(key: K) -> V | None

Always returns None.

def set(
    key: K,
    value: V
) -> None

Does nothing.

def has(key: K) -> bool

Always returns False.

def delete(key: K) -> None

Does nothing.

def clear() -> None

Does nothing.


Emitted when a GraphQL operation encounters an unhandled exception.

This is fired for infrastructure-level errors (timeouts, executor crashes), not for user-facing field errors which are part of the normal GraphQL response.


Information about a GraphQL operation.

GraphQL operation types.

Pagination information.

Simple offset-based pagination result.

Attributes: items: List of items in the current page. total: Total number of items. page: Current page number (1-indexed). page_size: Number of items per page. has_next: Whether there are more pages. has_previous: Whether there are previous pages.

property total_pages() -> int

Calculate total number of pages.


Input for pagination parameters.

Attributes: page: Page number (1-indexed). page_size: Number of items per page.


GraphQL Playground/GraphiQL configuration.

Attributes: enabled: Whether playground is enabled. path: Path to serve playground at. title: Title for the playground page.


Metrics for a GraphQL query execution.
def complete() -> None

Mark the query as complete and calculate duration.


Statistics for a single query execution.

Attributes: operation_name: Name of the operation. operation_type: Type (query, mutation, subscription). start_time: Execution start time. end_time: Execution end time. duration_ms: Execution duration in milliseconds. success: Whether execution succeeded. error_count: Number of errors.


Configuration for rate limiting.

Attributes: enabled: Whether rate limiting is enabled. requests_per_minute: Number of allowed requests per minute. burst_limit: Maximum burst size.


Enforce rate limiting on every GraphQL operation.

This extension delegates the actual limit check to the injected RateLimiter (resolved from the DI container by GraphQLProvider) and raises RateLimitError when the limit is exceeded.

Register it on the schema builder instead of wiring it into the executor

builder.add_extension(
RateLimitExtension(rate_limiter=rate_limiter, max_requests=60)
)
Parameters
ParameterTypeDescription
`rate_limiter`Rate limiter implementation; when ``None`` the extension is a no-op (useful for local/test environments).
`max_requests`Request allowance per window.
`window_seconds`Window length in seconds.
def __init__(
    *,
    rate_limiter: RateLimiter | None = None,
    max_requests: int = 60,
    window_seconds: int = 60
) -> None
async def on_operation() -> AsyncGenerator[None, None]

Check the rate limit before the GraphQL operation executes.


Base class for rate limiters.
async def is_allowed(
    context: Any,
    **kwargs: Any
) -> bool

Check if a request is allowed.


Redis-backed implementation of PersistedQueryStore.

Suitable for production use with multiple application instances.

def __init__(
    redis_client: Any,
    key_prefix: str = 'graphql:apq:',
    ttl_seconds: int = 86400
)

Initialize the store.

Parameters
ParameterTypeDescription
`redis_client`AnyRedis client instance (aioRedis or redis-py async).
`key_prefix`strPrefix for Redis keys.
`ttl_seconds`intTime-to-live for entries in seconds.
async def get(hash: str) -> str | None

Get a query by its hash.

async def put(
    hash: str,
    query: str
) -> None

Store a query with its hash.


Adapts a plain callable to the ResolverProtocol protocol.

Accepts any sync or async callable with the signature (parent, args, context, info) -> Any and exposes it as a ResolverProtocol via a resolve method. Sync callables are called directly; their return value is awaited only when it happens to be a coroutine.

Parameters
ParameterTypeDescription
`func`A sync or async callable that implements the resolver logic. The callable should accept up to four positional arguments: ``(parent, args, context, info)``. Arguments beyond what the callable declares are silently dropped so that short signatures (e.g. ``lambda parent, args: parent.id``) work transparently.
def __init__(func: Any) -> None
async def resolve(
    parent: Any,
    args: dict[str, Any],
    context: Any,
    info: Any
) -> Any

Invoke the wrapped callable with the resolver arguments.

Parameters
ParameterTypeDescription
`parent`AnyParent (root) object for the field.
`args`dict[str, Any]Parsed field arguments from the GraphQL query.
`context`AnyShared execution context.
`info`AnyGraphQL resolution info object.
Returns
TypeDescription
AnyResolved field value.

Context information passed to resolvers.

Build GraphQL schemas with configuration.

Provides a fluent interface for constructing GraphQL schemas with proper configuration, extensions, and type registration.

Example

builder = SchemaBuilderProtocol()
schema = (
builder
.query(Query)
.mutation(Mutation)
.subscription(Subscription)
.add_extension(QueryLogger())
.build()
)
def __init__(config: GraphQLConfig | None = None) -> None

Initialize the schema builder.

Parameters
ParameterTypeDescription
`config`GraphQLConfig | NoneGraphQL configuration.
def query(query_type: type[Any]) -> SchemaBuilderProtocol

Set the query type.

Parameters
ParameterTypeDescription
`query_type`type[Any]The query type class.
Returns
TypeDescription
SchemaBuilderProtocolSelf for chaining.
def mutation(mutation_type: type[Any]) -> SchemaBuilderProtocol

Set the mutation type.

Parameters
ParameterTypeDescription
`mutation_type`type[Any]The mutation type class.
Returns
TypeDescription
SchemaBuilderProtocolSelf for chaining.
def subscription(subscription_type: type[Any]) -> SchemaBuilderProtocol

Set the subscription type.

Parameters
ParameterTypeDescription
`subscription_type`type[Any]The subscription type class.
Returns
TypeDescription
SchemaBuilderProtocolSelf for chaining.
def add_type(type_class: type[Any]) -> SchemaBuilderProtocol

Add an additional type to the schema.

Parameters
ParameterTypeDescription
`type_class`type[Any]The type class to add.
Returns
TypeDescription
SchemaBuilderProtocolSelf for chaining.
def add_types(*type_classes: type[Any]) -> SchemaBuilderProtocol

Add multiple types to the schema.

Parameters
ParameterTypeDescription
`type_classes`type[Any]Type classes to add.
Returns
TypeDescription
SchemaBuilderProtocolSelf for chaining.
def add_extension(extension: Any) -> SchemaBuilderProtocol

Add a schema extension.

Parameters
ParameterTypeDescription
`extension`AnyThe extension to add (kept as Any to avoid strict coupling to Strawberry's extension type in various environments).
Returns
TypeDescription
SchemaBuilderProtocolSelf for chaining.
def add_dataloader(
    name: str,
    factory: Any
) -> SchemaBuilderProtocol

Register a DataLoaderProtocol factory for per-request loader initialisation.

Stored factories are wired into ContextFactory by GraphQLProvider during boot(), so loaders are available inside resolvers via context.get_dataloader(name).

Parameters
ParameterTypeDescription
`name`strUnique loader name.
`factory`AnyCallable ``(context) -> DataLoaderProtocol`` invoked per-request.
Returns
TypeDescription
SchemaBuilderProtocolSelf for chaining.
def add_directive(directive: Any) -> SchemaBuilderProtocol

Add a custom directive.

Parameters
ParameterTypeDescription
`directive`AnyThe directive to add.
Returns
TypeDescription
SchemaBuilderProtocolSelf for chaining.
def scalar_override(
    original: Any,
    override: Any
) -> SchemaBuilderProtocol

Override a scalar type.

Parameters
ParameterTypeDescription
`original`AnyOriginal scalar type.
`override`AnyOverride scalar type.
Returns
TypeDescription
SchemaBuilderProtocolSelf for chaining.
def build() -> Schema

Build the GraphQL schema.

Returns
TypeDescription
SchemaConfigured Strawberry schema.
Raises
ExceptionDescription
ValueErrorIf no query type is set and no default is provided.
property config() -> GraphQLConfig

Get the configuration.


Emitted after the GraphQL schema is successfully built.

Consumers may inspect type counts for observability and diagnostics.


Validate GraphQL schemas and queries.

Provides comprehensive validation of GraphQL queries against the schema, delegating depth enforcement to DepthLimitValidator and alias enforcement to AliasLimitValidator.

Example

validator = SchemaValidator(schema)
result = validator.validate_query(query)
if not result.is_valid:
for error in result.errors:
logger.info("Validation error: %s", error)
def __init__(
    schema: Any,
    max_depth: int = 10,
    max_aliases: int = 10
) -> None

Initialize the validator.

Parameters
ParameterTypeDescription
`schema`AnyGraphQL schema.
`max_depth`intMaximum query depth (delegated to DepthLimitValidator).
`max_aliases`intMaximum number of aliases (delegated to AliasLimitValidator).
def validate_query(
    query: str,
    variables: dict[str, Any] | None = None
) -> ValidationResult

Validate a GraphQL query.

Parameters
ParameterTypeDescription
`query`strGraphQL query string.
`variables`dict[str, Any] | NoneQuery variables.
Returns
TypeDescription
ValidationResultValidation result.

Input for sorting.

Attributes: field: Field to sort by. direction: Sort direction (ASC or DESC).


WebSocket subscription configuration.

Attributes: enabled: Whether subscriptions are enabled. path: WebSocket path for subscriptions. protocol: WebSocket protocol to use. keepalive_interval: Keepalive interval in seconds. connection_timeout: Connection timeout in seconds.


Information about an active subscription.

WebSocket subscription protocols.

Emitted when a GraphQL subscription is established.

Provides the subscription identifier and operation name for tracking and auditing long-lived connections.


A span in the execution trace.

Attributes: name: Span name. start_time: Start timestamp. end_time: End timestamp. duration_ms: Duration in milliseconds. metadata: Additional span metadata. children: Child spans.

def end() -> None

End the span and calculate duration.

def add_child(child: TraceSpan) -> None

Add a child span.

def to_dict() -> dict[str, Any]

Convert to dictionary.

Returns
TypeDescription
dict[str, Any]Dictionary representation.

Distributed tracing configuration.

Attributes: enabled: Whether tracing is enabled. service_name: Service name for tracing. trace_resolvers: Whether to trace individual resolvers. trace_dataloaders: Whether to trace DataLoaderProtocol batches. sample_rate: Sampling rate (0.0 to 1.0).


Strawberry extension for query tracing.

Adds tracing information to query responses in Apollo tracing format.

Example

from lexigram.graphql.monitoring import TracingExtension
schema = strawberry.Schema(
query=Query,
extensions=[TracingExtension()],
)
def __init__(
    include_in_response: bool = True,
    tracer: TracerProtocol | None = None
) -> None

Initialize the extension.

Parameters
ParameterTypeDescription
`include_in_response`boolInclude tracing in response extensions.
`tracer`TracerProtocol | NoneOptional kernel TracerProtocol for unified distributed tracing. When provided, GraphQL operation and resolver spans are forwarded to the application-wide tracing pipeline so GraphQL telemetry is correlated with infra traces.
def on_operation() -> Iterator[None]

Hook called during operation execution.

def resolve(
    _next: Callable[Ellipsis, Any],
    root: Any,
    info: Any,
    *args: Any,
    **kwargs: Any
) -> Any

Hook called during field resolution.


Rate limiter that delegates to an injected web rate limiter.
def __init__(web_rate_limiter: WebRateLimiterProtocol | None = None) -> None
async def is_allowed(
    context: Any,
    **kwargs: Any
) -> bool

Check if a request is allowed using the web rate limiter.


Result of query validation.

Attributes: is_valid: Whether the query is valid. errors: List of validation errors. depth: Maximum query depth. field_count: Total number of fields. warnings: Non-fatal warnings.

def add_error(error: str) -> None

Add a validation error.

def add_warning(warning: str) -> None

Add a validation warning.


def compute_query_hash(query: str) -> str

Compute SHA256 hash of a GraphQL query.

Parameters
ParameterTypeDescription
`query`strThe GraphQL query string.
Returns
TypeDescription
strHex-encoded SHA256 hash.

def create_connection_type(
    node_type: type[T],
    name: str | None = None
) -> type[Connection[T]]

Create a Connection type for a specific node type.

Parameters
ParameterTypeDescription
`node_type`type[T]The node type for the connection.
`name`str | NoneOptional name prefix for the connection type.
Returns
TypeDescription
type[Connection[T]]A Connection type class.

def create_depth_limit(
    max_depth: int = 10,
    ignore_introspection: bool = True
) -> DepthLimitExtension

Create a depth limit extension (convenience function).

Parameters
ParameterTypeDescription
`max_depth`intMaximum allowed depth.
`ignore_introspection`boolSkip introspection queries.
Returns
TypeDescription
DepthLimitExtensionConfigured extension.

Example

schema = strawberry.Schema(
query=Query,
extensions=[create_depth_limit(5)],
)

def create_loader(
    batch_fn: Callable[[list[K]], Awaitable[list[V | None]]],
    batch_size: int = 100,
    cache_enabled: bool = True
) -> DataLoaderProtocol[K, V]

Create a DataLoaderProtocol (convenience function).

Parameters
ParameterTypeDescription
`batch_fn`Callable[[list[K]], Awaitable[list[V | None]]]Batch load function.
`batch_size`intMaximum batch size.
`cache_enabled`boolWhether to enable caching.
Returns
TypeDescription
DataLoaderProtocol[K, V]Configured DataLoaderProtocol.

Example

user_loader = create_loader(
batch_load_users,
batch_size=50,
)
user = await user_loader.load("123")

def create_schema(
    query: type[Any],
    mutation: type[Any] | None = None,
    subscription: type[Any] | None = None,
    types: list[type[Any]] | None = None,
    extensions: list[Any] | None = None,
    config: GraphQLConfig | None = None
) -> Schema

Create a GraphQL schema (convenience function).

Parameters
ParameterTypeDescription
`query`type[Any]Query type class.
`mutation`type[Any] | NoneOptional mutation type class.
`subscription`type[Any] | NoneOptional subscription type class.
`types`list[type[Any]] | NoneAdditional type classes.
`extensions`list[Any] | NoneSchema extensions.
`config`GraphQLConfig | NoneGraphQL configuration.
Returns
TypeDescription
SchemaConfigured Strawberry schema.

Example

schema = create_schema(
query=Query,
mutation=Mutation,
config=GraphQLConfig(depth_limit=5),
)

def decode_cursor(cursor: str) -> int

Decode a base64 cursor to an offset.

Parameters
ParameterTypeDescription
`cursor`strThe cursor string to decode.
Returns
TypeDescription
intThe decoded offset.
Raises
ExceptionDescription
ValueErrorIf the cursor is invalid.

def decode_cursor_to_id(cursor: str) -> str

Decode a cursor to an item ID.

Parameters
ParameterTypeDescription
`cursor`strThe cursor string to decode.
Returns
TypeDescription
strThe decoded item ID.
Raises
ExceptionDescription
ValueErrorIf the cursor is invalid.

def encode_cursor(offset: int) -> str

Encode an offset as a base64 cursor.

Parameters
ParameterTypeDescription
`offset`intThe offset to encode.
Returns
TypeDescription
strBase64-encoded cursor string.

def encode_cursor_from_id(item_id: str) -> str

Encode an item ID as an opaque cursor.

Parameters
ParameterTypeDescription
`item_id`strThe item ID to encode.
Returns
TypeDescription
strBase64-encoded cursor string.

async def execute_query(
    schema: StrawberrySchema,
    query: str,
    variables: dict[str, Any] | None = None,
    operation_name: str | None = None,
    context: GraphQLContext | None = None
) -> GraphQLResponse[Any]

Execute a GraphQL query (convenience function).

If you need to build a context from a plain dictionary, use ContextFactory.from_dict() before calling this function.

Parameters
ParameterTypeDescription
`schema`StrawberrySchemaStrawberry GraphQL schema.
`query`strGraphQL query string.
`variables`dict[str, Any] | NoneQuery variables.
`operation_name`str | NoneOperation name.
`context`GraphQLContext | NoneGraphQL context.
Returns
TypeDescription
GraphQLResponse[Any]GraphQL response.

def field(
    name: str | None = None,
    description: str | None = None,
    deprecation_reason: str | None = None,
    default: Any = strawberry.UNSET,
    default_factory: Callable[[], Any] | None = None,
    permission_classes: list[Any] | None = None
) -> Any

Define a GraphQL field.

This is a wrapper around Strawberry’s field function with additional Lexigram-specific functionality.

Parameters
ParameterTypeDescription
`name`str | NoneOptional field name.
`description`str | NoneField description.
`deprecation_reason`str | NoneDeprecation reason if deprecated.
`default`AnyDefault value.
`default_factory`Callable[[], Any] | NoneFactory for default value.
`permission_classes`list[Any] | NonePermission classes for authorization.
Returns
TypeDescription
AnyStrawberry field.

Example

@strawberry.type
class User:
id: str
name: str = field(description="User's full name")
email: str = field(description="User's email address")

def get_context(info: Info) -> GraphQLContext

Get the GraphQL context from resolver info.

Parameters
ParameterTypeDescription
`info`InfoStrawberry resolver info.
Returns
TypeDescription
GraphQLContextGraphQL context.

Example

@strawberry.type
class Query:
@strawberry.field
async def me(self, info: Info) -> User:
context = get_context(info)
return context.user

def get_introspection_query(simplified: bool = False) -> str

Get the GraphQL introspection query.

Parameters
ParameterTypeDescription
`simplified`boolIf True, return simplified query.
Returns
TypeDescription
strIntrospection query string.

async def get_metrics_collector(context: Any | None = None) -> MetricsCollectorProtocol

Get the metrics collector instance.


def log_resolver(fn: F) -> F

Wrap an async GraphQL resolver with structured entry/exit/error logging.

Emits debug-level log events on entry and exit, and an error-level event when an exception propagates out of the resolver. The exception is always re-raised — this decorator never swallows errors.

Parameters
ParameterTypeDescription
`fn`FThe async resolver function to wrap.
Returns
TypeDescription
FWrapped resolver with structured logging applied.

Example

@strawberry.type
class Mutation:
@log_resolver
async def create_user(self, info: Info, input: CreateUserInput) -> User:
return await service.create(input)

def mutation(
    name: str | None = None,
    description: str | None = None,
    deprecation_reason: str | None = None,
    permission_classes: list[Any] | None = None
) -> Callable[[Callable[P, T]], Callable[P, Any]]

Decorator for marking a method as a GraphQL mutation.

This is a wrapper around Strawberry’s mutation decorator with additional Lexigram-specific functionality.

Parameters
ParameterTypeDescription
`name`str | NoneOptional field name (defaults to function name).
`description`str | NoneField description for documentation.
`deprecation_reason`str | NoneIf set, marks the field as deprecated.
`permission_classes`list[Any] | NoneList of permission classes for authorization.
Returns
TypeDescription
Callable[[Callable[P, T]], Callable[P, Any]]Decorated function.

Example

@strawberry.type
class Mutation:
@mutation(description="Create a new user")
async def create_user(
self, info: Info, input: CreateUserInput
) -> User:
return await create_user(input)

def query(
    name: str | None = None,
    description: str | None = None,
    deprecation_reason: str | None = None,
    permission_classes: list[Any] | None = None
) -> Callable[[Callable[P, T]], Callable[P, Any]]

Decorator for marking a method as a GraphQL query.

This is a wrapper around Strawberry’s field decorator with additional Lexigram-specific functionality.

Parameters
ParameterTypeDescription
`name`str | NoneOptional field name (defaults to function name).
`description`str | NoneField description for documentation.
`deprecation_reason`str | NoneIf set, marks the field as deprecated.
`permission_classes`list[Any] | NoneList of permission classes for authorization.
Returns
TypeDescription
Callable[[Callable[P, T]], Callable[P, Any]]Decorated function.

Example

@strawberry.type
class Query:
@query(description="Get user by ID")
async def user(self, info: Info, id: str) -> User:
return await get_user(id)

def resolver(
    name: str | None = None,
    description: str | None = None
) -> Callable[[Callable[P, T]], Callable[P, Any]]

Decorator for field resolvers.

Use this to define a resolver function that can be used as a field resolver in a GraphQL type.

Parameters
ParameterTypeDescription
`name`str | NoneOptional resolver name.
`description`str | NoneResolverProtocol description.
Returns
TypeDescription
Callable[[Callable[P, T]], Callable[P, Any]]Decorated resolver function.

Example

@resolver(description="Resolve user's full name")
async def resolve_full_name(
root: User, info: Info
) -> str:
return f"{root.first_name} {root.last_name}"
@strawberry.type
class User:
first_name: str
last_name: str
full_name: str = strawberry.field(resolver=resolve_full_name)

def retry_resolver(
    max_retries: int = 3,
    *,
    delay: float = 0.1,
    exceptions: tuple[type[Exception], Ellipsis] = (Exception,)
) -> Callable[[F], F]

Wrap an async GraphQL resolver with automatic retry logic.

Retries the decorated resolver up to max_retries times when any of the specified exceptions are raised. Uses exponential back-off between attempts: delay * 2 ** attempt seconds.

Parameters
ParameterTypeDescription
`max_retries`intMaximum number of attempts before re-raising the last exception. Must be at least 1.
`delay`floatBase delay in seconds between retries. Doubles on each attempt.
`exceptions`tuple[type[Exception], Ellipsis]Tuple of exception types that trigger a retry. Defaults to ``(Exception,)`` — any exception retries.
Returns
TypeDescription
Callable[[F], F]Decorator that wraps an async resolver with retry machinery.

Example

@strawberry.type
class Query:
@retry_resolver(max_retries=3, delay=0.2, exceptions=(TimeoutError,))
async def user(self, info: Info, id: str) -> User:
return await fetch_user(id)

def subscription(
    name: str | None = None,
    description: str | None = None,
    deprecation_reason: str | None = None,
    permission_classes: list[Any] | None = None
) -> Callable[[Callable[P, T]], Callable[P, Any]]

Decorator for marking a method as a GraphQL subscription.

This is a wrapper around Strawberry’s subscription decorator with additional Lexigram-specific functionality.

Parameters
ParameterTypeDescription
`name`str | NoneOptional field name (defaults to function name).
`description`str | NoneField description for documentation.
`deprecation_reason`str | NoneIf set, marks the field as deprecated.
`permission_classes`list[Any] | NoneList of permission classes for authorization.
Returns
TypeDescription
Callable[[Callable[P, T]], Callable[P, Any]]Decorated function.

Example

@strawberry.type
class Subscription:
@subscription(description="Subscribe to messages")
async def messages(
self, info: Info, room_id: str
) -> AsyncGenerator[Message, None]:
async for msg in message_stream(room_id):
yield msg

def trace_resolver(name: str | None = None) -> Callable[[Callable[P, T]], Callable[P, T]]

Decorator for tracing resolver execution.

Parameters
ParameterTypeDescription
`name`str | NoneOptional span name.
Returns
TypeDescription
Callable[[Callable[P, T]], Callable[P, T]]Decorator function.

Example

@strawberry.type
class Query:
@trace_resolver("fetch_user")
@strawberry.field
async def user(self, info: Info, id: str) -> User:
return await get_user(id)

def union_type(
    *types: Any,
    name: str | None = None
) -> Any

Create a GraphQL union type.

Parameters
ParameterTypeDescription
`types`AnyTypes to include in the union.
`name`str | NoneOptional name for the union.
Returns
TypeDescription
AnyUnion type annotation.

Example

SearchResult = union_type(User, Post, Comment, name="SearchResult")
@strawberry.type
class Query:
@strawberry.field
def search(self, query: str) -> list[SearchResult]:
...

def validate_query(
    schema: Any,
    query: str,
    variables: dict[str, Any] | None = None,
    max_depth: int = 10
) -> ValidationResult

Validate a GraphQL query (convenience function).

Parameters
ParameterTypeDescription
`schema`AnyGraphQL schema.
`query`strGraphQL query string.
`variables`dict[str, Any] | NoneQuery variables.
`max_depth`intMaximum allowed depth.
Returns
TypeDescription
ValidationResultValidation result.

Raised when authentication is required but missing.

Also satisfies lexigram.contracts.exceptions.AuthenticationError so middleware that catches the contracts type will catch this as well.


Raised when user is authenticated but lacks permissions.

Also satisfies lexigram.contracts.exceptions.AuthorizationError so middleware that catches the contracts type will catch this as well.


Raised when access is forbidden.

Raised when a network connection error occurs during GraphQL execution.

Base exception for all GraphQL errors.
def __init__(
    message: str,
    *,
    code: GraphQLErrorCode | None = None,
    **kwargs: Any
) -> None

Raised for invalid user input.

Raised when a requested resource is not found.

Raised when query parsing fails.

Raised when query exceeds complexity limit.

Raised when a GraphQL query exceeds the maximum depth.

Raised when rate limit is exceeded.

Raised when a resolver fails.

Raised for subscription-related errors.