{"owner":"strawberry-graphql","repo":"strawberry","hasSkills":true,"totalSkillsCount":20,"totalTokensCount":7686,"categories":["root-instruction","claude-rule","anthropic-skill"],"hasMcp":false,"mcpConfig":null,"found":["AGENTS.md","CLAUDE.md","docs/extensions/_template.md","docs/extensions/add-validation-rules.md","docs/extensions/apollo-federation-tracing.md","docs/extensions/apollo-tracing.md","docs/extensions/datadog.md","docs/extensions/disable-introspection.md","docs/extensions/disable-validation.md","docs/extensions/input-mutation.md","docs/extensions/mask-errors.md","docs/extensions/max-aliases-limiter.md","docs/extensions/max-tokens-limiter.md","docs/extensions/opentelemetry.md","docs/extensions/parser-cache.md","docs/extensions/pydantic_error_extension.md","docs/extensions/pyinstrument.md","docs/extensions/query-depth-limiter.md","docs/extensions/sentry-tracing.md","docs/extensions/validation-cache.md"],"skills":{"AGENTS.md":"# AGENTS.md\n\nStrawberry GraphQL\n\n- Docs: https://strawberry.rocks/docs\n- Repo: https://github.com/strawberry-graphql/strawberry\n\n## Setup\n\n```shell\n$ uv sync\n$ uv run pre-commit install\n```\n\nThe default uv dependency groups include both `dev` and `integrations`, so a\nplain `uv sync` installs everything needed for local development.\n\n## Commands\n\n- **Test:** `uv run pytest`\n- **Focused test:** `uv run pytest path/to/test.py -q`\n- **Type check:** `uv run mypy --config-file mypy.ini`\n- **Lint:** `uv run ruff check .`\n- **Format:** `uv run ruff format .`\n- **Check formatting:** `uv run ruff format --check .`\n- **Run all pre-commit hooks:** `uv run pre-commit run --all-files`\n\nRun focused tests while iterating, then run the relevant broader test suite.\nThe CI test matrix is defined in `noxfile.py`; list its sessions with\n`uv run nox -t tests -l`.\n\n## Engineering Principles\n\n- Write code as if we will maintain it for years. Prefer clear, cohesive\n  implementations over the quickest local patch, solve root causes, and leave\n  the surrounding code easier to understand.\n- Think about features end to end before changing them. As relevant, trace the\n  public API through schema construction and execution, sync and async paths,\n  typing, framework integrations, error behavior, backwards compatibility, and\n  performance.\n- A feature is complete when its implementation, tests, documentation, error\n  messages, and release note tell the same coherent story. Cover important edge\n  cases and the user-visible behavior, not only the happy-path implementation.\n- Before finishing, review the diff from both a user's and a maintainer's\n  perspective: does it fit Strawberry's existing design, is its behavior\n  unsurprising, and would we be happy to support it long term?\n\n## Code Style\n\n- Ruff for linting/formatting (line length 88, Python 3.11 target)\n- Keep production code fully typed. The repository's mypy configuration is not\n  globally strict, so follow the surrounding code and avoid introducing new\n  untyped definitions.\n- Decorator-based schema: `@strawberry.type`, `@strawberry.field`,\n  `@strawberry.mutation`\n- Preserve both synchronous and asynchronous execution paths unless a feature is\n  explicitly async-only.\n\n## Structure\n\n- `strawberry/` - Core library\n  - `schema/` - Schema definition/execution\n  - `types/` - GraphQL type definitions\n  - `extensions/` - Built-in extensions\n  - `django/`, `fastapi/`, `flask/`, etc. - Framework integrations\n- `tests/` - pytest suite with integration markers (`django`, `fastapi`,\n  `pydantic`, etc.)\n\n## PR Requirements\n\n- Include `RELEASE.md` file describing changes\n- Release types: patch/minor/major\n- Add tests for behavior changes and keep affected code covered\n- Update documentation when user-facing behavior changes\n\n## Release file (RELEASE.md)\n\nRelease type is one of: `patch`, `minor`, or `major` (semver). Release notes\nshould start with `This release adds ...` or `This release fixes ...` and lead\nwith the user-visible behavior.\n\nExample:\n\n```markdown\n---\nrelease type: patch\n---\n\nThis release fixes schema printing for nullable input defaults.\n\nStrawberry now preserves explicit `None` values in printed nested input\ndefaults.\n```\n","CLAUDE.md":"@AGENTS.md\n","docs/extensions/_template.md":"---\ntitle: Extension Name\nsummary: A summary of the extension.\ntags: comma,separated,list,of,tags\n---\n\n# `ExtensionName`\n\nThis extension does ...\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions import ExtensionName\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        ExtensionName(),\n    ],\n)\n```\n\n## API reference:\n\n```python\nclass ExtensionName(an_argument=None): ...\n```\n\n#### `an_argument: Optional[str] = None`\n\nDescription of the argument.\n\n## More examples:\n\n<details>\n  <summary>Using `an_argument`</summary>\n\n```python\nimport strawberry\nfrom strawberry.extensions import ValidationCache\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        ExtensionName(an_argument=\"something\"),\n    ],\n)\n```\n\n</details>\n","docs/extensions/add-validation-rules.md":"---\ntitle: Add Validation Rules\nsummary: Add GraphQL validation rules.\ntags: validation,security\n---\n\n# `AddValidationRules`\n\nThis extension allows you add custom validation rules.\n\nSee\n[graphql.validation.rules.custom](https://github.com/graphql-python/graphql-core/tree/main/src/graphql/validation/rules/custom)\nfor some custom rules that can be added from GraphQl-core.\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions import AddValidationRules\nfrom graphql import ValidationRule\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nclass MyCustomRule(ValidationRule): ...\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        AddValidationRules(MyCustomRule),\n    ],\n)\n```\n\n## API reference:\n\n```python\nclass AddValidationRules(validation_rules): ...\n```\n\n#### `validation_rules: List[Type[ASTValidationRule]]`\n\nList of GraphQL validation rules.\n\n## More examples:\n\n<details>\n  <summary>Adding a custom rule</summary>\n\n```python\nimport strawberry\nfrom strawberry.extensions import AddValidationRules\nfrom graphql import ValidationRule\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nclass CustomRule(ValidationRule):\n    def enter_field(self, node, *args) -> None:\n        if node.name.value == \"example\":\n            self.report_error(GraphQLError(\"Can't query field 'example'\"))\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        AddValidationRules([CustomRule]),\n    ],\n)\n\nresult = schema.execute_sync(\"{ example }\")\n\nassert str(result.errors[0]) == \"Can't query field 'example'\"\n```\n\n</details>\n\n<details>\n  <summary>Adding the `NoDeprecatedCustomRule` from GraphQL-core</summary>\n\n```python\nimport strawberry\nfrom strawberry.extensions import AddValidationRules\nfrom graphql.validation import NoDeprecatedCustomRule\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        AddValidationRules([NoDeprecatedCustomRule]),\n    ],\n)\n```\n\n</details>\n\n<details>\n  <summary>Adding the `NoSchemaIntrospectionCustomRule` from GraphQL-core</summary>\n\n```python\nimport strawberry\nfrom strawberry.extensions import AddValidationRules\nfrom graphql.validation import NoSchemaIntrospectionCustomRule\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        AddValidationRules([NoSchemaIntrospectionCustomRule]),\n    ],\n)\n```\n\n</details>\n","docs/extensions/apollo-federation-tracing.md":"---\ntitle: Apollo Federation Tracing\nsummary: Add Apollo Federation inline tracing (FTV1) to your GraphQL server.\ntags: tracing,federation\n---\n\n# `ApolloFederationTracingExtension`\n\nThis extension adds support for\n[Apollo Federation inline tracing (FTV1)](https://www.apollographql.com/docs/federation/).\nWhen a request includes the `apollo-federation-include-trace: ftv1` header, the\nextension records per-resolver timing and includes the trace in the response as\na base64-encoded protobuf under `extensions.ftv1`.\n\n<Warning>\n\nAny client can send the `apollo-federation-include-trace: ftv1` header unless\nyou restrict it. Tracing payloads expose resolver timing details, so make sure\nonly a trusted Apollo Gateway (or other internal traffic) can request traces —\nfor example by enforcing authentication, network policy, or stripping the header\nfrom public requests at the edge.\n\n</Warning>\n\n<Note>\n\nMake sure you have `protobuf` installed before using this extension.\n\n```shell\npip install 'strawberry-graphql[apollo-federation]'\n```\n\n</Note>\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions.tracing import ApolloFederationTracingExtension\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        ApolloFederationTracingExtension,\n    ],\n)\n```\n\n<Note>\n\nIf you are not running in an Async context then you'll need to use the sync\nversion:\n\n```python\nimport strawberry\nfrom strawberry.extensions.tracing import ApolloFederationTracingExtensionSync\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        ApolloFederationTracingExtensionSync,\n    ],\n)\n```\n\n</Note>\n\n## API reference:\n\n_No arguments_\n","docs/extensions/apollo-tracing.md":"---\ntitle: Apollo Tracing\nsummary: Add Apollo tracing to your GraphQL server.\ntags: tracing\n---\n\n# `ApolloTracingExtension`\n\nThis extension adds\n[tracing information](https://github.com/apollographql/apollo-tracing) to your\nresponse for [Apollo Engine](https://www.apollographql.com/platform/).\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions.tracing import ApolloTracingExtension\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        ApolloTracingExtension,\n    ],\n)\n```\n\n<Note>\n\nIf you are not running in an Async context then you'll need to use the sync\nversion:\n\n```python\nimport strawberry\nfrom strawberry.extensions.tracing import ApolloTracingExtensionSync\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        ApolloTracingExtensionSync,\n    ],\n)\n```\n\n</Note>\n\n## API reference:\n\n_No arguments_\n","docs/extensions/datadog.md":"---\ntitle: Datadog\nsummary: Add Datadog tracing to your GraphQL server.\ntags: tracing\n---\n\n# `DatadogExtension`\n\nThis extension adds support for tracing with Datadog.\n\n<Note>\n\nMake sure you have `ddtrace` installed before using this extension.\n\n```shell\npip install ddtrace\n```\n\n</Note>\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions.tracing import DatadogTracingExtension\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        DatadogTracingExtension,\n    ],\n)\n```\n\n<Note>\n\nIf you are not running in an Async context then you'll need to use the sync\nversion:\n\n```python\nimport strawberry\nfrom strawberry.extensions.tracing import DatadogTracingExtensionSync\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        DatadogTracingExtensionSync,\n    ],\n)\n```\n\n</Note>\n\n## API reference:\n\n_No arguments_\n\n## Extending the extension\n\n### Overriding the `create_span` method\n\nYou can customize any of the spans or add tags to them by overriding the\n`create_span` method.\n\nExample:\n\n```python\nfrom ddtrace import Span\n\nfrom strawberry.extensions import LifecycleStep\nfrom strawberry.extensions.tracing import DatadogTracingExtension\n\n\nclass DataDogExtension(DatadogTracingExtension):\n    def create_span(\n        self,\n        lifecycle_step: LifecycleStep,\n        name: str,\n        **kwargs,\n    ) -> Span:\n        span = super().create_span(lifecycle_step, name, **kwargs)\n        if lifecycle_step == LifecycleStep.OPERATION:\n            span.set_tag(\"graphql.query\", self.execution_context.query)\n        return span\n```\n","docs/extensions/disable-introspection.md":"---\ntitle: Disable Introspection\nsummary: Disable standard GraphQL introspection queries.\ntags: security,validation\n---\n\n# `DisableIntrospection`\n\nThe `DisableIntrospection` extension disables standard GraphQL introspection\nqueries for the schema. It blocks fields such as `__schema` and `__type`.\n\nThis can be useful to prevent clients from discovering unreleased or internal\nfeatures of the API through GraphQL introspection.\n\n<Warning>\n\n`DisableIntrospection` does not block non-introspection fields that may expose\nschema information. For example, Apollo Federation schemas expose `_service` and\nits `sdl` field so gateways and routers can compose federated services. If you\nuse `strawberry.federation.Schema`, protect federated endpoints from untrusted\nclients with your own authentication, authorization, or network controls.\n\n</Warning>\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions import DisableIntrospection\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        DisableIntrospection(),\n    ],\n)\n```\n\n## API reference:\n\n_No arguments_\n\n## Example query:\n\nRunning any query including the introspection field `__schema` will result in an\nerror. Consider the following query, for example:\n\n```graphql\nquery {\n  __schema {\n    __typename\n  }\n}\n```\n\nRunning it against the schema with the `DisableIntrospection` extension enabled\nwill result in an error response indicating that introspection has been\ndisabled:\n\n```json\n{\n  \"data\": null,\n  \"errors\": [\n    {\n      \"message\": \"GraphQL introspection has been disabled, but the requested query contained the field '__schema'.\",\n      \"locations\": [\n        {\n          \"line\": 2,\n          \"column\": 3\n        }\n      ]\n    }\n  ]\n}\n```\n","docs/extensions/disable-validation.md":"---\ntitle: Disable Validation\nsummary: Disable all query validation.\ntags: performance,validation\n---\n\n# `DisableValidation`\n\nThis extensions disables all query validation. This can be useful to improve\nperformance in some specific cases, for example when dealing with internal APIs\nwhere queries can be trusted.\n\n<Warning>\n\nOnly do this if you know what you are doing! Disabling validation breaks the\nsafety of having typed schema. If you are trying to improve performance you\nmight want to consider using the [ValidationCache](./validation-cache) instead.\n\n</Warning>\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions import DisableValidation\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        DisableValidation(),\n    ],\n)\n```\n\n## API reference:\n\n_No arguments_\n","docs/extensions/input-mutation.md":"---\ntitle: Input Mutation Extension\nsummary: Automatically create Input types for mutations\ntags: QoL\n---\n\n# `InputMutationExtension`\n\nThe pattern of defining a mutation that receives a single\n[input type](../types/input-types.md) argument called `input` is a common\npractice in GraphQL. It helps to keep the mutation signatures clean and makes it\neasier to manage complex mutations with multiple arguments.\n\nThe `InputMutationExtension` is a Strawberry field extension that allows you to\ndefine a mutation with multiple arguments without having to manually create an\ninput type for it. Instead, it generates an input type based on the arguments of\nthe mutation resolver.\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.field_extensions import InputMutationExtension\n\n\n@strawberry.type\nclass User:\n    username: str\n\n\n@strawberry.type\nclass Query:\n    hello: str\n\n\n@strawberry.type\nclass Mutation:\n    @strawberry.mutation(extensions=[InputMutationExtension()])\n    def register_user(\n        self,\n        username: str,\n        password: str,\n    ) -> User:\n        user = User(username=username)\n        # maybe persist the user in a database\n        return user\n\n\nschema = strawberry.Schema(query=Query, mutation=Mutation)\n```\n\nThe Strawberry schema above and the usage of the `InputMutationExtension` will\nresult in the following GraphQL schema:\n\n```graphql\ntype User {\n  username: String!\n}\n\ninput RegisterUserInput {\n  username: String!\n  password: String!\n}\n\ntype Mutation {\n  registerUser(input: RegisterUserInput!): User!\n}\n\ntype Query {\n  hello: String!\n}\n```\n\n## API reference:\n\n_No arguments_\n","docs/extensions/mask-errors.md":"---\ntitle: Mask Errors\nsummary: Hide error messages from the client.\ntags: security\n---\n\n# `MaskErrors`\n\nThis extension hides error messages from the client to prevent exposing\nsensitive details. By default it masks all errors raised in any field resolver.\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions import MaskErrors\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hidden_error(self) -> str:\n        raise KeyError(\"This error will not be visible\")\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        MaskErrors(),\n    ],\n)\n```\n\n## API reference:\n\n```python\nclass MaskErrors(\n    should_mask_error=default_should_mask_error, error_message=\"Unexpected error.\"\n): ...\n```\n\n#### `should_mask_error: Callable[[GraphQLError], bool] = default_should_mask_error`\n\nPredicate function to check if a GraphQLError should be masked or not. Use the\n`original_error` attribute to access the original error that was raised in the\nresolver.\n\n<Note>\n\nThe `default_should_mask_error` function always returns `True`.\n\n</Note>\n\n#### `error_message: str = \"Unexpected error.\"`\n\nThe error message to display to the client when there is an error.\n\n## More examples:\n\n<details>\n  <summary>Hide some exceptions</summary>\n\n```python\nimport strawberry\nfrom strawberry.extensions import MaskErrors\nfrom graphql.error import GraphQLError\n\n\nclass VisibleError(Exception):\n    pass\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def visible_error(self) -> str:\n        raise VisibleError(\"This error will be visible\")\n\n\ndef should_mask_error(error: GraphQLError) -> bool:\n    original_error = error.original_error\n    if original_error and isinstance(original_error, VisibleError):\n        return False\n\n    return True\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        MaskErrors(should_mask_error=should_mask_error),\n    ],\n)\n```\n\n</details>\n\n<details>\n  <summary>Change error message</summary>\n\n```python\nimport strawberry\nfrom strawberry.extensions import MaskErrors\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hidden_error(self) -> str:\n        raise KeyError(\"This error will not be visible\")\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        MaskErrors(error_message=\"Oh no! An error occured. Very sorry about that.\"),\n    ],\n)\n```\n\n</details>\n","docs/extensions/max-aliases-limiter.md":"---\ntitle: Max Aliases Limiter\nsummary:\n  Add a validator to limit the maximum number of aliases in a GraphQL document.\ntags: security\n---\n\n# `MaxAliasesLimiter`\n\nThis extension adds a validator to limit the maximum number of aliases in a\nGraphQL document.\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions import MaxAliasesLimiter\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        MaxAliasesLimiter(max_alias_count=15),\n    ],\n)\n```\n\n## API reference:\n\n```python\nclass MaxAliasesLimiter(max_alias_count): ...\n```\n\n#### `max_alias_count: int`\n\nThe maximum allowed number of aliases in a GraphQL document.\n","docs/extensions/max-tokens-limiter.md":"---\ntitle: Max Tokens Limiter\nsummary:\n  Add a validator to limit the maximum number of tokens in a GraphQL document.\ntags: security\n---\n\n# `MaxTokensLimiter`\n\nThis extension adds a validator to limit the maximum number of tokens in a\nGraphQL document sent to the server.\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions import MaxTokensLimiter\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        MaxTokensLimiter(max_token_count=1000),\n    ],\n)\n```\n\nWith the above configuration, if a client sends a query with more than 1000\ntokens, the server will respond with an error message.\n\n## API reference:\n\n```python\nclass MaxTokensLimiter(max_token_count): ...\n```\n\n#### `max_token_count: int`\n\nThe maximum allowed number of tokens in a GraphQL document.\n\nThe following things are counted as tokens:\n\n- various brackets: \"{\", \"}\", \"(\", \")\"\n- colon :\n- words\n\nNot counted:\n\n- quotes\n","docs/extensions/opentelemetry.md":"---\ntitle: Open Telemetry\nsummary: Add Open Telemetry tracing to your GraphQL server.\ntags: tracing\n---\n\n# `OpenTelemetryExtension`\n\nThis extension adds tracing information that is compatible with\n[Open Telemetry](https://opentelemetry.io/).\n\n<Note>\n\nThis extension requires additional requirements:\n\n```shell\npip install 'strawberry-graphql[opentelemetry]'\n```\n\n</Note>\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions.tracing import OpenTelemetryExtension\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        OpenTelemetryExtension,\n    ],\n)\n```\n\n<Note>\n\nIf you are not running in an Async context then you'll need to use the sync\nversion:\n\n```python\nimport strawberry\nfrom strawberry.extensions.tracing import OpenTelemetryExtensionSync\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        OpenTelemetryExtensionSync,\n    ],\n)\n```\n\n</Note>\n\n## API reference:\n\n```python\nclass OpenTelemetryExtension(arg_filter=None): ...\n```\n\n#### `arg_filter: Optional[ArgFilter]`\n\nA function to filter certain field arguments from being included in the tracing\ndata.\n\n```python\nArgFilter = Callable[[Dict[str, Any], GraphQLResolveInfo], Dict[str, Any]]\n```\n\n## More examples:\n\n<details>\n  <summary>Using `arg_filter`</summary>\n\n```python\nimport strawberry\nfrom strawberry.extensions.tracing import OpenTelemetryExtensionSync\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\ndef arg_filter(kwargs, info):\n    filtered_kwargs = {}\n    for name, value in kwargs.items():\n        # Never include any arguments called \"password\"\n        if name == \"password\":\n            continue\n        filtered_kwargs[name] = value\n\n    return filtered_kwargs\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        OpenTelemetryExtensionSync(\n            arg_filter=arg_filter,\n        ),\n    ],\n)\n```\n\n</details>\n\n<details>\n  <summary>Using `tracer_provider`</summary>\n\n```python\nimport strawberry\nfrom opentelemetry.trace import TracerProvider\nfrom strawberry.extensions.tracing import OpenTelemetryExtension\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nclass MyTracerProvider(TracerProvider):\n    def get_tracer(self, name, version=None, schema_url=None):\n        return super().get_tracer(name, version, schema_url)\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        OpenTelemetryExtension(\n            tracer_provider=MyTracerProvider(),\n        ),\n    ],\n)\n```\n\n</details>\n","docs/extensions/parser-cache.md":"---\ntitle: Parser Cache\nsummary: Add in memory caching to the parsing step of query execution.\ntags: performance,caching,parsing\n---\n\n# `ParserCache`\n\nThis extension adds LRU caching to the parsing step of query execution to\nimprove performance by caching the parsed result in memory.\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions import ParserCache\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        ParserCache(),\n    ],\n)\n```\n\n## API reference:\n\n```python\nclass ParserCache(maxsize=128): ...\n```\n\n#### `maxsize: Optional[int] = 128`\n\nSet the maxsize of the cache. By default the cache is bounded to 128 entries,\nwith the least recently used entries evicted first. Pass an explicit\n`maxsize=None` to let the cache grow without bound; only do this when the set of\ndistinct query texts reaching the server is trusted and bounded, as an unbounded\ncache lets clients grow the server's memory indefinitely by sending unique query\ntexts.\n\nMore info: https://docs.python.org/3/library/functools.html#functools.lru_cache\n\n## More examples:\n\n<details>\n  <summary>Using maxsize</summary>\n\n```python\nimport strawberry\nfrom strawberry.extensions import ParserCache\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        ParserCache(maxsize=100),\n    ],\n)\n```\n\n</details>\n","docs/extensions/pydantic_error_extension.md":"---\ntitle: Pydantic Error Extension\nsummary:\n  Formats Pydantic validation errors into structured GraphQL error extensions.\ntags: pydantic,validation,errors,graphql,extensions\n---\n\n# `PydanticErrorExtension`\n\nThis extension detects Pydantic validation errors during GraphQL execution and\nformats them into structured `validation_errors` under the `extensions` field of\nGraphQL errors.\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions import PydanticErrorExtension\n\n\n@strawberry.type\nclass Mutation:\n    @strawberry.mutation\n    def create_user(self, email: str) -> str:\n        return email\n\n\nschema = strawberry.Schema(\n    mutation=Mutation,\n    extensions=[\n        PydanticErrorExtension(),\n    ],\n)\n```\n\n## API reference:\n\n```python\nclass PydanticErrorExtension: ...\n```\n\nThis extension does not require any arguments.\n\n## More examples:\n\n<details>\n  <summary>Example validation error output</summary>\n\n```json\n{\n  \"errors\": [\n    {\n      \"message\": \"Validation error\",\n      \"extensions\": {\n        \"validation_errors\": [\n          {\n            \"field\": \"email\",\n            \"message\": \"value is not a valid email\"\n          }\n        ]\n      }\n    }\n  ]\n}\n```\n\n</details>\n","docs/extensions/pyinstrument.md":"---\ntitle: PyInstrument\nsummary: Easily Instrument your Schema\ntags: instrumentation,profiling\n---\n\n# `PyInstrument`\n\nThis extension allows you to instrument your schema and inspect the call stack.\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions import pyinstrument\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        pyinstrument.PyInstrument(report_path=\"pyinstrument.html\"),\n    ],\n)\n```\n\n## API reference:\n\n```python\nclass PyInstrument(report_Path=Path(\"pyinstrument.html\")): ...\n```\n\n#### `report_path: Path = Path(\"pyinstrument.html\")`\n\nPath to write the HTML PyInstrument report\n","docs/extensions/query-depth-limiter.md":"---\ntitle: Query Depth Limiter\nsummary: Add a validator to limit the query depth of GraphQL operations.\ntags: security\n---\n\n# `QueryDepthLimiter`\n\nThis extension adds a validator to limit the query depth of GraphQL operations.\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions import QueryDepthLimiter\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        QueryDepthLimiter(max_depth=10),\n    ],\n)\n```\n\n## API reference:\n\n```python\nclass QueryDepthLimiter(max_depth, callback=None, should_ignore=None): ...\n```\n\n#### `max_depth: int`\n\nThe maximum allowed depth for any operation in a GraphQL document.\n\n#### `callback: Optional[Callable[[Dict[str, int]], None]`\n\nCalled each time validation runs. Receives a dictionary which is a map of the\ndepths for each operation.\n\n#### `should_ignore: Optional[Callable[[IgnoreContext], bool]]`\n\nCalled at each field to determine whether the field should be ignored or not.\nMust be implemented by the user and returns `True` if the field should be\nignored and `False` otherwise.\n\nThe `IgnoreContext` class has the following attributes:\n\n- `field_name` of type `str`: the name of the field to be compared against\n- `field_args` of type\n  `strawberry.extensions.query_depth_limiter.FieldArgumentsType`: the arguments\n  of the field to be compared against\n- `query` of type `graphql.language.Node`: the query string\n- `context` of type `graphql.validation.ValidationContext`: the context passed\n  to the query\n\nThis argument is injected, regardless of name, by the `QueryDepthLimiter` class\nand should not be passed by the user.\n\nInstead, the user should write business logic to determine whether a field\nshould be ignored or not by the attributes of the `IgnoreContext` class.\n\n## Example with field_name:\n\n```python\nimport strawberry\nfrom strawberry.extensions import QueryDepthLimiter, IgnoreContext\n\n\n@strawberry.type\nclass Book:\n    title: str\n    author: \"User\"\n\n\n@strawberry.type\nclass User:\n    favourite_books: list[Book]\n    published_books: list[Book]\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def book(self) -> Book:\n        return Book(\n            title=\"The Hitchhiker's Guide to the Strawberry Fields\",\n            author=User(favourite_books=[], published_books=[]),\n        )\n\n    @strawberry.field\n    def user(self) -> User:\n        return User(favourite_books=[], published_books=[])\n\n\ndef should_ignore(ignore: IgnoreContext):\n    return ignore.field_name == \"user\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        QueryDepthLimiter(max_depth=2, should_ignore=should_ignore),\n    ],\n)\n\n# This query fails\nschema.execute(\"\"\"\n    query TooDeep {\n        book {\n            author {\n                publishedBooks {\n                    title\n                }\n            }\n        }\n    }\n    \"\"\")\n\n# This query succeeds because the `user` field is ignored\nschema.execute(\"\"\"\n    query NotTooDeep {\n        user {\n            favouriteBooks {\n                author {\n                    publishedBooks {\n                        title\n                    }\n                }\n            }\n        }\n    }\n    \"\"\")\n```\n\n## Example with field_args:\n\n```python\nimport strawberry\nfrom strawberry.extensions import QueryDepthLimiter, IgnoreContext\n\n\n@strawberry.type\nclass Book:\n    title: str\n    author: \"User\"\n\n\n@strawberry.type\nclass User:\n    name: str | None\n    favourite_books: list[Book]\n    published_books: list[Book]\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def book(self) -> Book:\n        return Book(\n            title=\"The Hitchhiker's Guide to the Strawberry Fields\",\n            author=User(favourite_books=[], published_books=[]),\n        )\n\n    @strawberry.field\n    def user(self, name: str | None = None) -> User:\n        return User(name=name, favourite_books=[], published_books=[])\n\n\ndef should_ignore(ignore: IgnoreContext):\n    return ignore.field_args.get(\"name\") == \"matt\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        QueryDepthLimiter(max_depth=2, should_ignore=should_ignore),\n    ],\n)\n\n# This query fails\nschema.execute(\"\"\"\n    query TooDeep {\n        book {\n            author {\n                publishedBooks {\n                    title\n                }\n            }\n        }\n    }\n    \"\"\")\n\n# This query succeeds because the `user` field is ignored\nschema.execute(\"\"\"\n    query NotTooDeep {\n        user(name:\"matt\") {\n            favouriteBooks {\n                author {\n                    publishedBooks {\n                        title\n                    }\n                }\n            }\n        }\n    }\n    \"\"\")\n```\n","docs/extensions/sentry-tracing.md":"---\ntitle: Sentry Tracing\nsummary: Add Sentry tracing to your GraphQL server.\ntags: tracing\n---\n\n# `SentryTracingExtension`\n\n<Warning>\n\nAs of Sentry 1.32.0, Strawberry is officially supported by the Sentry SDK.\nTherefore, Strawberry's `SentryTracingExtension` has been deprecated in version\n0.210.0 and finally removed with Strawberry 0.249.0 in favor of the official\nSentry SDK integration.\n\nFor more details, please refer to the\n[documentation for the official Sentry Strawberry integration](https://docs.sentry.io/platforms/python/integrations/strawberry/).\n\n</Warning>\n\n## Filtering input coercion errors\n\nThe official Sentry integration captures all errors returned in a GraphQL\nresponse. If invalid client input should not be reported, use Sentry's\n`before_send` callback to filter `StrawberryInputCoercionError`:\n\n```python\nfrom typing import Any\n\nimport sentry_sdk\n\nfrom strawberry.exceptions import StrawberryInputCoercionError\n\n\ndef before_send(event: dict[str, Any], hint: dict[str, Any]) -> dict[str, Any] | None:\n    exc_info = hint.get(\"exc_info\")\n    error = exc_info[1] if exc_info else None\n\n    if isinstance(error, StrawberryInputCoercionError) or isinstance(\n        getattr(error, \"original_error\", None), StrawberryInputCoercionError\n    ):\n        return None\n\n    return event\n\n\nsentry_sdk.init(before_send=before_send)\n```\n\nChecking `original_error` is necessary because graphql-core wraps scalar errors\nraised while coercing variables in another `GraphQLError`. For this reason,\nSentry's `ignore_errors` option alone does not filter every input coercion\nerror.\n","docs/extensions/validation-cache.md":"---\ntitle: Validation Cache\nsummary: Add in memory caching to the validation step of query execution.\ntags: performance,caching,validation\n---\n\n# `ValidationCache`\n\nThis extension adds LRU caching to the validation step of query execution to\nimprove performance by caching the validation errors in memory.\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions import ValidationCache\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        ValidationCache(),\n    ],\n)\n```\n\n## API reference:\n\n```python\nclass ValidationCache(maxsize=128): ...\n```\n\n#### `maxsize: Optional[int] = 128`\n\nSet the maxsize of the cache. By default the cache is bounded to 128 entries,\nwith the least recently used entries evicted first. Pass an explicit\n`maxsize=None` to let the cache grow without bound; only do this when the set of\ndistinct query texts reaching the server is trusted and bounded, as an unbounded\ncache lets clients grow the server's memory indefinitely by sending unique query\ntexts.\n\nMore info: https://docs.python.org/3/library/functools.html#functools.lru_cache\n\n## More examples:\n\n<details>\n  <summary>Using maxsize</summary>\n\n```python\nimport strawberry\nfrom strawberry.extensions import ValidationCache\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        ValidationCache(maxsize=100),\n    ],\n)\n```\n\n</details>\n"},"files":{"AGENTS.md":"# AGENTS.md\n\nStrawberry GraphQL\n\n- Docs: https://strawberry.rocks/docs\n- Repo: https://github.com/strawberry-graphql/strawberry\n\n## Setup\n\n```shell\n$ uv sync\n$ uv run pre-commit install\n```\n\nThe default uv dependency groups include both `dev` and `integrations`, so a\nplain `uv sync` installs everything needed for local development.\n\n## Commands\n\n- **Test:** `uv run pytest`\n- **Focused test:** `uv run pytest path/to/test.py -q`\n- **Type check:** `uv run mypy --config-file mypy.ini`\n- **Lint:** `uv run ruff check .`\n- **Format:** `uv run ruff format .`\n- **Check formatting:** `uv run ruff format --check .`\n- **Run all pre-commit hooks:** `uv run pre-commit run --all-files`\n\nRun focused tests while iterating, then run the relevant broader test suite.\nThe CI test matrix is defined in `noxfile.py`; list its sessions with\n`uv run nox -t tests -l`.\n\n## Engineering Principles\n\n- Write code as if we will maintain it for years. Prefer clear, cohesive\n  implementations over the quickest local patch, solve root causes, and leave\n  the surrounding code easier to understand.\n- Think about features end to end before changing them. As relevant, trace the\n  public API through schema construction and execution, sync and async paths,\n  typing, framework integrations, error behavior, backwards compatibility, and\n  performance.\n- A feature is complete when its implementation, tests, documentation, error\n  messages, and release note tell the same coherent story. Cover important edge\n  cases and the user-visible behavior, not only the happy-path implementation.\n- Before finishing, review the diff from both a user's and a maintainer's\n  perspective: does it fit Strawberry's existing design, is its behavior\n  unsurprising, and would we be happy to support it long term?\n\n## Code Style\n\n- Ruff for linting/formatting (line length 88, Python 3.11 target)\n- Keep production code fully typed. The repository's mypy configuration is not\n  globally strict, so follow the surrounding code and avoid introducing new\n  untyped definitions.\n- Decorator-based schema: `@strawberry.type`, `@strawberry.field`,\n  `@strawberry.mutation`\n- Preserve both synchronous and asynchronous execution paths unless a feature is\n  explicitly async-only.\n\n## Structure\n\n- `strawberry/` - Core library\n  - `schema/` - Schema definition/execution\n  - `types/` - GraphQL type definitions\n  - `extensions/` - Built-in extensions\n  - `django/`, `fastapi/`, `flask/`, etc. - Framework integrations\n- `tests/` - pytest suite with integration markers (`django`, `fastapi`,\n  `pydantic`, etc.)\n\n## PR Requirements\n\n- Include `RELEASE.md` file describing changes\n- Release types: patch/minor/major\n- Add tests for behavior changes and keep affected code covered\n- Update documentation when user-facing behavior changes\n\n## Release file (RELEASE.md)\n\nRelease type is one of: `patch`, `minor`, or `major` (semver). Release notes\nshould start with `This release adds ...` or `This release fixes ...` and lead\nwith the user-visible behavior.\n\nExample:\n\n```markdown\n---\nrelease type: patch\n---\n\nThis release fixes schema printing for nullable input defaults.\n\nStrawberry now preserves explicit `None` values in printed nested input\ndefaults.\n```\n","CLAUDE.md":"@AGENTS.md\n","docs/extensions/_template.md":"---\ntitle: Extension Name\nsummary: A summary of the extension.\ntags: comma,separated,list,of,tags\n---\n\n# `ExtensionName`\n\nThis extension does ...\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions import ExtensionName\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        ExtensionName(),\n    ],\n)\n```\n\n## API reference:\n\n```python\nclass ExtensionName(an_argument=None): ...\n```\n\n#### `an_argument: Optional[str] = None`\n\nDescription of the argument.\n\n## More examples:\n\n<details>\n  <summary>Using `an_argument`</summary>\n\n```python\nimport strawberry\nfrom strawberry.extensions import ValidationCache\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        ExtensionName(an_argument=\"something\"),\n    ],\n)\n```\n\n</details>\n","docs/extensions/add-validation-rules.md":"---\ntitle: Add Validation Rules\nsummary: Add GraphQL validation rules.\ntags: validation,security\n---\n\n# `AddValidationRules`\n\nThis extension allows you add custom validation rules.\n\nSee\n[graphql.validation.rules.custom](https://github.com/graphql-python/graphql-core/tree/main/src/graphql/validation/rules/custom)\nfor some custom rules that can be added from GraphQl-core.\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions import AddValidationRules\nfrom graphql import ValidationRule\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nclass MyCustomRule(ValidationRule): ...\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        AddValidationRules(MyCustomRule),\n    ],\n)\n```\n\n## API reference:\n\n```python\nclass AddValidationRules(validation_rules): ...\n```\n\n#### `validation_rules: List[Type[ASTValidationRule]]`\n\nList of GraphQL validation rules.\n\n## More examples:\n\n<details>\n  <summary>Adding a custom rule</summary>\n\n```python\nimport strawberry\nfrom strawberry.extensions import AddValidationRules\nfrom graphql import ValidationRule\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nclass CustomRule(ValidationRule):\n    def enter_field(self, node, *args) -> None:\n        if node.name.value == \"example\":\n            self.report_error(GraphQLError(\"Can't query field 'example'\"))\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        AddValidationRules([CustomRule]),\n    ],\n)\n\nresult = schema.execute_sync(\"{ example }\")\n\nassert str(result.errors[0]) == \"Can't query field 'example'\"\n```\n\n</details>\n\n<details>\n  <summary>Adding the `NoDeprecatedCustomRule` from GraphQL-core</summary>\n\n```python\nimport strawberry\nfrom strawberry.extensions import AddValidationRules\nfrom graphql.validation import NoDeprecatedCustomRule\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        AddValidationRules([NoDeprecatedCustomRule]),\n    ],\n)\n```\n\n</details>\n\n<details>\n  <summary>Adding the `NoSchemaIntrospectionCustomRule` from GraphQL-core</summary>\n\n```python\nimport strawberry\nfrom strawberry.extensions import AddValidationRules\nfrom graphql.validation import NoSchemaIntrospectionCustomRule\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        AddValidationRules([NoSchemaIntrospectionCustomRule]),\n    ],\n)\n```\n\n</details>\n","docs/extensions/apollo-federation-tracing.md":"---\ntitle: Apollo Federation Tracing\nsummary: Add Apollo Federation inline tracing (FTV1) to your GraphQL server.\ntags: tracing,federation\n---\n\n# `ApolloFederationTracingExtension`\n\nThis extension adds support for\n[Apollo Federation inline tracing (FTV1)](https://www.apollographql.com/docs/federation/).\nWhen a request includes the `apollo-federation-include-trace: ftv1` header, the\nextension records per-resolver timing and includes the trace in the response as\na base64-encoded protobuf under `extensions.ftv1`.\n\n<Warning>\n\nAny client can send the `apollo-federation-include-trace: ftv1` header unless\nyou restrict it. Tracing payloads expose resolver timing details, so make sure\nonly a trusted Apollo Gateway (or other internal traffic) can request traces —\nfor example by enforcing authentication, network policy, or stripping the header\nfrom public requests at the edge.\n\n</Warning>\n\n<Note>\n\nMake sure you have `protobuf` installed before using this extension.\n\n```shell\npip install 'strawberry-graphql[apollo-federation]'\n```\n\n</Note>\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions.tracing import ApolloFederationTracingExtension\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        ApolloFederationTracingExtension,\n    ],\n)\n```\n\n<Note>\n\nIf you are not running in an Async context then you'll need to use the sync\nversion:\n\n```python\nimport strawberry\nfrom strawberry.extensions.tracing import ApolloFederationTracingExtensionSync\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        ApolloFederationTracingExtensionSync,\n    ],\n)\n```\n\n</Note>\n\n## API reference:\n\n_No arguments_\n","docs/extensions/apollo-tracing.md":"---\ntitle: Apollo Tracing\nsummary: Add Apollo tracing to your GraphQL server.\ntags: tracing\n---\n\n# `ApolloTracingExtension`\n\nThis extension adds\n[tracing information](https://github.com/apollographql/apollo-tracing) to your\nresponse for [Apollo Engine](https://www.apollographql.com/platform/).\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions.tracing import ApolloTracingExtension\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        ApolloTracingExtension,\n    ],\n)\n```\n\n<Note>\n\nIf you are not running in an Async context then you'll need to use the sync\nversion:\n\n```python\nimport strawberry\nfrom strawberry.extensions.tracing import ApolloTracingExtensionSync\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        ApolloTracingExtensionSync,\n    ],\n)\n```\n\n</Note>\n\n## API reference:\n\n_No arguments_\n","docs/extensions/datadog.md":"---\ntitle: Datadog\nsummary: Add Datadog tracing to your GraphQL server.\ntags: tracing\n---\n\n# `DatadogExtension`\n\nThis extension adds support for tracing with Datadog.\n\n<Note>\n\nMake sure you have `ddtrace` installed before using this extension.\n\n```shell\npip install ddtrace\n```\n\n</Note>\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions.tracing import DatadogTracingExtension\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        DatadogTracingExtension,\n    ],\n)\n```\n\n<Note>\n\nIf you are not running in an Async context then you'll need to use the sync\nversion:\n\n```python\nimport strawberry\nfrom strawberry.extensions.tracing import DatadogTracingExtensionSync\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        DatadogTracingExtensionSync,\n    ],\n)\n```\n\n</Note>\n\n## API reference:\n\n_No arguments_\n\n## Extending the extension\n\n### Overriding the `create_span` method\n\nYou can customize any of the spans or add tags to them by overriding the\n`create_span` method.\n\nExample:\n\n```python\nfrom ddtrace import Span\n\nfrom strawberry.extensions import LifecycleStep\nfrom strawberry.extensions.tracing import DatadogTracingExtension\n\n\nclass DataDogExtension(DatadogTracingExtension):\n    def create_span(\n        self,\n        lifecycle_step: LifecycleStep,\n        name: str,\n        **kwargs,\n    ) -> Span:\n        span = super().create_span(lifecycle_step, name, **kwargs)\n        if lifecycle_step == LifecycleStep.OPERATION:\n            span.set_tag(\"graphql.query\", self.execution_context.query)\n        return span\n```\n","docs/extensions/disable-introspection.md":"---\ntitle: Disable Introspection\nsummary: Disable standard GraphQL introspection queries.\ntags: security,validation\n---\n\n# `DisableIntrospection`\n\nThe `DisableIntrospection` extension disables standard GraphQL introspection\nqueries for the schema. It blocks fields such as `__schema` and `__type`.\n\nThis can be useful to prevent clients from discovering unreleased or internal\nfeatures of the API through GraphQL introspection.\n\n<Warning>\n\n`DisableIntrospection` does not block non-introspection fields that may expose\nschema information. For example, Apollo Federation schemas expose `_service` and\nits `sdl` field so gateways and routers can compose federated services. If you\nuse `strawberry.federation.Schema`, protect federated endpoints from untrusted\nclients with your own authentication, authorization, or network controls.\n\n</Warning>\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions import DisableIntrospection\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        DisableIntrospection(),\n    ],\n)\n```\n\n## API reference:\n\n_No arguments_\n\n## Example query:\n\nRunning any query including the introspection field `__schema` will result in an\nerror. Consider the following query, for example:\n\n```graphql\nquery {\n  __schema {\n    __typename\n  }\n}\n```\n\nRunning it against the schema with the `DisableIntrospection` extension enabled\nwill result in an error response indicating that introspection has been\ndisabled:\n\n```json\n{\n  \"data\": null,\n  \"errors\": [\n    {\n      \"message\": \"GraphQL introspection has been disabled, but the requested query contained the field '__schema'.\",\n      \"locations\": [\n        {\n          \"line\": 2,\n          \"column\": 3\n        }\n      ]\n    }\n  ]\n}\n```\n","docs/extensions/disable-validation.md":"---\ntitle: Disable Validation\nsummary: Disable all query validation.\ntags: performance,validation\n---\n\n# `DisableValidation`\n\nThis extensions disables all query validation. This can be useful to improve\nperformance in some specific cases, for example when dealing with internal APIs\nwhere queries can be trusted.\n\n<Warning>\n\nOnly do this if you know what you are doing! Disabling validation breaks the\nsafety of having typed schema. If you are trying to improve performance you\nmight want to consider using the [ValidationCache](./validation-cache) instead.\n\n</Warning>\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions import DisableValidation\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        DisableValidation(),\n    ],\n)\n```\n\n## API reference:\n\n_No arguments_\n","docs/extensions/input-mutation.md":"---\ntitle: Input Mutation Extension\nsummary: Automatically create Input types for mutations\ntags: QoL\n---\n\n# `InputMutationExtension`\n\nThe pattern of defining a mutation that receives a single\n[input type](../types/input-types.md) argument called `input` is a common\npractice in GraphQL. It helps to keep the mutation signatures clean and makes it\neasier to manage complex mutations with multiple arguments.\n\nThe `InputMutationExtension` is a Strawberry field extension that allows you to\ndefine a mutation with multiple arguments without having to manually create an\ninput type for it. Instead, it generates an input type based on the arguments of\nthe mutation resolver.\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.field_extensions import InputMutationExtension\n\n\n@strawberry.type\nclass User:\n    username: str\n\n\n@strawberry.type\nclass Query:\n    hello: str\n\n\n@strawberry.type\nclass Mutation:\n    @strawberry.mutation(extensions=[InputMutationExtension()])\n    def register_user(\n        self,\n        username: str,\n        password: str,\n    ) -> User:\n        user = User(username=username)\n        # maybe persist the user in a database\n        return user\n\n\nschema = strawberry.Schema(query=Query, mutation=Mutation)\n```\n\nThe Strawberry schema above and the usage of the `InputMutationExtension` will\nresult in the following GraphQL schema:\n\n```graphql\ntype User {\n  username: String!\n}\n\ninput RegisterUserInput {\n  username: String!\n  password: String!\n}\n\ntype Mutation {\n  registerUser(input: RegisterUserInput!): User!\n}\n\ntype Query {\n  hello: String!\n}\n```\n\n## API reference:\n\n_No arguments_\n","docs/extensions/mask-errors.md":"---\ntitle: Mask Errors\nsummary: Hide error messages from the client.\ntags: security\n---\n\n# `MaskErrors`\n\nThis extension hides error messages from the client to prevent exposing\nsensitive details. By default it masks all errors raised in any field resolver.\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions import MaskErrors\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hidden_error(self) -> str:\n        raise KeyError(\"This error will not be visible\")\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        MaskErrors(),\n    ],\n)\n```\n\n## API reference:\n\n```python\nclass MaskErrors(\n    should_mask_error=default_should_mask_error, error_message=\"Unexpected error.\"\n): ...\n```\n\n#### `should_mask_error: Callable[[GraphQLError], bool] = default_should_mask_error`\n\nPredicate function to check if a GraphQLError should be masked or not. Use the\n`original_error` attribute to access the original error that was raised in the\nresolver.\n\n<Note>\n\nThe `default_should_mask_error` function always returns `True`.\n\n</Note>\n\n#### `error_message: str = \"Unexpected error.\"`\n\nThe error message to display to the client when there is an error.\n\n## More examples:\n\n<details>\n  <summary>Hide some exceptions</summary>\n\n```python\nimport strawberry\nfrom strawberry.extensions import MaskErrors\nfrom graphql.error import GraphQLError\n\n\nclass VisibleError(Exception):\n    pass\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def visible_error(self) -> str:\n        raise VisibleError(\"This error will be visible\")\n\n\ndef should_mask_error(error: GraphQLError) -> bool:\n    original_error = error.original_error\n    if original_error and isinstance(original_error, VisibleError):\n        return False\n\n    return True\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        MaskErrors(should_mask_error=should_mask_error),\n    ],\n)\n```\n\n</details>\n\n<details>\n  <summary>Change error message</summary>\n\n```python\nimport strawberry\nfrom strawberry.extensions import MaskErrors\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hidden_error(self) -> str:\n        raise KeyError(\"This error will not be visible\")\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        MaskErrors(error_message=\"Oh no! An error occured. Very sorry about that.\"),\n    ],\n)\n```\n\n</details>\n","docs/extensions/max-aliases-limiter.md":"---\ntitle: Max Aliases Limiter\nsummary:\n  Add a validator to limit the maximum number of aliases in a GraphQL document.\ntags: security\n---\n\n# `MaxAliasesLimiter`\n\nThis extension adds a validator to limit the maximum number of aliases in a\nGraphQL document.\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions import MaxAliasesLimiter\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        MaxAliasesLimiter(max_alias_count=15),\n    ],\n)\n```\n\n## API reference:\n\n```python\nclass MaxAliasesLimiter(max_alias_count): ...\n```\n\n#### `max_alias_count: int`\n\nThe maximum allowed number of aliases in a GraphQL document.\n","docs/extensions/max-tokens-limiter.md":"---\ntitle: Max Tokens Limiter\nsummary:\n  Add a validator to limit the maximum number of tokens in a GraphQL document.\ntags: security\n---\n\n# `MaxTokensLimiter`\n\nThis extension adds a validator to limit the maximum number of tokens in a\nGraphQL document sent to the server.\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions import MaxTokensLimiter\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        MaxTokensLimiter(max_token_count=1000),\n    ],\n)\n```\n\nWith the above configuration, if a client sends a query with more than 1000\ntokens, the server will respond with an error message.\n\n## API reference:\n\n```python\nclass MaxTokensLimiter(max_token_count): ...\n```\n\n#### `max_token_count: int`\n\nThe maximum allowed number of tokens in a GraphQL document.\n\nThe following things are counted as tokens:\n\n- various brackets: \"{\", \"}\", \"(\", \")\"\n- colon :\n- words\n\nNot counted:\n\n- quotes\n","docs/extensions/opentelemetry.md":"---\ntitle: Open Telemetry\nsummary: Add Open Telemetry tracing to your GraphQL server.\ntags: tracing\n---\n\n# `OpenTelemetryExtension`\n\nThis extension adds tracing information that is compatible with\n[Open Telemetry](https://opentelemetry.io/).\n\n<Note>\n\nThis extension requires additional requirements:\n\n```shell\npip install 'strawberry-graphql[opentelemetry]'\n```\n\n</Note>\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions.tracing import OpenTelemetryExtension\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        OpenTelemetryExtension,\n    ],\n)\n```\n\n<Note>\n\nIf you are not running in an Async context then you'll need to use the sync\nversion:\n\n```python\nimport strawberry\nfrom strawberry.extensions.tracing import OpenTelemetryExtensionSync\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        OpenTelemetryExtensionSync,\n    ],\n)\n```\n\n</Note>\n\n## API reference:\n\n```python\nclass OpenTelemetryExtension(arg_filter=None): ...\n```\n\n#### `arg_filter: Optional[ArgFilter]`\n\nA function to filter certain field arguments from being included in the tracing\ndata.\n\n```python\nArgFilter = Callable[[Dict[str, Any], GraphQLResolveInfo], Dict[str, Any]]\n```\n\n## More examples:\n\n<details>\n  <summary>Using `arg_filter`</summary>\n\n```python\nimport strawberry\nfrom strawberry.extensions.tracing import OpenTelemetryExtensionSync\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\ndef arg_filter(kwargs, info):\n    filtered_kwargs = {}\n    for name, value in kwargs.items():\n        # Never include any arguments called \"password\"\n        if name == \"password\":\n            continue\n        filtered_kwargs[name] = value\n\n    return filtered_kwargs\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        OpenTelemetryExtensionSync(\n            arg_filter=arg_filter,\n        ),\n    ],\n)\n```\n\n</details>\n\n<details>\n  <summary>Using `tracer_provider`</summary>\n\n```python\nimport strawberry\nfrom opentelemetry.trace import TracerProvider\nfrom strawberry.extensions.tracing import OpenTelemetryExtension\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nclass MyTracerProvider(TracerProvider):\n    def get_tracer(self, name, version=None, schema_url=None):\n        return super().get_tracer(name, version, schema_url)\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        OpenTelemetryExtension(\n            tracer_provider=MyTracerProvider(),\n        ),\n    ],\n)\n```\n\n</details>\n","docs/extensions/parser-cache.md":"---\ntitle: Parser Cache\nsummary: Add in memory caching to the parsing step of query execution.\ntags: performance,caching,parsing\n---\n\n# `ParserCache`\n\nThis extension adds LRU caching to the parsing step of query execution to\nimprove performance by caching the parsed result in memory.\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions import ParserCache\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        ParserCache(),\n    ],\n)\n```\n\n## API reference:\n\n```python\nclass ParserCache(maxsize=128): ...\n```\n\n#### `maxsize: Optional[int] = 128`\n\nSet the maxsize of the cache. By default the cache is bounded to 128 entries,\nwith the least recently used entries evicted first. Pass an explicit\n`maxsize=None` to let the cache grow without bound; only do this when the set of\ndistinct query texts reaching the server is trusted and bounded, as an unbounded\ncache lets clients grow the server's memory indefinitely by sending unique query\ntexts.\n\nMore info: https://docs.python.org/3/library/functools.html#functools.lru_cache\n\n## More examples:\n\n<details>\n  <summary>Using maxsize</summary>\n\n```python\nimport strawberry\nfrom strawberry.extensions import ParserCache\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        ParserCache(maxsize=100),\n    ],\n)\n```\n\n</details>\n","docs/extensions/pydantic_error_extension.md":"---\ntitle: Pydantic Error Extension\nsummary:\n  Formats Pydantic validation errors into structured GraphQL error extensions.\ntags: pydantic,validation,errors,graphql,extensions\n---\n\n# `PydanticErrorExtension`\n\nThis extension detects Pydantic validation errors during GraphQL execution and\nformats them into structured `validation_errors` under the `extensions` field of\nGraphQL errors.\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions import PydanticErrorExtension\n\n\n@strawberry.type\nclass Mutation:\n    @strawberry.mutation\n    def create_user(self, email: str) -> str:\n        return email\n\n\nschema = strawberry.Schema(\n    mutation=Mutation,\n    extensions=[\n        PydanticErrorExtension(),\n    ],\n)\n```\n\n## API reference:\n\n```python\nclass PydanticErrorExtension: ...\n```\n\nThis extension does not require any arguments.\n\n## More examples:\n\n<details>\n  <summary>Example validation error output</summary>\n\n```json\n{\n  \"errors\": [\n    {\n      \"message\": \"Validation error\",\n      \"extensions\": {\n        \"validation_errors\": [\n          {\n            \"field\": \"email\",\n            \"message\": \"value is not a valid email\"\n          }\n        ]\n      }\n    }\n  ]\n}\n```\n\n</details>\n","docs/extensions/pyinstrument.md":"---\ntitle: PyInstrument\nsummary: Easily Instrument your Schema\ntags: instrumentation,profiling\n---\n\n# `PyInstrument`\n\nThis extension allows you to instrument your schema and inspect the call stack.\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions import pyinstrument\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        pyinstrument.PyInstrument(report_path=\"pyinstrument.html\"),\n    ],\n)\n```\n\n## API reference:\n\n```python\nclass PyInstrument(report_Path=Path(\"pyinstrument.html\")): ...\n```\n\n#### `report_path: Path = Path(\"pyinstrument.html\")`\n\nPath to write the HTML PyInstrument report\n","docs/extensions/query-depth-limiter.md":"---\ntitle: Query Depth Limiter\nsummary: Add a validator to limit the query depth of GraphQL operations.\ntags: security\n---\n\n# `QueryDepthLimiter`\n\nThis extension adds a validator to limit the query depth of GraphQL operations.\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions import QueryDepthLimiter\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        QueryDepthLimiter(max_depth=10),\n    ],\n)\n```\n\n## API reference:\n\n```python\nclass QueryDepthLimiter(max_depth, callback=None, should_ignore=None): ...\n```\n\n#### `max_depth: int`\n\nThe maximum allowed depth for any operation in a GraphQL document.\n\n#### `callback: Optional[Callable[[Dict[str, int]], None]`\n\nCalled each time validation runs. Receives a dictionary which is a map of the\ndepths for each operation.\n\n#### `should_ignore: Optional[Callable[[IgnoreContext], bool]]`\n\nCalled at each field to determine whether the field should be ignored or not.\nMust be implemented by the user and returns `True` if the field should be\nignored and `False` otherwise.\n\nThe `IgnoreContext` class has the following attributes:\n\n- `field_name` of type `str`: the name of the field to be compared against\n- `field_args` of type\n  `strawberry.extensions.query_depth_limiter.FieldArgumentsType`: the arguments\n  of the field to be compared against\n- `query` of type `graphql.language.Node`: the query string\n- `context` of type `graphql.validation.ValidationContext`: the context passed\n  to the query\n\nThis argument is injected, regardless of name, by the `QueryDepthLimiter` class\nand should not be passed by the user.\n\nInstead, the user should write business logic to determine whether a field\nshould be ignored or not by the attributes of the `IgnoreContext` class.\n\n## Example with field_name:\n\n```python\nimport strawberry\nfrom strawberry.extensions import QueryDepthLimiter, IgnoreContext\n\n\n@strawberry.type\nclass Book:\n    title: str\n    author: \"User\"\n\n\n@strawberry.type\nclass User:\n    favourite_books: list[Book]\n    published_books: list[Book]\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def book(self) -> Book:\n        return Book(\n            title=\"The Hitchhiker's Guide to the Strawberry Fields\",\n            author=User(favourite_books=[], published_books=[]),\n        )\n\n    @strawberry.field\n    def user(self) -> User:\n        return User(favourite_books=[], published_books=[])\n\n\ndef should_ignore(ignore: IgnoreContext):\n    return ignore.field_name == \"user\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        QueryDepthLimiter(max_depth=2, should_ignore=should_ignore),\n    ],\n)\n\n# This query fails\nschema.execute(\"\"\"\n    query TooDeep {\n        book {\n            author {\n                publishedBooks {\n                    title\n                }\n            }\n        }\n    }\n    \"\"\")\n\n# This query succeeds because the `user` field is ignored\nschema.execute(\"\"\"\n    query NotTooDeep {\n        user {\n            favouriteBooks {\n                author {\n                    publishedBooks {\n                        title\n                    }\n                }\n            }\n        }\n    }\n    \"\"\")\n```\n\n## Example with field_args:\n\n```python\nimport strawberry\nfrom strawberry.extensions import QueryDepthLimiter, IgnoreContext\n\n\n@strawberry.type\nclass Book:\n    title: str\n    author: \"User\"\n\n\n@strawberry.type\nclass User:\n    name: str | None\n    favourite_books: list[Book]\n    published_books: list[Book]\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def book(self) -> Book:\n        return Book(\n            title=\"The Hitchhiker's Guide to the Strawberry Fields\",\n            author=User(favourite_books=[], published_books=[]),\n        )\n\n    @strawberry.field\n    def user(self, name: str | None = None) -> User:\n        return User(name=name, favourite_books=[], published_books=[])\n\n\ndef should_ignore(ignore: IgnoreContext):\n    return ignore.field_args.get(\"name\") == \"matt\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        QueryDepthLimiter(max_depth=2, should_ignore=should_ignore),\n    ],\n)\n\n# This query fails\nschema.execute(\"\"\"\n    query TooDeep {\n        book {\n            author {\n                publishedBooks {\n                    title\n                }\n            }\n        }\n    }\n    \"\"\")\n\n# This query succeeds because the `user` field is ignored\nschema.execute(\"\"\"\n    query NotTooDeep {\n        user(name:\"matt\") {\n            favouriteBooks {\n                author {\n                    publishedBooks {\n                        title\n                    }\n                }\n            }\n        }\n    }\n    \"\"\")\n```\n","docs/extensions/sentry-tracing.md":"---\ntitle: Sentry Tracing\nsummary: Add Sentry tracing to your GraphQL server.\ntags: tracing\n---\n\n# `SentryTracingExtension`\n\n<Warning>\n\nAs of Sentry 1.32.0, Strawberry is officially supported by the Sentry SDK.\nTherefore, Strawberry's `SentryTracingExtension` has been deprecated in version\n0.210.0 and finally removed with Strawberry 0.249.0 in favor of the official\nSentry SDK integration.\n\nFor more details, please refer to the\n[documentation for the official Sentry Strawberry integration](https://docs.sentry.io/platforms/python/integrations/strawberry/).\n\n</Warning>\n\n## Filtering input coercion errors\n\nThe official Sentry integration captures all errors returned in a GraphQL\nresponse. If invalid client input should not be reported, use Sentry's\n`before_send` callback to filter `StrawberryInputCoercionError`:\n\n```python\nfrom typing import Any\n\nimport sentry_sdk\n\nfrom strawberry.exceptions import StrawberryInputCoercionError\n\n\ndef before_send(event: dict[str, Any], hint: dict[str, Any]) -> dict[str, Any] | None:\n    exc_info = hint.get(\"exc_info\")\n    error = exc_info[1] if exc_info else None\n\n    if isinstance(error, StrawberryInputCoercionError) or isinstance(\n        getattr(error, \"original_error\", None), StrawberryInputCoercionError\n    ):\n        return None\n\n    return event\n\n\nsentry_sdk.init(before_send=before_send)\n```\n\nChecking `original_error` is necessary because graphql-core wraps scalar errors\nraised while coercing variables in another `GraphQLError`. For this reason,\nSentry's `ignore_errors` option alone does not filter every input coercion\nerror.\n","docs/extensions/validation-cache.md":"---\ntitle: Validation Cache\nsummary: Add in memory caching to the validation step of query execution.\ntags: performance,caching,validation\n---\n\n# `ValidationCache`\n\nThis extension adds LRU caching to the validation step of query execution to\nimprove performance by caching the validation errors in memory.\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions import ValidationCache\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        ValidationCache(),\n    ],\n)\n```\n\n## API reference:\n\n```python\nclass ValidationCache(maxsize=128): ...\n```\n\n#### `maxsize: Optional[int] = 128`\n\nSet the maxsize of the cache. By default the cache is bounded to 128 entries,\nwith the least recently used entries evicted first. Pass an explicit\n`maxsize=None` to let the cache grow without bound; only do this when the set of\ndistinct query texts reaching the server is trusted and bounded, as an unbounded\ncache lets clients grow the server's memory indefinitely by sending unique query\ntexts.\n\nMore info: https://docs.python.org/3/library/functools.html#functools.lru_cache\n\n## More examples:\n\n<details>\n  <summary>Using maxsize</summary>\n\n```python\nimport strawberry\nfrom strawberry.extensions import ValidationCache\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        ValidationCache(maxsize=100),\n    ],\n)\n```\n\n</details>\n"},"items":[{"name":"AGENTS.md","path":"AGENTS.md","rawUrl":"https://raw.githubusercontent.com/strawberry-graphql/strawberry/HEAD/AGENTS.md","title":"AI Agent Protocol & Instructions","category":"root-instruction","format":"markdown","content":"# AGENTS.md\n\nStrawberry GraphQL\n\n- Docs: https://strawberry.rocks/docs\n- Repo: https://github.com/strawberry-graphql/strawberry\n\n## Setup\n\n```shell\n$ uv sync\n$ uv run pre-commit install\n```\n\nThe default uv dependency groups include both `dev` and `integrations`, so a\nplain `uv sync` installs everything needed for local development.\n\n## Commands\n\n- **Test:** `uv run pytest`\n- **Focused test:** `uv run pytest path/to/test.py -q`\n- **Type check:** `uv run mypy --config-file mypy.ini`\n- **Lint:** `uv run ruff check .`\n- **Format:** `uv run ruff format .`\n- **Check formatting:** `uv run ruff format --check .`\n- **Run all pre-commit hooks:** `uv run pre-commit run --all-files`\n\nRun focused tests while iterating, then run the relevant broader test suite.\nThe CI test matrix is defined in `noxfile.py`; list its sessions with\n`uv run nox -t tests -l`.\n\n## Engineering Principles\n\n- Write code as if we will maintain it for years. Prefer clear, cohesive\n  implementations over the quickest local patch, solve root causes, and leave\n  the surrounding code easier to understand.\n- Think about features end to end before changing them. As relevant, trace the\n  public API through schema construction and execution, sync and async paths,\n  typing, framework integrations, error behavior, backwards compatibility, and\n  performance.\n- A feature is complete when its implementation, tests, documentation, error\n  messages, and release note tell the same coherent story. Cover important edge\n  cases and the user-visible behavior, not only the happy-path implementation.\n- Before finishing, review the diff from both a user's and a maintainer's\n  perspective: does it fit Strawberry's existing design, is its behavior\n  unsurprising, and would we be happy to support it long term?\n\n## Code Style\n\n- Ruff for linting/formatting (line length 88, Python 3.11 target)\n- Keep production code fully typed. The repository's mypy configuration is not\n  globally strict, so follow the surrounding code and avoid introducing new\n  untyped definitions.\n- Decorator-based schema: `@strawberry.type`, `@strawberry.field`,\n  `@strawberry.mutation`\n- Preserve both synchronous and asynchronous execution paths unless a feature is\n  explicitly async-only.\n\n## Structure\n\n- `strawberry/` - Core library\n  - `schema/` - Schema definition/execution\n  - `types/` - GraphQL type definitions\n  - `extensions/` - Built-in extensions\n  - `django/`, `fastapi/`, `flask/`, etc. - Framework integrations\n- `tests/` - pytest suite with integration markers (`django`, `fastapi`,\n  `pydantic`, etc.)\n\n## PR Requirements\n\n- Include `RELEASE.md` file describing changes\n- Release types: patch/minor/major\n- Add tests for behavior changes and keep affected code covered\n- Update documentation when user-facing behavior changes\n\n## Release file (RELEASE.md)\n\nRelease type is one of: `patch`, `minor`, or `major` (semver). Release notes\nshould start with `This release adds ...` or `This release fixes ...` and lead\nwith the user-visible behavior.\n\nExample:\n\n```markdown\n---\nrelease type: patch\n---\n\nThis release fixes schema printing for nullable input defaults.\n\nStrawberry now preserves explicit `None` values in printed nested input\ndefaults.\n```\n","isInternal":false,"tokens":765,"sizeBytes":3210},{"name":"CLAUDE.md","path":"CLAUDE.md","rawUrl":"https://raw.githubusercontent.com/strawberry-graphql/strawberry/HEAD/CLAUDE.md","title":"Claude Agent Guidelines & System Prompt","category":"claude-rule","format":"markdown","content":"@AGENTS.md\n","isInternal":false,"tokens":5,"sizeBytes":11},{"name":"_template.md","path":"docs/extensions/_template.md","rawUrl":"https://raw.githubusercontent.com/strawberry-graphql/strawberry/HEAD/docs/extensions/_template.md","title":"Extensions Skill","category":"anthropic-skill","format":"markdown","content":"---\ntitle: Extension Name\nsummary: A summary of the extension.\ntags: comma,separated,list,of,tags\n---\n\n# `ExtensionName`\n\nThis extension does ...\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions import ExtensionName\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        ExtensionName(),\n    ],\n)\n```\n\n## API reference:\n\n```python\nclass ExtensionName(an_argument=None): ...\n```\n\n#### `an_argument: Optional[str] = None`\n\nDescription of the argument.\n\n## More examples:\n\n<details>\n  <summary>Using `an_argument`</summary>\n\n```python\nimport strawberry\nfrom strawberry.extensions import ValidationCache\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        ExtensionName(an_argument=\"something\"),\n    ],\n)\n```\n\n</details>\n","frontmatter":{"title":"Extension Name","summary":"A summary of the extension.","tags":"comma,separated,list,of,tags"},"isInternal":false,"tokens":197,"sizeBytes":880},{"name":"add-validation-rules.md","path":"docs/extensions/add-validation-rules.md","rawUrl":"https://raw.githubusercontent.com/strawberry-graphql/strawberry/HEAD/docs/extensions/add-validation-rules.md","title":"Extensions Skill","category":"anthropic-skill","format":"markdown","content":"---\ntitle: Add Validation Rules\nsummary: Add GraphQL validation rules.\ntags: validation,security\n---\n\n# `AddValidationRules`\n\nThis extension allows you add custom validation rules.\n\nSee\n[graphql.validation.rules.custom](https://github.com/graphql-python/graphql-core/tree/main/src/graphql/validation/rules/custom)\nfor some custom rules that can be added from GraphQl-core.\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions import AddValidationRules\nfrom graphql import ValidationRule\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nclass MyCustomRule(ValidationRule): ...\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        AddValidationRules(MyCustomRule),\n    ],\n)\n```\n\n## API reference:\n\n```python\nclass AddValidationRules(validation_rules): ...\n```\n\n#### `validation_rules: List[Type[ASTValidationRule]]`\n\nList of GraphQL validation rules.\n\n## More examples:\n\n<details>\n  <summary>Adding a custom rule</summary>\n\n```python\nimport strawberry\nfrom strawberry.extensions import AddValidationRules\nfrom graphql import ValidationRule\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nclass CustomRule(ValidationRule):\n    def enter_field(self, node, *args) -> None:\n        if node.name.value == \"example\":\n            self.report_error(GraphQLError(\"Can't query field 'example'\"))\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        AddValidationRules([CustomRule]),\n    ],\n)\n\nresult = schema.execute_sync(\"{ example }\")\n\nassert str(result.errors[0]) == \"Can't query field 'example'\"\n```\n\n</details>\n\n<details>\n  <summary>Adding the `NoDeprecatedCustomRule` from GraphQL-core</summary>\n\n```python\nimport strawberry\nfrom strawberry.extensions import AddValidationRules\nfrom graphql.validation import NoDeprecatedCustomRule\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        AddValidationRules([NoDeprecatedCustomRule]),\n    ],\n)\n```\n\n</details>\n\n<details>\n  <summary>Adding the `NoSchemaIntrospectionCustomRule` from GraphQL-core</summary>\n\n```python\nimport strawberry\nfrom strawberry.extensions import AddValidationRules\nfrom graphql.validation import NoSchemaIntrospectionCustomRule\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        AddValidationRules([NoSchemaIntrospectionCustomRule]),\n    ],\n)\n```\n\n</details>\n","frontmatter":{"title":"Add Validation Rules","summary":"Add GraphQL validation rules.","tags":"validation,security"},"isInternal":false,"tokens":589,"sizeBytes":2656},{"name":"apollo-federation-tracing.md","path":"docs/extensions/apollo-federation-tracing.md","rawUrl":"https://raw.githubusercontent.com/strawberry-graphql/strawberry/HEAD/docs/extensions/apollo-federation-tracing.md","title":"Extensions Skill","category":"anthropic-skill","format":"markdown","content":"---\ntitle: Apollo Federation Tracing\nsummary: Add Apollo Federation inline tracing (FTV1) to your GraphQL server.\ntags: tracing,federation\n---\n\n# `ApolloFederationTracingExtension`\n\nThis extension adds support for\n[Apollo Federation inline tracing (FTV1)](https://www.apollographql.com/docs/federation/).\nWhen a request includes the `apollo-federation-include-trace: ftv1` header, the\nextension records per-resolver timing and includes the trace in the response as\na base64-encoded protobuf under `extensions.ftv1`.\n\n<Warning>\n\nAny client can send the `apollo-federation-include-trace: ftv1` header unless\nyou restrict it. Tracing payloads expose resolver timing details, so make sure\nonly a trusted Apollo Gateway (or other internal traffic) can request traces —\nfor example by enforcing authentication, network policy, or stripping the header\nfrom public requests at the edge.\n\n</Warning>\n\n<Note>\n\nMake sure you have `protobuf` installed before using this extension.\n\n```shell\npip install 'strawberry-graphql[apollo-federation]'\n```\n\n</Note>\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions.tracing import ApolloFederationTracingExtension\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        ApolloFederationTracingExtension,\n    ],\n)\n```\n\n<Note>\n\nIf you are not running in an Async context then you'll need to use the sync\nversion:\n\n```python\nimport strawberry\nfrom strawberry.extensions.tracing import ApolloFederationTracingExtensionSync\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        ApolloFederationTracingExtensionSync,\n    ],\n)\n```\n\n</Note>\n\n## API reference:\n\n_No arguments_\n","frontmatter":{"title":"Apollo Federation Tracing","summary":"Add Apollo Federation inline tracing (FTV1) to your GraphQL server.","tags":"tracing,federation"},"isInternal":false,"tokens":427,"sizeBytes":1871},{"name":"apollo-tracing.md","path":"docs/extensions/apollo-tracing.md","rawUrl":"https://raw.githubusercontent.com/strawberry-graphql/strawberry/HEAD/docs/extensions/apollo-tracing.md","title":"Extensions Skill","category":"anthropic-skill","format":"markdown","content":"---\ntitle: Apollo Tracing\nsummary: Add Apollo tracing to your GraphQL server.\ntags: tracing\n---\n\n# `ApolloTracingExtension`\n\nThis extension adds\n[tracing information](https://github.com/apollographql/apollo-tracing) to your\nresponse for [Apollo Engine](https://www.apollographql.com/platform/).\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions.tracing import ApolloTracingExtension\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        ApolloTracingExtension,\n    ],\n)\n```\n\n<Note>\n\nIf you are not running in an Async context then you'll need to use the sync\nversion:\n\n```python\nimport strawberry\nfrom strawberry.extensions.tracing import ApolloTracingExtensionSync\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        ApolloTracingExtensionSync,\n    ],\n)\n```\n\n</Note>\n\n## API reference:\n\n_No arguments_\n","frontmatter":{"title":"Apollo Tracing","summary":"Add Apollo tracing to your GraphQL server.","tags":"tracing"},"isInternal":false,"tokens":254,"sizeBytes":1080},{"name":"datadog.md","path":"docs/extensions/datadog.md","rawUrl":"https://raw.githubusercontent.com/strawberry-graphql/strawberry/HEAD/docs/extensions/datadog.md","title":"Extensions Skill","category":"anthropic-skill","format":"markdown","content":"---\ntitle: Datadog\nsummary: Add Datadog tracing to your GraphQL server.\ntags: tracing\n---\n\n# `DatadogExtension`\n\nThis extension adds support for tracing with Datadog.\n\n<Note>\n\nMake sure you have `ddtrace` installed before using this extension.\n\n```shell\npip install ddtrace\n```\n\n</Note>\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions.tracing import DatadogTracingExtension\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        DatadogTracingExtension,\n    ],\n)\n```\n\n<Note>\n\nIf you are not running in an Async context then you'll need to use the sync\nversion:\n\n```python\nimport strawberry\nfrom strawberry.extensions.tracing import DatadogTracingExtensionSync\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        DatadogTracingExtensionSync,\n    ],\n)\n```\n\n</Note>\n\n## API reference:\n\n_No arguments_\n\n## Extending the extension\n\n### Overriding the `create_span` method\n\nYou can customize any of the spans or add tags to them by overriding the\n`create_span` method.\n\nExample:\n\n```python\nfrom ddtrace import Span\n\nfrom strawberry.extensions import LifecycleStep\nfrom strawberry.extensions.tracing import DatadogTracingExtension\n\n\nclass DataDogExtension(DatadogTracingExtension):\n    def create_span(\n        self,\n        lifecycle_step: LifecycleStep,\n        name: str,\n        **kwargs,\n    ) -> Span:\n        span = super().create_span(lifecycle_step, name, **kwargs)\n        if lifecycle_step == LifecycleStep.OPERATION:\n            span.set_tag(\"graphql.query\", self.execution_context.query)\n        return span\n```\n","frontmatter":{"title":"Datadog","summary":"Add Datadog tracing to your GraphQL server.","tags":"tracing"},"isInternal":false,"tokens":417,"sizeBytes":1796},{"name":"disable-introspection.md","path":"docs/extensions/disable-introspection.md","rawUrl":"https://raw.githubusercontent.com/strawberry-graphql/strawberry/HEAD/docs/extensions/disable-introspection.md","title":"Extensions Skill","category":"anthropic-skill","format":"markdown","content":"---\ntitle: Disable Introspection\nsummary: Disable standard GraphQL introspection queries.\ntags: security,validation\n---\n\n# `DisableIntrospection`\n\nThe `DisableIntrospection` extension disables standard GraphQL introspection\nqueries for the schema. It blocks fields such as `__schema` and `__type`.\n\nThis can be useful to prevent clients from discovering unreleased or internal\nfeatures of the API through GraphQL introspection.\n\n<Warning>\n\n`DisableIntrospection` does not block non-introspection fields that may expose\nschema information. For example, Apollo Federation schemas expose `_service` and\nits `sdl` field so gateways and routers can compose federated services. If you\nuse `strawberry.federation.Schema`, protect federated endpoints from untrusted\nclients with your own authentication, authorization, or network controls.\n\n</Warning>\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions import DisableIntrospection\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        DisableIntrospection(),\n    ],\n)\n```\n\n## API reference:\n\n_No arguments_\n\n## Example query:\n\nRunning any query including the introspection field `__schema` will result in an\nerror. Consider the following query, for example:\n\n```graphql\nquery {\n  __schema {\n    __typename\n  }\n}\n```\n\nRunning it against the schema with the `DisableIntrospection` extension enabled\nwill result in an error response indicating that introspection has been\ndisabled:\n\n```json\n{\n  \"data\": null,\n  \"errors\": [\n    {\n      \"message\": \"GraphQL introspection has been disabled, but the requested query contained the field '__schema'.\",\n      \"locations\": [\n        {\n          \"line\": 2,\n          \"column\": 3\n        }\n      ]\n    }\n  ]\n}\n```\n","frontmatter":{"title":"Disable Introspection","summary":"Disable standard GraphQL introspection queries.","tags":"security,validation"},"isInternal":false,"tokens":407,"sizeBytes":1842},{"name":"disable-validation.md","path":"docs/extensions/disable-validation.md","rawUrl":"https://raw.githubusercontent.com/strawberry-graphql/strawberry/HEAD/docs/extensions/disable-validation.md","title":"Extensions Skill","category":"anthropic-skill","format":"markdown","content":"---\ntitle: Disable Validation\nsummary: Disable all query validation.\ntags: performance,validation\n---\n\n# `DisableValidation`\n\nThis extensions disables all query validation. This can be useful to improve\nperformance in some specific cases, for example when dealing with internal APIs\nwhere queries can be trusted.\n\n<Warning>\n\nOnly do this if you know what you are doing! Disabling validation breaks the\nsafety of having typed schema. If you are trying to improve performance you\nmight want to consider using the [ValidationCache](./validation-cache) instead.\n\n</Warning>\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions import DisableValidation\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        DisableValidation(),\n    ],\n)\n```\n\n## API reference:\n\n_No arguments_\n","frontmatter":{"title":"Disable Validation","summary":"Disable all query validation.","tags":"performance,validation"},"isInternal":false,"tokens":190,"sizeBytes":918},{"name":"input-mutation.md","path":"docs/extensions/input-mutation.md","rawUrl":"https://raw.githubusercontent.com/strawberry-graphql/strawberry/HEAD/docs/extensions/input-mutation.md","title":"Extensions Skill","category":"anthropic-skill","format":"markdown","content":"---\ntitle: Input Mutation Extension\nsummary: Automatically create Input types for mutations\ntags: QoL\n---\n\n# `InputMutationExtension`\n\nThe pattern of defining a mutation that receives a single\n[input type](../types/input-types.md) argument called `input` is a common\npractice in GraphQL. It helps to keep the mutation signatures clean and makes it\neasier to manage complex mutations with multiple arguments.\n\nThe `InputMutationExtension` is a Strawberry field extension that allows you to\ndefine a mutation with multiple arguments without having to manually create an\ninput type for it. Instead, it generates an input type based on the arguments of\nthe mutation resolver.\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.field_extensions import InputMutationExtension\n\n\n@strawberry.type\nclass User:\n    username: str\n\n\n@strawberry.type\nclass Query:\n    hello: str\n\n\n@strawberry.type\nclass Mutation:\n    @strawberry.mutation(extensions=[InputMutationExtension()])\n    def register_user(\n        self,\n        username: str,\n        password: str,\n    ) -> User:\n        user = User(username=username)\n        # maybe persist the user in a database\n        return user\n\n\nschema = strawberry.Schema(query=Query, mutation=Mutation)\n```\n\nThe Strawberry schema above and the usage of the `InputMutationExtension` will\nresult in the following GraphQL schema:\n\n```graphql\ntype User {\n  username: String!\n}\n\ninput RegisterUserInput {\n  username: String!\n  password: String!\n}\n\ntype Mutation {\n  registerUser(input: RegisterUserInput!): User!\n}\n\ntype Query {\n  hello: String!\n}\n```\n\n## API reference:\n\n_No arguments_\n","frontmatter":{"title":"Input Mutation Extension","summary":"Automatically create Input types for mutations","tags":"QoL"},"isInternal":false,"tokens":348,"sizeBytes":1622},{"name":"mask-errors.md","path":"docs/extensions/mask-errors.md","rawUrl":"https://raw.githubusercontent.com/strawberry-graphql/strawberry/HEAD/docs/extensions/mask-errors.md","title":"Extensions Skill","category":"anthropic-skill","format":"markdown","content":"---\ntitle: Mask Errors\nsummary: Hide error messages from the client.\ntags: security\n---\n\n# `MaskErrors`\n\nThis extension hides error messages from the client to prevent exposing\nsensitive details. By default it masks all errors raised in any field resolver.\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions import MaskErrors\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hidden_error(self) -> str:\n        raise KeyError(\"This error will not be visible\")\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        MaskErrors(),\n    ],\n)\n```\n\n## API reference:\n\n```python\nclass MaskErrors(\n    should_mask_error=default_should_mask_error, error_message=\"Unexpected error.\"\n): ...\n```\n\n#### `should_mask_error: Callable[[GraphQLError], bool] = default_should_mask_error`\n\nPredicate function to check if a GraphQLError should be masked or not. Use the\n`original_error` attribute to access the original error that was raised in the\nresolver.\n\n<Note>\n\nThe `default_should_mask_error` function always returns `True`.\n\n</Note>\n\n#### `error_message: str = \"Unexpected error.\"`\n\nThe error message to display to the client when there is an error.\n\n## More examples:\n\n<details>\n  <summary>Hide some exceptions</summary>\n\n```python\nimport strawberry\nfrom strawberry.extensions import MaskErrors\nfrom graphql.error import GraphQLError\n\n\nclass VisibleError(Exception):\n    pass\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def visible_error(self) -> str:\n        raise VisibleError(\"This error will be visible\")\n\n\ndef should_mask_error(error: GraphQLError) -> bool:\n    original_error = error.original_error\n    if original_error and isinstance(original_error, VisibleError):\n        return False\n\n    return True\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        MaskErrors(should_mask_error=should_mask_error),\n    ],\n)\n```\n\n</details>\n\n<details>\n  <summary>Change error message</summary>\n\n```python\nimport strawberry\nfrom strawberry.extensions import MaskErrors\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hidden_error(self) -> str:\n        raise KeyError(\"This error will not be visible\")\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        MaskErrors(error_message=\"Oh no! An error occured. Very sorry about that.\"),\n    ],\n)\n```\n\n</details>\n","frontmatter":{"title":"Mask Errors","summary":"Hide error messages from the client.","tags":"security"},"isInternal":false,"tokens":510,"sizeBytes":2342},{"name":"max-aliases-limiter.md","path":"docs/extensions/max-aliases-limiter.md","rawUrl":"https://raw.githubusercontent.com/strawberry-graphql/strawberry/HEAD/docs/extensions/max-aliases-limiter.md","title":"Extensions Skill","category":"anthropic-skill","format":"markdown","content":"---\ntitle: Max Aliases Limiter\nsummary:\n  Add a validator to limit the maximum number of aliases in a GraphQL document.\ntags: security\n---\n\n# `MaxAliasesLimiter`\n\nThis extension adds a validator to limit the maximum number of aliases in a\nGraphQL document.\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions import MaxAliasesLimiter\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        MaxAliasesLimiter(max_alias_count=15),\n    ],\n)\n```\n\n## API reference:\n\n```python\nclass MaxAliasesLimiter(max_alias_count): ...\n```\n\n#### `max_alias_count: int`\n\nThe maximum allowed number of aliases in a GraphQL document.\n","frontmatter":{"title":"Max Aliases Limiter","summary":"Add a validator to limit the maximum number of aliases in a GraphQL document.","tags":"security"},"isInternal":false,"tokens":173,"sizeBytes":759},{"name":"max-tokens-limiter.md","path":"docs/extensions/max-tokens-limiter.md","rawUrl":"https://raw.githubusercontent.com/strawberry-graphql/strawberry/HEAD/docs/extensions/max-tokens-limiter.md","title":"Extensions Skill","category":"anthropic-skill","format":"markdown","content":"---\ntitle: Max Tokens Limiter\nsummary:\n  Add a validator to limit the maximum number of tokens in a GraphQL document.\ntags: security\n---\n\n# `MaxTokensLimiter`\n\nThis extension adds a validator to limit the maximum number of tokens in a\nGraphQL document sent to the server.\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions import MaxTokensLimiter\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        MaxTokensLimiter(max_token_count=1000),\n    ],\n)\n```\n\nWith the above configuration, if a client sends a query with more than 1000\ntokens, the server will respond with an error message.\n\n## API reference:\n\n```python\nclass MaxTokensLimiter(max_token_count): ...\n```\n\n#### `max_token_count: int`\n\nThe maximum allowed number of tokens in a GraphQL document.\n\nThe following things are counted as tokens:\n\n- various brackets: \"{\", \"}\", \"(\", \")\"\n- colon :\n- words\n\nNot counted:\n\n- quotes\n","frontmatter":{"title":"Max Tokens Limiter","summary":"Add a validator to limit the maximum number of tokens in a GraphQL document.","tags":"security"},"isInternal":false,"tokens":237,"sizeBytes":1031},{"name":"opentelemetry.md","path":"docs/extensions/opentelemetry.md","rawUrl":"https://raw.githubusercontent.com/strawberry-graphql/strawberry/HEAD/docs/extensions/opentelemetry.md","title":"Extensions Skill","category":"anthropic-skill","format":"markdown","content":"---\ntitle: Open Telemetry\nsummary: Add Open Telemetry tracing to your GraphQL server.\ntags: tracing\n---\n\n# `OpenTelemetryExtension`\n\nThis extension adds tracing information that is compatible with\n[Open Telemetry](https://opentelemetry.io/).\n\n<Note>\n\nThis extension requires additional requirements:\n\n```shell\npip install 'strawberry-graphql[opentelemetry]'\n```\n\n</Note>\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions.tracing import OpenTelemetryExtension\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        OpenTelemetryExtension,\n    ],\n)\n```\n\n<Note>\n\nIf you are not running in an Async context then you'll need to use the sync\nversion:\n\n```python\nimport strawberry\nfrom strawberry.extensions.tracing import OpenTelemetryExtensionSync\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        OpenTelemetryExtensionSync,\n    ],\n)\n```\n\n</Note>\n\n## API reference:\n\n```python\nclass OpenTelemetryExtension(arg_filter=None): ...\n```\n\n#### `arg_filter: Optional[ArgFilter]`\n\nA function to filter certain field arguments from being included in the tracing\ndata.\n\n```python\nArgFilter = Callable[[Dict[str, Any], GraphQLResolveInfo], Dict[str, Any]]\n```\n\n## More examples:\n\n<details>\n  <summary>Using `arg_filter`</summary>\n\n```python\nimport strawberry\nfrom strawberry.extensions.tracing import OpenTelemetryExtensionSync\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\ndef arg_filter(kwargs, info):\n    filtered_kwargs = {}\n    for name, value in kwargs.items():\n        # Never include any arguments called \"password\"\n        if name == \"password\":\n            continue\n        filtered_kwargs[name] = value\n\n    return filtered_kwargs\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        OpenTelemetryExtensionSync(\n            arg_filter=arg_filter,\n        ),\n    ],\n)\n```\n\n</details>\n\n<details>\n  <summary>Using `tracer_provider`</summary>\n\n```python\nimport strawberry\nfrom opentelemetry.trace import TracerProvider\nfrom strawberry.extensions.tracing import OpenTelemetryExtension\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nclass MyTracerProvider(TracerProvider):\n    def get_tracer(self, name, version=None, schema_url=None):\n        return super().get_tracer(name, version, schema_url)\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        OpenTelemetryExtension(\n            tracer_provider=MyTracerProvider(),\n        ),\n    ],\n)\n```\n\n</details>\n","frontmatter":{"title":"Open Telemetry","summary":"Add Open Telemetry tracing to your GraphQL server.","tags":"tracing"},"isInternal":false,"tokens":635,"sizeBytes":2789},{"name":"parser-cache.md","path":"docs/extensions/parser-cache.md","rawUrl":"https://raw.githubusercontent.com/strawberry-graphql/strawberry/HEAD/docs/extensions/parser-cache.md","title":"Extensions Skill","category":"anthropic-skill","format":"markdown","content":"---\ntitle: Parser Cache\nsummary: Add in memory caching to the parsing step of query execution.\ntags: performance,caching,parsing\n---\n\n# `ParserCache`\n\nThis extension adds LRU caching to the parsing step of query execution to\nimprove performance by caching the parsed result in memory.\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions import ParserCache\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        ParserCache(),\n    ],\n)\n```\n\n## API reference:\n\n```python\nclass ParserCache(maxsize=128): ...\n```\n\n#### `maxsize: Optional[int] = 128`\n\nSet the maxsize of the cache. By default the cache is bounded to 128 entries,\nwith the least recently used entries evicted first. Pass an explicit\n`maxsize=None` to let the cache grow without bound; only do this when the set of\ndistinct query texts reaching the server is trusted and bounded, as an unbounded\ncache lets clients grow the server's memory indefinitely by sending unique query\ntexts.\n\nMore info: https://docs.python.org/3/library/functools.html#functools.lru_cache\n\n## More examples:\n\n<details>\n  <summary>Using maxsize</summary>\n\n```python\nimport strawberry\nfrom strawberry.extensions import ParserCache\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        ParserCache(maxsize=100),\n    ],\n)\n```\n\n</details>\n","frontmatter":{"title":"Parser Cache","summary":"Add in memory caching to the parsing step of query execution.","tags":"performance,caching,parsing"},"isInternal":false,"tokens":357,"sizeBytes":1542},{"name":"pydantic_error_extension.md","path":"docs/extensions/pydantic_error_extension.md","rawUrl":"https://raw.githubusercontent.com/strawberry-graphql/strawberry/HEAD/docs/extensions/pydantic_error_extension.md","title":"Extensions Skill","category":"anthropic-skill","format":"markdown","content":"---\ntitle: Pydantic Error Extension\nsummary:\n  Formats Pydantic validation errors into structured GraphQL error extensions.\ntags: pydantic,validation,errors,graphql,extensions\n---\n\n# `PydanticErrorExtension`\n\nThis extension detects Pydantic validation errors during GraphQL execution and\nformats them into structured `validation_errors` under the `extensions` field of\nGraphQL errors.\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions import PydanticErrorExtension\n\n\n@strawberry.type\nclass Mutation:\n    @strawberry.mutation\n    def create_user(self, email: str) -> str:\n        return email\n\n\nschema = strawberry.Schema(\n    mutation=Mutation,\n    extensions=[\n        PydanticErrorExtension(),\n    ],\n)\n```\n\n## API reference:\n\n```python\nclass PydanticErrorExtension: ...\n```\n\nThis extension does not require any arguments.\n\n## More examples:\n\n<details>\n  <summary>Example validation error output</summary>\n\n```json\n{\n  \"errors\": [\n    {\n      \"message\": \"Validation error\",\n      \"extensions\": {\n        \"validation_errors\": [\n          {\n            \"field\": \"email\",\n            \"message\": \"value is not a valid email\"\n          }\n        ]\n      }\n    }\n  ]\n}\n```\n\n</details>\n","frontmatter":{"title":"Pydantic Error Extension","summary":"Formats Pydantic validation errors into structured GraphQL error extensions.","tags":"pydantic,validation,errors,graphql,extensions"},"isInternal":false,"tokens":268,"sizeBytes":1206},{"name":"pyinstrument.md","path":"docs/extensions/pyinstrument.md","rawUrl":"https://raw.githubusercontent.com/strawberry-graphql/strawberry/HEAD/docs/extensions/pyinstrument.md","title":"Extensions Skill","category":"anthropic-skill","format":"markdown","content":"---\ntitle: PyInstrument\nsummary: Easily Instrument your Schema\ntags: instrumentation,profiling\n---\n\n# `PyInstrument`\n\nThis extension allows you to instrument your schema and inspect the call stack.\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions import pyinstrument\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        pyinstrument.PyInstrument(report_path=\"pyinstrument.html\"),\n    ],\n)\n```\n\n## API reference:\n\n```python\nclass PyInstrument(report_Path=Path(\"pyinstrument.html\")): ...\n```\n\n#### `report_path: Path = Path(\"pyinstrument.html\")`\n\nPath to write the HTML PyInstrument report\n","frontmatter":{"title":"PyInstrument","summary":"Easily Instrument your Schema","tags":"instrumentation,profiling"},"isInternal":false,"tokens":164,"sizeBytes":740},{"name":"query-depth-limiter.md","path":"docs/extensions/query-depth-limiter.md","rawUrl":"https://raw.githubusercontent.com/strawberry-graphql/strawberry/HEAD/docs/extensions/query-depth-limiter.md","title":"Extensions Skill","category":"anthropic-skill","format":"markdown","content":"---\ntitle: Query Depth Limiter\nsummary: Add a validator to limit the query depth of GraphQL operations.\ntags: security\n---\n\n# `QueryDepthLimiter`\n\nThis extension adds a validator to limit the query depth of GraphQL operations.\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions import QueryDepthLimiter\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        QueryDepthLimiter(max_depth=10),\n    ],\n)\n```\n\n## API reference:\n\n```python\nclass QueryDepthLimiter(max_depth, callback=None, should_ignore=None): ...\n```\n\n#### `max_depth: int`\n\nThe maximum allowed depth for any operation in a GraphQL document.\n\n#### `callback: Optional[Callable[[Dict[str, int]], None]`\n\nCalled each time validation runs. Receives a dictionary which is a map of the\ndepths for each operation.\n\n#### `should_ignore: Optional[Callable[[IgnoreContext], bool]]`\n\nCalled at each field to determine whether the field should be ignored or not.\nMust be implemented by the user and returns `True` if the field should be\nignored and `False` otherwise.\n\nThe `IgnoreContext` class has the following attributes:\n\n- `field_name` of type `str`: the name of the field to be compared against\n- `field_args` of type\n  `strawberry.extensions.query_depth_limiter.FieldArgumentsType`: the arguments\n  of the field to be compared against\n- `query` of type `graphql.language.Node`: the query string\n- `context` of type `graphql.validation.ValidationContext`: the context passed\n  to the query\n\nThis argument is injected, regardless of name, by the `QueryDepthLimiter` class\nand should not be passed by the user.\n\nInstead, the user should write business logic to determine whether a field\nshould be ignored or not by the attributes of the `IgnoreContext` class.\n\n## Example with field_name:\n\n```python\nimport strawberry\nfrom strawberry.extensions import QueryDepthLimiter, IgnoreContext\n\n\n@strawberry.type\nclass Book:\n    title: str\n    author: \"User\"\n\n\n@strawberry.type\nclass User:\n    favourite_books: list[Book]\n    published_books: list[Book]\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def book(self) -> Book:\n        return Book(\n            title=\"The Hitchhiker's Guide to the Strawberry Fields\",\n            author=User(favourite_books=[], published_books=[]),\n        )\n\n    @strawberry.field\n    def user(self) -> User:\n        return User(favourite_books=[], published_books=[])\n\n\ndef should_ignore(ignore: IgnoreContext):\n    return ignore.field_name == \"user\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        QueryDepthLimiter(max_depth=2, should_ignore=should_ignore),\n    ],\n)\n\n# This query fails\nschema.execute(\"\"\"\n    query TooDeep {\n        book {\n            author {\n                publishedBooks {\n                    title\n                }\n            }\n        }\n    }\n    \"\"\")\n\n# This query succeeds because the `user` field is ignored\nschema.execute(\"\"\"\n    query NotTooDeep {\n        user {\n            favouriteBooks {\n                author {\n                    publishedBooks {\n                        title\n                    }\n                }\n            }\n        }\n    }\n    \"\"\")\n```\n\n## Example with field_args:\n\n```python\nimport strawberry\nfrom strawberry.extensions import QueryDepthLimiter, IgnoreContext\n\n\n@strawberry.type\nclass Book:\n    title: str\n    author: \"User\"\n\n\n@strawberry.type\nclass User:\n    name: str | None\n    favourite_books: list[Book]\n    published_books: list[Book]\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def book(self) -> Book:\n        return Book(\n            title=\"The Hitchhiker's Guide to the Strawberry Fields\",\n            author=User(favourite_books=[], published_books=[]),\n        )\n\n    @strawberry.field\n    def user(self, name: str | None = None) -> User:\n        return User(name=name, favourite_books=[], published_books=[])\n\n\ndef should_ignore(ignore: IgnoreContext):\n    return ignore.field_args.get(\"name\") == \"matt\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        QueryDepthLimiter(max_depth=2, should_ignore=should_ignore),\n    ],\n)\n\n# This query fails\nschema.execute(\"\"\"\n    query TooDeep {\n        book {\n            author {\n                publishedBooks {\n                    title\n                }\n            }\n        }\n    }\n    \"\"\")\n\n# This query succeeds because the `user` field is ignored\nschema.execute(\"\"\"\n    query NotTooDeep {\n        user(name:\"matt\") {\n            favouriteBooks {\n                author {\n                    publishedBooks {\n                        title\n                    }\n                }\n            }\n        }\n    }\n    \"\"\")\n```\n","frontmatter":{"title":"Query Depth Limiter","summary":"Add a validator to limit the query depth of GraphQL operations.","tags":"security"},"isInternal":false,"tokens":1024,"sizeBytes":4731},{"name":"sentry-tracing.md","path":"docs/extensions/sentry-tracing.md","rawUrl":"https://raw.githubusercontent.com/strawberry-graphql/strawberry/HEAD/docs/extensions/sentry-tracing.md","title":"Extensions Skill","category":"anthropic-skill","format":"markdown","content":"---\ntitle: Sentry Tracing\nsummary: Add Sentry tracing to your GraphQL server.\ntags: tracing\n---\n\n# `SentryTracingExtension`\n\n<Warning>\n\nAs of Sentry 1.32.0, Strawberry is officially supported by the Sentry SDK.\nTherefore, Strawberry's `SentryTracingExtension` has been deprecated in version\n0.210.0 and finally removed with Strawberry 0.249.0 in favor of the official\nSentry SDK integration.\n\nFor more details, please refer to the\n[documentation for the official Sentry Strawberry integration](https://docs.sentry.io/platforms/python/integrations/strawberry/).\n\n</Warning>\n\n## Filtering input coercion errors\n\nThe official Sentry integration captures all errors returned in a GraphQL\nresponse. If invalid client input should not be reported, use Sentry's\n`before_send` callback to filter `StrawberryInputCoercionError`:\n\n```python\nfrom typing import Any\n\nimport sentry_sdk\n\nfrom strawberry.exceptions import StrawberryInputCoercionError\n\n\ndef before_send(event: dict[str, Any], hint: dict[str, Any]) -> dict[str, Any] | None:\n    exc_info = hint.get(\"exc_info\")\n    error = exc_info[1] if exc_info else None\n\n    if isinstance(error, StrawberryInputCoercionError) or isinstance(\n        getattr(error, \"original_error\", None), StrawberryInputCoercionError\n    ):\n        return None\n\n    return event\n\n\nsentry_sdk.init(before_send=before_send)\n```\n\nChecking `original_error` is necessary because graphql-core wraps scalar errors\nraised while coercing variables in another `GraphQLError`. For this reason,\nSentry's `ignore_errors` option alone does not filter every input coercion\nerror.\n","frontmatter":{"title":"Sentry Tracing","summary":"Add Sentry tracing to your GraphQL server.","tags":"tracing"},"isInternal":false,"tokens":362,"sizeBytes":1587},{"name":"validation-cache.md","path":"docs/extensions/validation-cache.md","rawUrl":"https://raw.githubusercontent.com/strawberry-graphql/strawberry/HEAD/docs/extensions/validation-cache.md","title":"Extensions Skill","category":"anthropic-skill","format":"markdown","content":"---\ntitle: Validation Cache\nsummary: Add in memory caching to the validation step of query execution.\ntags: performance,caching,validation\n---\n\n# `ValidationCache`\n\nThis extension adds LRU caching to the validation step of query execution to\nimprove performance by caching the validation errors in memory.\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions import ValidationCache\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        ValidationCache(),\n    ],\n)\n```\n\n## API reference:\n\n```python\nclass ValidationCache(maxsize=128): ...\n```\n\n#### `maxsize: Optional[int] = 128`\n\nSet the maxsize of the cache. By default the cache is bounded to 128 entries,\nwith the least recently used entries evicted first. Pass an explicit\n`maxsize=None` to let the cache grow without bound; only do this when the set of\ndistinct query texts reaching the server is trusted and bounded, as an unbounded\ncache lets clients grow the server's memory indefinitely by sending unique query\ntexts.\n\nMore info: https://docs.python.org/3/library/functools.html#functools.lru_cache\n\n## More examples:\n\n<details>\n  <summary>Using maxsize</summary>\n\n```python\nimport strawberry\nfrom strawberry.extensions import ValidationCache\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        ValidationCache(maxsize=100),\n    ],\n)\n```\n\n</details>\n","frontmatter":{"title":"Validation Cache","summary":"Add in memory caching to the validation step of query execution.","tags":"performance,caching,validation"},"isInternal":false,"tokens":357,"sizeBytes":1583}],"systemPromptSnippet":"<yakaai_skills repo=\"strawberry-graphql/strawberry\">\n<!-- File: AGENTS.md (Tokens: ~765 | Category: root-instruction) -->\n# AGENTS.md\n\nStrawberry GraphQL\n\n- Docs: https://strawberry.rocks/docs\n- Repo: https://github.com/strawberry-graphql/strawberry\n\n## Setup\n\n```shell\n$ uv sync\n$ uv run pre-commit install\n```\n\nThe default uv dependency groups include both `dev` and `integrations`, so a\nplain `uv sync` installs everything needed for local development.\n\n## Commands\n\n- **Test:** `uv run pytest`\n- **Focused test:** `uv run pytest path/to/test.py -q`\n- **Type check:** `uv run mypy --config-file mypy.ini`\n- **Lint:** `uv run ruff check .`\n- **Format:** `uv run ruff format .`\n- **Check formatting:** `uv run ruff format --check .`\n- **Run all pre-commit hooks:** `uv run pre-commit run --all-files`\n\nRun focused tests while iterating, then run the relevant broader test suite.\nThe CI test matrix is defined in `noxfile.py`; list its sessions with\n`uv run nox -t tests -l`.\n\n## Engineering Principles\n\n- Write code as if we will maintain it for years. Prefer clear, cohesive\n  implementations over the quickest local patch, solve root causes, and leave\n  the surrounding code easier to understand.\n- Think about features end to end before changing them. As relevant, trace the\n  public API through schema construction and execution, sync and async paths,\n  typing, framework integrations, error behavior, backwards compatibility, and\n  performance.\n- A feature is complete when its implementation, tests, documentation, error\n  messages, and release note tell the same coherent story. Cover important edge\n  cases and the user-visible behavior, not only the happy-path implementation.\n- Before finishing, review the diff from both a user's and a maintainer's\n  perspective: does it fit Strawberry's existing design, is its behavior\n  unsurprising, and would we be happy to support it long term?\n\n## Code Style\n\n- Ruff for linting/formatting (line length 88, Python 3.11 target)\n- Keep production code fully typed. The repository's mypy configuration is not\n  globally strict, so follow the surrounding code and avoid introducing new\n  untyped definitions.\n- Decorator-based schema: `@strawberry.type`, `@strawberry.field`,\n  `@strawberry.mutation`\n- Preserve both synchronous and asynchronous execution paths unless a feature is\n  explicitly async-only.\n\n## Structure\n\n- `strawberry/` - Core library\n  - `schema/` - Schema definition/execution\n  - `types/` - GraphQL type definitions\n  - `extensions/` - Built-in extensions\n  - `django/`, `fastapi/`, `flask/`, etc. - Framework integrations\n- `tests/` - pytest suite with integration markers (`django`, `fastapi`,\n  `pydantic`, etc.)\n\n## PR Requirements\n\n- Include `RELEASE.md` file describing changes\n- Release types: patch/minor/major\n- Add tests for behavior changes and keep affected code covered\n- Update documentation when user-facing behavior changes\n\n## Release file (RELEASE.md)\n\nRelease type is one of: `patch`, `minor`, or `major` (semver). Release notes\nshould start with `This release adds ...` or `This release fixes ...` and lead\nwith the user-visible behavior.\n\nExample:\n\n```markdown\n---\nrelease type: patch\n---\n\nThis release fixes schema printing for nullable input defaults.\n\nStrawberry now preserves explicit `None` values in printed nested input\ndefaults.\n```\n\n<!-- File: CLAUDE.md (Tokens: ~5 | Category: claude-rule) -->\n@AGENTS.md\n\n<!-- File: docs/extensions/_template.md (Tokens: ~197 | Category: anthropic-skill) -->\n---\ntitle: Extension Name\nsummary: A summary of the extension.\ntags: comma,separated,list,of,tags\n---\n\n# `ExtensionName`\n\nThis extension does ...\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions import ExtensionName\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        ExtensionName(),\n    ],\n)\n```\n\n## API reference:\n\n```python\nclass ExtensionName(an_argument=None): ...\n```\n\n#### `an_argument: Optional[str] = None`\n\nDescription of the argument.\n\n## More examples:\n\n<details>\n  <summary>Using `an_argument`</summary>\n\n```python\nimport strawberry\nfrom strawberry.extensions import ValidationCache\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        ExtensionName(an_argument=\"something\"),\n    ],\n)\n```\n\n</details>\n\n<!-- File: docs/extensions/add-validation-rules.md (Tokens: ~589 | Category: anthropic-skill) -->\n---\ntitle: Add Validation Rules\nsummary: Add GraphQL validation rules.\ntags: validation,security\n---\n\n# `AddValidationRules`\n\nThis extension allows you add custom validation rules.\n\nSee\n[graphql.validation.rules.custom](https://github.com/graphql-python/graphql-core/tree/main/src/graphql/validation/rules/custom)\nfor some custom rules that can be added from GraphQl-core.\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions import AddValidationRules\nfrom graphql import ValidationRule\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nclass MyCustomRule(ValidationRule): ...\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        AddValidationRules(MyCustomRule),\n    ],\n)\n```\n\n## API reference:\n\n```python\nclass AddValidationRules(validation_rules): ...\n```\n\n#### `validation_rules: List[Type[ASTValidationRule]]`\n\nList of GraphQL validation rules.\n\n## More examples:\n\n<details>\n  <summary>Adding a custom rule</summary>\n\n```python\nimport strawberry\nfrom strawberry.extensions import AddValidationRules\nfrom graphql import ValidationRule\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nclass CustomRule(ValidationRule):\n    def enter_field(self, node, *args) -> None:\n        if node.name.value == \"example\":\n            self.report_error(GraphQLError(\"Can't query field 'example'\"))\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        AddValidationRules([CustomRule]),\n    ],\n)\n\nresult = schema.execute_sync(\"{ example }\")\n\nassert str(result.errors[0]) == \"Can't query field 'example'\"\n```\n\n</details>\n\n<details>\n  <summary>Adding the `NoDeprecatedCustomRule` from GraphQL-core</summary>\n\n```python\nimport strawberry\nfrom strawberry.extensions import AddValidationRules\nfrom graphql.validation import NoDeprecatedCustomRule\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        AddValidationRules([NoDeprecatedCustomRule]),\n    ],\n)\n```\n\n</details>\n\n<details>\n  <summary>Adding the `NoSchemaIntrospectionCustomRule` from GraphQL-core</summary>\n\n```python\nimport strawberry\nfrom strawberry.extensions import AddValidationRules\nfrom graphql.validation import NoSchemaIntrospectionCustomRule\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        AddValidationRules([NoSchemaIntrospectionCustomRule]),\n    ],\n)\n```\n\n</details>\n\n<!-- File: docs/extensions/apollo-federation-tracing.md (Tokens: ~427 | Category: anthropic-skill) -->\n---\ntitle: Apollo Federation Tracing\nsummary: Add Apollo Federation inline tracing (FTV1) to your GraphQL server.\ntags: tracing,federation\n---\n\n# `ApolloFederationTracingExtension`\n\nThis extension adds support for\n[Apollo Federation inline tracing (FTV1)](https://www.apollographql.com/docs/federation/).\nWhen a request includes the `apollo-federation-include-trace: ftv1` header, the\nextension records per-resolver timing and includes the trace in the response as\na base64-encoded protobuf under `extensions.ftv1`.\n\n<Warning>\n\nAny client can send the `apollo-federation-include-trace: ftv1` header unless\nyou restrict it. Tracing payloads expose resolver timing details, so make sure\nonly a trusted Apollo Gateway (or other internal traffic) can request traces —\nfor example by enforcing authentication, network policy, or stripping the header\nfrom public requests at the edge.\n\n</Warning>\n\n<Note>\n\nMake sure you have `protobuf` installed before using this extension.\n\n```shell\npip install 'strawberry-graphql[apollo-federation]'\n```\n\n</Note>\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions.tracing import ApolloFederationTracingExtension\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        ApolloFederationTracingExtension,\n    ],\n)\n```\n\n<Note>\n\nIf you are not running in an Async context then you'll need to use the sync\nversion:\n\n```python\nimport strawberry\nfrom strawberry.extensions.tracing import ApolloFederationTracingExtensionSync\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        ApolloFederationTracingExtensionSync,\n    ],\n)\n```\n\n</Note>\n\n## API reference:\n\n_No arguments_\n\n<!-- File: docs/extensions/apollo-tracing.md (Tokens: ~254 | Category: anthropic-skill) -->\n---\ntitle: Apollo Tracing\nsummary: Add Apollo tracing to your GraphQL server.\ntags: tracing\n---\n\n# `ApolloTracingExtension`\n\nThis extension adds\n[tracing information](https://github.com/apollographql/apollo-tracing) to your\nresponse for [Apollo Engine](https://www.apollographql.com/platform/).\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions.tracing import ApolloTracingExtension\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        ApolloTracingExtension,\n    ],\n)\n```\n\n<Note>\n\nIf you are not running in an Async context then you'll need to use the sync\nversion:\n\n```python\nimport strawberry\nfrom strawberry.extensions.tracing import ApolloTracingExtensionSync\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        ApolloTracingExtensionSync,\n    ],\n)\n```\n\n</Note>\n\n## API reference:\n\n_No arguments_\n\n<!-- File: docs/extensions/datadog.md (Tokens: ~417 | Category: anthropic-skill) -->\n---\ntitle: Datadog\nsummary: Add Datadog tracing to your GraphQL server.\ntags: tracing\n---\n\n# `DatadogExtension`\n\nThis extension adds support for tracing with Datadog.\n\n<Note>\n\nMake sure you have `ddtrace` installed before using this extension.\n\n```shell\npip install ddtrace\n```\n\n</Note>\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions.tracing import DatadogTracingExtension\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        DatadogTracingExtension,\n    ],\n)\n```\n\n<Note>\n\nIf you are not running in an Async context then you'll need to use the sync\nversion:\n\n```python\nimport strawberry\nfrom strawberry.extensions.tracing import DatadogTracingExtensionSync\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        DatadogTracingExtensionSync,\n    ],\n)\n```\n\n</Note>\n\n## API reference:\n\n_No arguments_\n\n## Extending the extension\n\n### Overriding the `create_span` method\n\nYou can customize any of the spans or add tags to them by overriding the\n`create_span` method.\n\nExample:\n\n```python\nfrom ddtrace import Span\n\nfrom strawberry.extensions import LifecycleStep\nfrom strawberry.extensions.tracing import DatadogTracingExtension\n\n\nclass DataDogExtension(DatadogTracingExtension):\n    def create_span(\n        self,\n        lifecycle_step: LifecycleStep,\n        name: str,\n        **kwargs,\n    ) -> Span:\n        span = super().create_span(lifecycle_step, name, **kwargs)\n        if lifecycle_step == LifecycleStep.OPERATION:\n            span.set_tag(\"graphql.query\", self.execution_context.query)\n        return span\n```\n\n<!-- File: docs/extensions/disable-introspection.md (Tokens: ~407 | Category: anthropic-skill) -->\n---\ntitle: Disable Introspection\nsummary: Disable standard GraphQL introspection queries.\ntags: security,validation\n---\n\n# `DisableIntrospection`\n\nThe `DisableIntrospection` extension disables standard GraphQL introspection\nqueries for the schema. It blocks fields such as `__schema` and `__type`.\n\nThis can be useful to prevent clients from discovering unreleased or internal\nfeatures of the API through GraphQL introspection.\n\n<Warning>\n\n`DisableIntrospection` does not block non-introspection fields that may expose\nschema information. For example, Apollo Federation schemas expose `_service` and\nits `sdl` field so gateways and routers can compose federated services. If you\nuse `strawberry.federation.Schema`, protect federated endpoints from untrusted\nclients with your own authentication, authorization, or network controls.\n\n</Warning>\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions import DisableIntrospection\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        DisableIntrospection(),\n    ],\n)\n```\n\n## API reference:\n\n_No arguments_\n\n## Example query:\n\nRunning any query including the introspection field `__schema` will result in an\nerror. Consider the following query, for example:\n\n```graphql\nquery {\n  __schema {\n    __typename\n  }\n}\n```\n\nRunning it against the schema with the `DisableIntrospection` extension enabled\nwill result in an error response indicating that introspection has been\ndisabled:\n\n```json\n{\n  \"data\": null,\n  \"errors\": [\n    {\n      \"message\": \"GraphQL introspection has been disabled, but the requested query contained the field '__schema'.\",\n      \"locations\": [\n        {\n          \"line\": 2,\n          \"column\": 3\n        }\n      ]\n    }\n  ]\n}\n```\n\n<!-- File: docs/extensions/disable-validation.md (Tokens: ~190 | Category: anthropic-skill) -->\n---\ntitle: Disable Validation\nsummary: Disable all query validation.\ntags: performance,validation\n---\n\n# `DisableValidation`\n\nThis extensions disables all query validation. This can be useful to improve\nperformance in some specific cases, for example when dealing with internal APIs\nwhere queries can be trusted.\n\n<Warning>\n\nOnly do this if you know what you are doing! Disabling validation breaks the\nsafety of having typed schema. If you are trying to improve performance you\nmight want to consider using the [ValidationCache](./validation-cache) instead.\n\n</Warning>\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions import DisableValidation\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        DisableValidation(),\n    ],\n)\n```\n\n## API reference:\n\n_No arguments_\n\n<!-- File: docs/extensions/input-mutation.md (Tokens: ~348 | Category: anthropic-skill) -->\n---\ntitle: Input Mutation Extension\nsummary: Automatically create Input types for mutations\ntags: QoL\n---\n\n# `InputMutationExtension`\n\nThe pattern of defining a mutation that receives a single\n[input type](../types/input-types.md) argument called `input` is a common\npractice in GraphQL. It helps to keep the mutation signatures clean and makes it\neasier to manage complex mutations with multiple arguments.\n\nThe `InputMutationExtension` is a Strawberry field extension that allows you to\ndefine a mutation with multiple arguments without having to manually create an\ninput type for it. Instead, it generates an input type based on the arguments of\nthe mutation resolver.\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.field_extensions import InputMutationExtension\n\n\n@strawberry.type\nclass User:\n    username: str\n\n\n@strawberry.type\nclass Query:\n    hello: str\n\n\n@strawberry.type\nclass Mutation:\n    @strawberry.mutation(extensions=[InputMutationExtension()])\n    def register_user(\n        self,\n        username: str,\n        password: str,\n    ) -> User:\n        user = User(username=username)\n        # maybe persist the user in a database\n        return user\n\n\nschema = strawberry.Schema(query=Query, mutation=Mutation)\n```\n\nThe Strawberry schema above and the usage of the `InputMutationExtension` will\nresult in the following GraphQL schema:\n\n```graphql\ntype User {\n  username: String!\n}\n\ninput RegisterUserInput {\n  username: String!\n  password: String!\n}\n\ntype Mutation {\n  registerUser(input: RegisterUserInput!): User!\n}\n\ntype Query {\n  hello: String!\n}\n```\n\n## API reference:\n\n_No arguments_\n\n<!-- File: docs/extensions/mask-errors.md (Tokens: ~510 | Category: anthropic-skill) -->\n---\ntitle: Mask Errors\nsummary: Hide error messages from the client.\ntags: security\n---\n\n# `MaskErrors`\n\nThis extension hides error messages from the client to prevent exposing\nsensitive details. By default it masks all errors raised in any field resolver.\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions import MaskErrors\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hidden_error(self) -> str:\n        raise KeyError(\"This error will not be visible\")\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        MaskErrors(),\n    ],\n)\n```\n\n## API reference:\n\n```python\nclass MaskErrors(\n    should_mask_error=default_should_mask_error, error_message=\"Unexpected error.\"\n): ...\n```\n\n#### `should_mask_error: Callable[[GraphQLError], bool] = default_should_mask_error`\n\nPredicate function to check if a GraphQLError should be masked or not. Use the\n`original_error` attribute to access the original error that was raised in the\nresolver.\n\n<Note>\n\nThe `default_should_mask_error` function always returns `True`.\n\n</Note>\n\n#### `error_message: str = \"Unexpected error.\"`\n\nThe error message to display to the client when there is an error.\n\n## More examples:\n\n<details>\n  <summary>Hide some exceptions</summary>\n\n```python\nimport strawberry\nfrom strawberry.extensions import MaskErrors\nfrom graphql.error import GraphQLError\n\n\nclass VisibleError(Exception):\n    pass\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def visible_error(self) -> str:\n        raise VisibleError(\"This error will be visible\")\n\n\ndef should_mask_error(error: GraphQLError) -> bool:\n    original_error = error.original_error\n    if original_error and isinstance(original_error, VisibleError):\n        return False\n\n    return True\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        MaskErrors(should_mask_error=should_mask_error),\n    ],\n)\n```\n\n</details>\n\n<details>\n  <summary>Change error message</summary>\n\n```python\nimport strawberry\nfrom strawberry.extensions import MaskErrors\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hidden_error(self) -> str:\n        raise KeyError(\"This error will not be visible\")\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        MaskErrors(error_message=\"Oh no! An error occured. Very sorry about that.\"),\n    ],\n)\n```\n\n</details>\n\n<!-- File: docs/extensions/max-aliases-limiter.md (Tokens: ~173 | Category: anthropic-skill) -->\n---\ntitle: Max Aliases Limiter\nsummary:\n  Add a validator to limit the maximum number of aliases in a GraphQL document.\ntags: security\n---\n\n# `MaxAliasesLimiter`\n\nThis extension adds a validator to limit the maximum number of aliases in a\nGraphQL document.\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions import MaxAliasesLimiter\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        MaxAliasesLimiter(max_alias_count=15),\n    ],\n)\n```\n\n## API reference:\n\n```python\nclass MaxAliasesLimiter(max_alias_count): ...\n```\n\n#### `max_alias_count: int`\n\nThe maximum allowed number of aliases in a GraphQL document.\n\n<!-- File: docs/extensions/max-tokens-limiter.md (Tokens: ~237 | Category: anthropic-skill) -->\n---\ntitle: Max Tokens Limiter\nsummary:\n  Add a validator to limit the maximum number of tokens in a GraphQL document.\ntags: security\n---\n\n# `MaxTokensLimiter`\n\nThis extension adds a validator to limit the maximum number of tokens in a\nGraphQL document sent to the server.\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions import MaxTokensLimiter\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        MaxTokensLimiter(max_token_count=1000),\n    ],\n)\n```\n\nWith the above configuration, if a client sends a query with more than 1000\ntokens, the server will respond with an error message.\n\n## API reference:\n\n```python\nclass MaxTokensLimiter(max_token_count): ...\n```\n\n#### `max_token_count: int`\n\nThe maximum allowed number of tokens in a GraphQL document.\n\nThe following things are counted as tokens:\n\n- various brackets: \"{\", \"}\", \"(\", \")\"\n- colon :\n- words\n\nNot counted:\n\n- quotes\n\n<!-- File: docs/extensions/opentelemetry.md (Tokens: ~635 | Category: anthropic-skill) -->\n---\ntitle: Open Telemetry\nsummary: Add Open Telemetry tracing to your GraphQL server.\ntags: tracing\n---\n\n# `OpenTelemetryExtension`\n\nThis extension adds tracing information that is compatible with\n[Open Telemetry](https://opentelemetry.io/).\n\n<Note>\n\nThis extension requires additional requirements:\n\n```shell\npip install 'strawberry-graphql[opentelemetry]'\n```\n\n</Note>\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions.tracing import OpenTelemetryExtension\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        OpenTelemetryExtension,\n    ],\n)\n```\n\n<Note>\n\nIf you are not running in an Async context then you'll need to use the sync\nversion:\n\n```python\nimport strawberry\nfrom strawberry.extensions.tracing import OpenTelemetryExtensionSync\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        OpenTelemetryExtensionSync,\n    ],\n)\n```\n\n</Note>\n\n## API reference:\n\n```python\nclass OpenTelemetryExtension(arg_filter=None): ...\n```\n\n#### `arg_filter: Optional[ArgFilter]`\n\nA function to filter certain field arguments from being included in the tracing\ndata.\n\n```python\nArgFilter = Callable[[Dict[str, Any], GraphQLResolveInfo], Dict[str, Any]]\n```\n\n## More examples:\n\n<details>\n  <summary>Using `arg_filter`</summary>\n\n```python\nimport strawberry\nfrom strawberry.extensions.tracing import OpenTelemetryExtensionSync\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\ndef arg_filter(kwargs, info):\n    filtered_kwargs = {}\n    for name, value in kwargs.items():\n        # Never include any arguments called \"password\"\n        if name == \"password\":\n            continue\n        filtered_kwargs[name] = value\n\n    return filtered_kwargs\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        OpenTelemetryExtensionSync(\n            arg_filter=arg_filter,\n        ),\n    ],\n)\n```\n\n</details>\n\n<details>\n  <summary>Using `tracer_provider`</summary>\n\n```python\nimport strawberry\nfrom opentelemetry.trace import TracerProvider\nfrom strawberry.extensions.tracing import OpenTelemetryExtension\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nclass MyTracerProvider(TracerProvider):\n    def get_tracer(self, name, version=None, schema_url=None):\n        return super().get_tracer(name, version, schema_url)\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        OpenTelemetryExtension(\n            tracer_provider=MyTracerProvider(),\n        ),\n    ],\n)\n```\n\n</details>\n\n<!-- File: docs/extensions/parser-cache.md (Tokens: ~357 | Category: anthropic-skill) -->\n---\ntitle: Parser Cache\nsummary: Add in memory caching to the parsing step of query execution.\ntags: performance,caching,parsing\n---\n\n# `ParserCache`\n\nThis extension adds LRU caching to the parsing step of query execution to\nimprove performance by caching the parsed result in memory.\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions import ParserCache\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        ParserCache(),\n    ],\n)\n```\n\n## API reference:\n\n```python\nclass ParserCache(maxsize=128): ...\n```\n\n#### `maxsize: Optional[int] = 128`\n\nSet the maxsize of the cache. By default the cache is bounded to 128 entries,\nwith the least recently used entries evicted first. Pass an explicit\n`maxsize=None` to let the cache grow without bound; only do this when the set of\ndistinct query texts reaching the server is trusted and bounded, as an unbounded\ncache lets clients grow the server's memory indefinitely by sending unique query\ntexts.\n\nMore info: https://docs.python.org/3/library/functools.html#functools.lru_cache\n\n## More examples:\n\n<details>\n  <summary>Using maxsize</summary>\n\n```python\nimport strawberry\nfrom strawberry.extensions import ParserCache\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        ParserCache(maxsize=100),\n    ],\n)\n```\n\n</details>\n\n<!-- File: docs/extensions/pydantic_error_extension.md (Tokens: ~268 | Category: anthropic-skill) -->\n---\ntitle: Pydantic Error Extension\nsummary:\n  Formats Pydantic validation errors into structured GraphQL error extensions.\ntags: pydantic,validation,errors,graphql,extensions\n---\n\n# `PydanticErrorExtension`\n\nThis extension detects Pydantic validation errors during GraphQL execution and\nformats them into structured `validation_errors` under the `extensions` field of\nGraphQL errors.\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions import PydanticErrorExtension\n\n\n@strawberry.type\nclass Mutation:\n    @strawberry.mutation\n    def create_user(self, email: str) -> str:\n        return email\n\n\nschema = strawberry.Schema(\n    mutation=Mutation,\n    extensions=[\n        PydanticErrorExtension(),\n    ],\n)\n```\n\n## API reference:\n\n```python\nclass PydanticErrorExtension: ...\n```\n\nThis extension does not require any arguments.\n\n## More examples:\n\n<details>\n  <summary>Example validation error output</summary>\n\n```json\n{\n  \"errors\": [\n    {\n      \"message\": \"Validation error\",\n      \"extensions\": {\n        \"validation_errors\": [\n          {\n            \"field\": \"email\",\n            \"message\": \"value is not a valid email\"\n          }\n        ]\n      }\n    }\n  ]\n}\n```\n\n</details>\n\n<!-- File: docs/extensions/pyinstrument.md (Tokens: ~164 | Category: anthropic-skill) -->\n---\ntitle: PyInstrument\nsummary: Easily Instrument your Schema\ntags: instrumentation,profiling\n---\n\n# `PyInstrument`\n\nThis extension allows you to instrument your schema and inspect the call stack.\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions import pyinstrument\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        pyinstrument.PyInstrument(report_path=\"pyinstrument.html\"),\n    ],\n)\n```\n\n## API reference:\n\n```python\nclass PyInstrument(report_Path=Path(\"pyinstrument.html\")): ...\n```\n\n#### `report_path: Path = Path(\"pyinstrument.html\")`\n\nPath to write the HTML PyInstrument report\n\n<!-- File: docs/extensions/query-depth-limiter.md (Tokens: ~1024 | Category: anthropic-skill) -->\n---\ntitle: Query Depth Limiter\nsummary: Add a validator to limit the query depth of GraphQL operations.\ntags: security\n---\n\n# `QueryDepthLimiter`\n\nThis extension adds a validator to limit the query depth of GraphQL operations.\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions import QueryDepthLimiter\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        QueryDepthLimiter(max_depth=10),\n    ],\n)\n```\n\n## API reference:\n\n```python\nclass QueryDepthLimiter(max_depth, callback=None, should_ignore=None): ...\n```\n\n#### `max_depth: int`\n\nThe maximum allowed depth for any operation in a GraphQL document.\n\n#### `callback: Optional[Callable[[Dict[str, int]], None]`\n\nCalled each time validation runs. Receives a dictionary which is a map of the\ndepths for each operation.\n\n#### `should_ignore: Optional[Callable[[IgnoreContext], bool]]`\n\nCalled at each field to determine whether the field should be ignored or not.\nMust be implemented by the user and returns `True` if the field should be\nignored and `False` otherwise.\n\nThe `IgnoreContext` class has the following attributes:\n\n- `field_name` of type `str`: the name of the field to be compared against\n- `field_args` of type\n  `strawberry.extensions.query_depth_limiter.FieldArgumentsType`: the arguments\n  of the field to be compared against\n- `query` of type `graphql.language.Node`: the query string\n- `context` of type `graphql.validation.ValidationContext`: the context passed\n  to the query\n\nThis argument is injected, regardless of name, by the `QueryDepthLimiter` class\nand should not be passed by the user.\n\nInstead, the user should write business logic to determine whether a field\nshould be ignored or not by the attributes of the `IgnoreContext` class.\n\n## Example with field_name:\n\n```python\nimport strawberry\nfrom strawberry.extensions import QueryDepthLimiter, IgnoreContext\n\n\n@strawberry.type\nclass Book:\n    title: str\n    author: \"User\"\n\n\n@strawberry.type\nclass User:\n    favourite_books: list[Book]\n    published_books: list[Book]\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def book(self) -> Book:\n        return Book(\n            title=\"The Hitchhiker's Guide to the Strawberry Fields\",\n            author=User(favourite_books=[], published_books=[]),\n        )\n\n    @strawberry.field\n    def user(self) -> User:\n        return User(favourite_books=[], published_books=[])\n\n\ndef should_ignore(ignore: IgnoreContext):\n    return ignore.field_name == \"user\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        QueryDepthLimiter(max_depth=2, should_ignore=should_ignore),\n    ],\n)\n\n# This query fails\nschema.execute(\"\"\"\n    query TooDeep {\n        book {\n            author {\n                publishedBooks {\n                    title\n                }\n            }\n        }\n    }\n    \"\"\")\n\n# This query succeeds because the `user` field is ignored\nschema.execute(\"\"\"\n    query NotTooDeep {\n        user {\n            favouriteBooks {\n                author {\n                    publishedBooks {\n                        title\n                    }\n                }\n            }\n        }\n    }\n    \"\"\")\n```\n\n## Example with field_args:\n\n```python\nimport strawberry\nfrom strawberry.extensions import QueryDepthLimiter, IgnoreContext\n\n\n@strawberry.type\nclass Book:\n    title: str\n    author: \"User\"\n\n\n@strawberry.type\nclass User:\n    name: str | None\n    favourite_books: list[Book]\n    published_books: list[Book]\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def book(self) -> Book:\n        return Book(\n            title=\"The Hitchhiker's Guide to the Strawberry Fields\",\n            author=User(favourite_books=[], published_books=[]),\n        )\n\n    @strawberry.field\n    def user(self, name: str | None = None) -> User:\n        return User(name=name, favourite_books=[], published_books=[])\n\n\ndef should_ignore(ignore: IgnoreContext):\n    return ignore.field_args.get(\"name\") == \"matt\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        QueryDepthLimiter(max_depth=2, should_ignore=should_ignore),\n    ],\n)\n\n# This query fails\nschema.execute(\"\"\"\n    query TooDeep {\n        book {\n            author {\n                publishedBooks {\n                    title\n                }\n            }\n        }\n    }\n    \"\"\")\n\n# This query succeeds because the `user` field is ignored\nschema.execute(\"\"\"\n    query NotTooDeep {\n        user(name:\"matt\") {\n            favouriteBooks {\n                author {\n                    publishedBooks {\n                        title\n                    }\n                }\n            }\n        }\n    }\n    \"\"\")\n```\n\n<!-- File: docs/extensions/sentry-tracing.md (Tokens: ~362 | Category: anthropic-skill) -->\n---\ntitle: Sentry Tracing\nsummary: Add Sentry tracing to your GraphQL server.\ntags: tracing\n---\n\n# `SentryTracingExtension`\n\n<Warning>\n\nAs of Sentry 1.32.0, Strawberry is officially supported by the Sentry SDK.\nTherefore, Strawberry's `SentryTracingExtension` has been deprecated in version\n0.210.0 and finally removed with Strawberry 0.249.0 in favor of the official\nSentry SDK integration.\n\nFor more details, please refer to the\n[documentation for the official Sentry Strawberry integration](https://docs.sentry.io/platforms/python/integrations/strawberry/).\n\n</Warning>\n\n## Filtering input coercion errors\n\nThe official Sentry integration captures all errors returned in a GraphQL\nresponse. If invalid client input should not be reported, use Sentry's\n`before_send` callback to filter `StrawberryInputCoercionError`:\n\n```python\nfrom typing import Any\n\nimport sentry_sdk\n\nfrom strawberry.exceptions import StrawberryInputCoercionError\n\n\ndef before_send(event: dict[str, Any], hint: dict[str, Any]) -> dict[str, Any] | None:\n    exc_info = hint.get(\"exc_info\")\n    error = exc_info[1] if exc_info else None\n\n    if isinstance(error, StrawberryInputCoercionError) or isinstance(\n        getattr(error, \"original_error\", None), StrawberryInputCoercionError\n    ):\n        return None\n\n    return event\n\n\nsentry_sdk.init(before_send=before_send)\n```\n\nChecking `original_error` is necessary because graphql-core wraps scalar errors\nraised while coercing variables in another `GraphQLError`. For this reason,\nSentry's `ignore_errors` option alone does not filter every input coercion\nerror.\n\n<!-- File: docs/extensions/validation-cache.md (Tokens: ~357 | Category: anthropic-skill) -->\n---\ntitle: Validation Cache\nsummary: Add in memory caching to the validation step of query execution.\ntags: performance,caching,validation\n---\n\n# `ValidationCache`\n\nThis extension adds LRU caching to the validation step of query execution to\nimprove performance by caching the validation errors in memory.\n\n## Usage example:\n\n```python\nimport strawberry\nfrom strawberry.extensions import ValidationCache\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        ValidationCache(),\n    ],\n)\n```\n\n## API reference:\n\n```python\nclass ValidationCache(maxsize=128): ...\n```\n\n#### `maxsize: Optional[int] = 128`\n\nSet the maxsize of the cache. By default the cache is bounded to 128 entries,\nwith the least recently used entries evicted first. Pass an explicit\n`maxsize=None` to let the cache grow without bound; only do this when the set of\ndistinct query texts reaching the server is trusted and bounded, as an unbounded\ncache lets clients grow the server's memory indefinitely by sending unique query\ntexts.\n\nMore info: https://docs.python.org/3/library/functools.html#functools.lru_cache\n\n## More examples:\n\n<details>\n  <summary>Using maxsize</summary>\n\n```python\nimport strawberry\nfrom strawberry.extensions import ValidationCache\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def hello(self) -> str:\n        return \"Hello, world!\"\n\n\nschema = strawberry.Schema(\n    Query,\n    extensions=[\n        ValidationCache(maxsize=100),\n    ],\n)\n```\n\n</details>\n</yakaai_skills>"}