ProvenPin Install

Strawberry code-first GraphQL schema tested offline: working versions (tested 2026-10-18)

Define code-first GraphQL types, queries, mutations and input types, then execute the schema in-process with context using strawberry and pytest.

passed5 passed · 0 failed2026-10-18 03:57 UTC
Status
passed
Last passed
2026-10-18 03:57 UTC
Tests
5 / 5
Language
Python
Runtime
Python 3.13.16
pinned versions3
strawberry-graphql@0.336.0pytest-asyncio@1.4.0pytest@9.1.1
run it
uv venv -q .venv && uv pip install -q --python .venv/bin/python -r requirements.txt
.venv/bin/python -m pytest -q
test environment
Python 3.13.16
linux 6.17.0-1022-azure
x64
runner: github-actions 39095370682

The code

Exactly the files that passed. Your agent can pull them with get_recipe("strawberry-graphql-schema-tests") (install), or see them on GitHub.

requirements.txt
strawberry-graphql==0.336.0
pytest-asyncio==1.4.0
pytest==9.1.1
schema.py
from dataclasses import dataclass, field

import strawberry

@strawberry.type
class User:
    id: strawberry.ID
    name: str
    email: str

    @strawberry.field
    def display_name(self) -> str:
        # exposed as "displayName" in the schema by strawberry's auto camel-casing
        return self.name.title()

@strawberry.input
class CreateUserInput:
    name: str
    email: str

@dataclass
class Store:
    users: dict[str, User] = field(default_factory=dict)
    seq: int = 0

    def add(self, name: str, email: str) -> User:
        self.seq += 1
        user = User(id=strawberry.ID(str(self.seq)), name=name, email=email)
        self.users[str(self.seq)] = user
        return user

@strawberry.type
class Query:
    @strawberry.field
    def user(self, info: strawberry.Info[Store, None], id: strawberry.ID) -> User | None:
        return info.context.users.get(str(id))

    @strawberry.field
    async def users(self, info: strawberry.Info[Store, None]) -> list[User]:
        return list(info.context.users.values())

@strawberry.type
class Mutation:
    @strawberry.mutation
    def create_user(self, info: strawberry.Info[Store, None], input: CreateUserInput) -> User:
        return info.context.add(input.name, input.email)

schema = strawberry.Schema(query=Query, mutation=Mutation)
tests/test_schema.py
import pytest

from schema import Store, schema

@pytest.fixture
def store():
    s = Store()
    s.add("Ada Lovelace", "[email protected]")
    return s

async def run(query, store, variables=None):
    return await schema.execute(query, variable_values=variables, context_value=store)

async def test_query_reads_context(store):
    result = await run('{ user(id: "1") { id name } }', store)
    assert result.errors is None
    assert result.data == {"user": {"id": "1", "name": "Ada Lovelace"}}

async def test_resolver_field_is_camel_cased(store):
    # the Python field is display_name but the schema exposes displayName
    result = await run('{ user(id: "1") { displayName } }', store)
    assert result.errors is None
    assert result.data["user"]["displayName"] == "Ada Lovelace"

async def test_mutation_with_variables(store):
    query = """
    mutation Create($input: CreateUserInput!) {
      createUser(input: $input) { id name email }
    }
    """
    result = await run(query, store, {"input": {"name": "Grace Hopper", "email": "[email protected]"}})
    assert result.errors is None
    assert result.data["createUser"]["name"] == "Grace Hopper"
    assert len(store.users) == 2

async def test_missing_input_field_is_a_validation_error(store):
    result = await run('mutation { createUser(input: {name: "x"}) { id } }', store)
    assert result.data is None
    assert result.errors is not None
    assert "email" in str(result.errors)

async def test_async_resolver_needs_async_execute(store):
    result = await run("{ users { name } }", store)
    assert result.errors is None
    assert [u["name"] for u in result.data["users"]] == ["Ada Lovelace"]
    # execute_sync does not raise here, it returns an error result instead
    sync = schema.execute_sync("{ users { name } }", context_value=store)
    assert sync.data is None
    assert "synchronously" in str(sync.errors)
pytest.ini
[pytest]
pythonpath = .
asyncio_mode = auto
filterwarnings =
    ignore:coroutine .* was never awaited:RuntimeWarning

Connect to ProvenPin

Add the free MCP server so your agent can pull this recipe and others like it. Same setup as the docs.

terminal
claude mcp add --transport http provenpin https://mcp.provenpin.com/mcp

Any other MCP client: Streamable HTTP at https://mcp.provenpin.com/mcp. No API key, no signup.