Skip to content
GitHubDiscord

Graphql (lexigram-graphql)

GraphQL support for Lexigram Framework — Strawberry, Apollo Federation, and subscriptions.


lexigram-graphql provides a complete GraphQL layer built on Strawberry, with field-level permissions, DataLoaderProtocol batching for N+1 query elimination, WebSocket subscriptions, depth/complexity limiting, persisted queries, and automatic playground disable in production. All services are wired through Lexigram’s DI container.


Terminal window
uv add lexigram lexigram-web lexigram-graphql
# Optional extras
uv add "lexigram-graphql[starlette]" # Starlette integration
uv add "lexigram-graphql[subscriptions]" # WebSocket subscriptions
from lexigram import Application
from lexigram.di.module import Module, module
from lexigram.graphql import GraphQLModule
from lexigram.web import WebModule
import strawberry
@strawberry.type
class Query:
@strawberry.field
def hello(self) -> str:
return "world"
@module(
imports=[
WebModule.configure(host="127.0.0.1", port=8000),
GraphQLModule.configure(query_class=Query),
]
)
class AppModule(Module):
pass
async def main() -> None:
async with Application.boot(modules=[AppModule]) as app:
web = await app.container.resolve(WebProvider)
web.run_server(host="127.0.0.1", port=8000)
if __name__ == "__main__":
import asyncio
asyncio.run(main())

GraphQL endpoint: http://127.0.0.1:8000/graphql Playground: http://127.0.0.1:8000/graphql/playground (development only)

Zero-config usage: Call GraphQLModule.configure() with no arguments to use all defaults.

application.yaml
graphql:
server:
path: "/graphql"
debug: false
playground:
enabled: true
schema:
max_depth: 10
complexity_limit: 1000
Section titled “Option 2 — Profiles + Environment Variables (recommended)”
Terminal window
export LEX_GRAPHQL__PATH=/api/graphql
export LEX_GRAPHQL__DEBUG=true
export LEX_GRAPHQL__DEPTH_LIMIT__MAX_DEPTH=8
from lexigram.graphql import GraphQLModule
from lexigram.graphql.config import GraphQLConfig
config = GraphQLConfig.development()
GraphQLModule.configure(config=config, query_class=Query)
FieldDefaultEnv varDescription
path"/graphql"LEX_GRAPHQL__PATHGraphQL HTTP endpoint
debugfalseLEX_GRAPHQL__DEBUGPropagates to errors.debug_mode
introspection.enabledtrueLEX_GRAPHQL__INTROSPECTION__ENABLEDDisabled automatically in production
playground.enabledtrueLEX_GRAPHQL__PLAYGROUND__ENABLEDDisabled automatically in production
playground.path"/graphql/playground"LEX_GRAPHQL__PLAYGROUND__PATHPlayground URL
subscriptions.enabledtrueLEX_GRAPHQL__SUBSCRIPTIONS__ENABLEDWebSocket subscriptions
subscriptions.path"/graphql/ws"LEX_GRAPHQL__SUBSCRIPTIONS__PATHWebSocket endpoint
depth_limit.enabledtrueLEX_GRAPHQL__DEPTH_LIMIT__ENABLEDEnable query depth limiting
depth_limit.max_depth10LEX_GRAPHQL__DEPTH_LIMIT__MAX_DEPTHMaximum allowed query depth
complexity.enabledtrueLEX_GRAPHQL__COMPLEXITY__ENABLEDEnable complexity scoring
complexity.max_complexity1000LEX_GRAPHQL__COMPLEXITY__MAX_COMPLEXITYMaximum complexity score
dataloader.enabledtrueLEX_GRAPHQL__DATALOADER__ENABLEDEnable DataLoaderProtocol integration
dataloader.batch_delay_ms2.0LEX_GRAPHQL__DATALOADER__BATCH_DELAY_MSBatch accumulation delay (ms)
persisted_queries.enabledtrueLEX_GRAPHQL__PERSISTED_QUERIES__ENABLEDAutomatic persisted queries (APQ)
cache.enabledtrueLEX_GRAPHQL__CACHE__ENABLEDResponse caching
errors.mask_errorstrueLEX_GRAPHQL__ERRORS__MASK_ERRORSMask internal errors in responses
schema_baseline_pathnullLEX_GRAPHQL__SCHEMA_BASELINE_PATHSDL file for breaking-change detection
MethodDescription
GraphQLModule.configure(...)Configure with explicit config and query class
GraphQLModule.stub()Minimal config for testing
  • Strawberry GraphQL — schema-first GraphQL with type annotations
  • DataLoaderProtocol batching — eliminates N+1 queries with per-request caching
  • WebSocket subscriptions — graphql-transport-ws protocol support
  • Depth and complexity limiting — prevents malicious or expensive queries
  • Field-level permissions — AbstractPermission subclassing for fine-grained access
  • Automatic persisted queries (APQ) — reduces payload size for repeated queries
  • Schema baseline checking — detect breaking changes at boot via SDL comparison
from lexigram import Application
from lexigram.graphql import GraphQLModule
async with Application.boot(modules=[GraphQLModule.stub()]) as app:
executor = await app.container.resolve(GraphQLExecutorProtocol)
assert executor is not None
FileWhat it contains
src/lexigram/graphql/module.pyGraphQLModule.configure(), .stub()
src/lexigram/graphql/config.pyGraphQLConfig and all sub-configs
src/lexigram/graphql/di/provider.pyGraphQLProvider boot and registration
src/lexigram/graphql/security/permissions.pyAbstractPermission base class
src/lexigram/graphql/dataloader/loader.pyDataLoaderProtocol implementation
src/lexigram/graphql/decorators.py@retry_resolver, @log_resolver