Context And Extensions

Chemist-managed fields rely on a small context contract rather than a framework base class.

Chemist does not create the GraphQL context object. Your application supplies that object to Strawberry, and sc.extensions() adds the request-local loader container and selection cache onto it during execution.

Required context behavior

Your GraphQL context should provide:

  • get_session(): an async context manager yielding an AsyncSession

At runtime, sc.extensions() also attaches the internal dataloader container and the field-selection cache used by Chemist-managed fields.

If you want Chemist-managed loaders to reuse one request-local session instead of opening a new AsyncSession per internal load, call:

sc.configure(use_single_loader_session=True)

That setting only changes Chemist's internal loader queries. Your own root resolvers and custom fields still use info.context.get_session() directly. Chemist drains in-flight shared-session loader work before operation teardown closes the shared session, and any late internal loads during shutdown fall back to a fresh short-lived session.

Schema integration

schema = strawberry.Schema(
    query=Query,
    extensions=sc.extensions(),
)

You can mix Chemist-managed fields with normal Strawberry resolvers on the same schema.

Execution wiring

Pass your application context into Strawberry execution explicitly:

context = build_context(session_factory, request_id="req-001")
result = await schema.execute(query, context_value=context)

For ASGI integrations, return that same context object from the framework context hook for each request.

Primary example: