hexastack-graphql
Strawberry GraphQL presentation adapter and CQRS integration for Hexastack.
Part of the Hexastack Framework · Governed by Hexaqual.
1. Overview & Capabilities
hexastack-graphql brings the power and type-safety of Strawberry GraphQL into the Hexastack architecture:
- Type-Safe GraphQL Schemas: Native Python dataclass-based GraphQL schema definition via Strawberry.
- CQRS Integration via Context: Injects the
rodi.Container,CommandBusPort, andQueryBusPortdirectly into Strawberry'sInfo.context(GraphQLContext). - Declarative Query & Mutation Registries:
@graphql_query_typeand@graphql_mutation_type: Register whole type classes to be merged into root Query and Mutation types.@graphql_queryand@graphql_mutation: Register standalone resolver functions as top-level fields.
- Dynamic Field Resolver Feature Flagging:
@feature_flag_field("flag_key", raise_error=True, fallback=...): Evaluates feature flags dynamically before executing field resolvers, raising aGraphQLErroror returning a safe fallback value.
- Observability & Metrics:
StrawberryMetricsExtension: Captures operation execution duration histograms and throughput counters pushed toMetricsPort.
- FastAPI Mount & GraphiQL Playground: Seamless mounting as a
GraphQLRouterinto FastAPI applications with interactive GraphiQL playground enabled.
2. Package Anatomy & Key Components
hexastack_graphql/
├── domain/ # GraphQLContext, GraphQLError, SchemaBuildingError
├── ports/ # GraphQLContextFactoryPort
├── adapters/ # create_graphql_router, mount_graphql_router (FastAPI integration)
└── infra/
├── bootstrap.py # GraphQLBootstrapper (order=35)
├── config.py # HexastackGraphQLConfig
├── decorators.py# @graphql_query, @graphql_mutation, @graphql_query_type, @graphql_mutation_type, @feature_flag_field
└── registries/ # schema.py (GraphQLSchemaRegistry)
Key Exports
| Category | Exports |
|---|---|
| Bootstrap | GraphQLBootstrapper (order=35), HexastackGraphQLConfig |
| Context & Domain | GraphQLContext, GraphQLError, SchemaBuildingError |
| Decorators | @graphql_query, @graphql_mutation, @graphql_query_type, @graphql_mutation_type, @feature_flag_field |
| FastAPI Adapters | create_graphql_router, mount_graphql_router |
| Registries | GraphQLSchemaRegistry, get_schema_registry |
3. Monorepo & Sibling Relationships
graph TD
subgraph ClientRequests ["GraphQL Client Requests"]
CLIENT["Web / Mobile GraphQL Clients"]
end
subgraph GraphQLAdapter ["hexastack-graphql"]
SCHEMA["strawberry.Schema"]
CTX["GraphQLContext (Container + Buses)"]
ROUTER["GraphQLRouter (FastAPI integration)"]
end
subgraph ApplicationLayer ["hexastack-cqrs"]
CBUS["CommandBusPort"]
QBUS["QueryBusPort"]
end
subgraph WebServer ["hexastack-fastapi"]
FASTAPI_APP["FastAPI Application"]
end
CLIENT --> ROUTER
FASTAPI_APP --> ROUTER
ROUTER --> SCHEMA
SCHEMA --> CTX
CTX -->|dispatches commands/queries to| CBUS
CTX -->|dispatches commands/queries to| QBUS
Explicit Dependencies (Direct)
hexastack-core: DI container, configuration registry, base exceptions.hexastack-cqrs:CommandBusPortandQueryBusPortfor message dispatching.strawberry-graphql>=0.260.0: Core GraphQL engine and schema generator.
Implied / Behavioral Relationships (DI-Mediated)
- FastAPI Auto-Mounting:
GraphQLBootstrapper(order=35) discovers theFastAPIinstance created byFastApiBootstrapper(order=30) and attaches theGraphQLRouterautomatically ifauto_mount_fastapi=true. - CQRS Dispatching: Field resolvers receive
info.context.query_busandinfo.context.command_busto delegate execution into the CQRS pipeline.
Optional Integrations (Extras)
[fastapi]: Installshexastack-fastapiandfastapi>=0.141.1for HTTP routing and GraphiQL playground.
4. Installation
# Standalone install
pip install hexastack-graphql
# With FastAPI integration
pip install "hexastack-graphql[fastapi]"
# Via umbrella package
pip install "hexastack[graphql]"
5. Configuration Reference
[hexastack.graphql]
path = "/graphql" # Route prefix for GraphQL endpoint
graphiql = true # Enable interactive GraphiQL web UI
allow_queries = true
allow_mutations = true
auto_mount_fastapi = true # Auto mount onto FastAPI application on bootstrap
title = "Hexastack GraphQL API"
6. Quickstart Example
from dataclasses import dataclass
import strawberry
from strawberry.types import Info
from hexastack_core.infra.bootstrap import bootstrap
from hexastack_cqrs.domain.query import Query
from hexastack_cqrs.infra.decorators import query_handler
from hexastack_graphql.domain.context import GraphQLContext
from hexastack_graphql.infra.decorators import graphql_query_type
# 1. Define CQRS Query & Handler
@dataclass(frozen=True)
class GetItemQuery(Query):
item_id: str
@query_handler(GetItemQuery)
class GetItemHandler:
def __call__(self, qry: GetItemQuery) -> dict:
return {"id": qry.item_id, "name": f"Item {qry.item_id}"}
# 2. Define Strawberry GraphQL Type
@strawberry.type
class ItemType:
id: str
name: str
@graphql_query_type
class Query:
@strawberry.field
def item(self, info: Info[GraphQLContext, None], item_id: str) -> ItemType:
res = info.context.query_bus.dispatch(GetItemQuery(item_id=item_id))
return ItemType(id=res["id"], name=res["name"])
# 3. Bootstrap Runtime with GraphQL
runtime = bootstrap(packages_to_scan=[__name__])
schema = runtime.get("graphql_schema")
result = schema.execute_sync(
'{ item(itemId: "123") { id name } }',
context_value=GraphQLContext(
container=runtime.container, query_bus=runtime.get("query_bus")
),
)
print(result.data) # {'item': {'id': '123', 'name': 'Item 123'}}
Metadata
Release files for hexastack-graphql 0.9.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| hexastack_graphql-0.9.0.tar.gz | 12.3 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| hexastack_graphql-0.9.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 30.1 kB
Release files / hexastack_graphql-0.9.0.tar.gz
| Download URL | hexastack_graphql-0.9.0.tar.gz |
|---|---|
| Size | 12.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
6b820846caaedecd109cf966d74d1eae1b11e3014f5a1eed28247df9509413ce
|
|
BLAKE2b-256 checksum How to use checksums |
6f507cfd2c93e699f5ed3c9f96467650c7f41d5d980f2e97147a16c67b1903b1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / hexastack_graphql-0.9.0-py3-none-any.whl
| Download URL | hexastack_graphql-0.9.0-py3-none-any.whl |
|---|---|
| Size | 17.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e2659425c5ab55a9ebb11bb112e1e7ef4cca5105ea4e7209cbe4b4d8987d5327
|
|
BLAKE2b-256 checksum How to use checksums |
54c1d9775487c4506f08ccd2a85e559fde83a3f2095e24dde19ffd4a92e20d7c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Security for hexastack-graphql 0.9.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.