The response has been limited to 50k tokens of the smallest files in the repo. You can remove this limitation by removing the max tokens filter.
├── .alexignore
├── .alexrc
├── .codecov.yml
├── .coveragerc
├── .devcontainer
    ├── Dockerfile
    ├── devcontainer.json
    └── post-install.sh
├── .dockerignore
├── .editorconfig
├── .github
    ├── bot-action
    │   ├── Dockerfile
    │   ├── action.yml
    │   └── main.py
    ├── dependabot.yml
    ├── logo.png
    ├── pyproject.toml
    ├── release-check-action
    │   ├── Dockerfile
    │   ├── action.yml
    │   ├── check.py
    │   ├── config.py
    │   └── release.py
    └── workflows
    │   ├── codeflash.yaml
    │   ├── codeql-analysis.yml
    │   ├── federation-compatibility.yml
    │   ├── invite-contributors.yml
    │   ├── issue-manager.yml
    │   ├── ok-to-preview.yml
    │   ├── pre-release-pr.yml
    │   ├── release-check.yml
    │   ├── release.yml
    │   ├── slash-commands.yml
    │   └── test.yml
├── .gitignore
├── .gitpod.yml
├── .pre-commit-config.yaml
├── .prettierrc
├── CHANGELOG.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── docs
    ├── README.md
    ├── _test.md
    ├── breaking-changes.md
    ├── breaking-changes
    │   ├── 0.146.0.md
    │   ├── 0.159.0.md
    │   ├── 0.169.0.md
    │   ├── 0.180.0.md
    │   ├── 0.213.0.md
    │   ├── 0.217.0.md
    │   ├── 0.233.0.md
    │   ├── 0.236.0.md
    │   ├── 0.240.0.md
    │   ├── 0.243.0.md
    │   ├── 0.249.0.md
    │   ├── 0.251.0.md
    │   └── 0.268.0.md
    ├── cli
    │   └── locate-definition.md
    ├── codegen
    │   ├── query-codegen.md
    │   └── schema-codegen.md
    ├── concepts
    │   ├── async.md
    │   └── typings.md
    ├── editors
    │   ├── mypy.md
    │   ├── pylance.png
    │   └── vscode.md
    ├── errors.md
    ├── errors
    │   ├── _template.md
    │   ├── conflicting-arguments.md
    │   ├── duplicated-type-name.md
    │   ├── invalid-argument-type.md
    │   ├── invalid-superclass-interface.md
    │   ├── invalid-type-for-union-merge.md
    │   ├── invalid-union-type.md
    │   ├── missing-arguments-annotations.md
    │   ├── missing-field-annotation.md
    │   ├── missing-return-annotation.md
    │   ├── node-id-annotation.md
    │   ├── object-is-not-an-enum.md
    │   ├── object-is-not-class.md
    │   ├── permission-fail-silently-requires-optional.md
    │   ├── private-strawberry-field.md
    │   ├── relay-wrong-annotation.md
    │   ├── relay-wrong-resolver-annotation.md
    │   ├── scalar-already-registered.md
    │   ├── unresolved-field-type.md
    │   └── unsupported-type.md
    ├── extensions.md
    ├── extensions
    │   ├── _template.md
    │   ├── add-validation-rules.md
    │   ├── apollo-tracing.md
    │   ├── datadog.md
    │   ├── disable-introspection.md
    │   ├── disable-validation.md
    │   ├── input-mutation.md
    │   ├── mask-errors.md
    │   ├── max-aliases-limiter.md
    │   ├── max-tokens-limiter.md
    │   ├── opentelemetry.md
    │   ├── parser-cache.md
    │   ├── pyinstrument.md
    │   ├── query-depth-limiter.md
    │   ├── sentry-tracing.md
    │   └── validation-cache.md
    ├── faq.md
    ├── federation
    │   ├── custom_directives.md
    │   ├── entities.md
    │   ├── entity-interfaces.md
    │   └── introduction.md
    ├── general
    │   ├── multipart-subscriptions.md
    │   ├── mutations.md
    │   ├── queries.md
    │   ├── schema-basics.md
    │   ├── subscriptions.md
    │   └── upgrades.md
    ├── guides
    │   ├── accessing-parent-data.md
    │   ├── authentication.md
    │   ├── convert-to-dictionary.md
    │   ├── custom-extensions.md
    │   ├── dataloaders.md
    │   ├── errors.md
    │   ├── federation-v1.md
    │   ├── federation.md
    │   ├── field-extensions.md
    │   ├── file-upload.md
    │   ├── pagination
    │   │   ├── connections.md
    │   │   ├── cursor-based.md
    │   │   ├── offset-based.md
    │   │   └── overview.md
    │   ├── permissions.md
    │   ├── relay.md
    │   ├── schema-export.md
    │   ├── server.md
    │   └── tools.md
    ├── images
    │   ├── index-query-example.png
    │   ├── index-server.png
    │   └── subscriptions-count-websocket.png
    ├── index.md
    ├── integrations
    │   ├── aiohttp.md
    │   ├── asgi.md
    │   ├── chalice.md
    │   ├── channels.md
    │   ├── creating-an-integration.md
    │   ├── django.md
    │   ├── fastapi.md
    │   ├── flask.md
    │   ├── index.md
    │   ├── litestar.md
    │   ├── pydantic.md
    │   ├── quart.md
    │   ├── sanic.md
    │   └── starlette.md
    ├── operations
    │   ├── deployment.md
    │   ├── testing.md
    │   └── tracing.md
    └── types
    │   ├── enums.md
    │   ├── exceptions.md
    │   ├── generics.md
    │   ├── input-types.md
    │   ├── interfaces.md
    │   ├── lazy.md
    │   ├── object-types.md
    │   ├── operation-directives.md
    │   ├── private.md
    │   ├── resolvers.md
    │   ├── scalars.md
    │   ├── schema-configurations.md
    │   ├── schema-directives.md
    │   ├── schema.md
    │   └── union.md
├── federation-compatibility
    ├── Dockerfile
    ├── docker-compose.yml
    └── schema.py
├── mypy.ini
├── noxfile.py
├── poetry.lock
├── pyproject.toml
├── setup.py
├── strawberry
    ├── __init__.py
    ├── __main__.py
    ├── aiohttp
    │   ├── __init__.py
    │   ├── test
    │   │   ├── __init__.py
    │   │   └── client.py
    │   └── views.py
    ├── annotation.py
    ├── asgi
    │   ├── __init__.py
    │   └── test
    │   │   ├── __init__.py
    │   │   └── client.py
    ├── chalice
    │   ├── __init__.py
    │   └── views.py
    ├── channels
    │   ├── __init__.py
    │   ├── handlers
    │   │   ├── __init__.py
    │   │   ├── base.py
    │   │   ├── http_handler.py
    │   │   └── ws_handler.py
    │   ├── router.py
    │   └── testing.py
    ├── cli
    │   ├── __init__.py
    │   ├── app.py
    │   ├── commands
    │   │   ├── __init__.py
    │   │   ├── codegen.py
    │   │   ├── export_schema.py
    │   │   ├── locate_definition.py
    │   │   ├── schema_codegen.py
    │   │   ├── server.py
    │   │   └── upgrade
    │   │   │   ├── __init__.py
    │   │   │   ├── _fake_progress.py
    │   │   │   └── _run_codemod.py
    │   ├── constants.py
    │   ├── debug_server.py
    │   └── utils
    │   │   ├── __init__.py
    │   │   └── load_schema.py
    ├── codegen
    │   ├── __init__.py
    │   ├── exceptions.py
    │   ├── plugins
    │   │   ├── __init__.py
    │   │   ├── print_operation.py
    │   │   ├── python.py
    │   │   └── typescript.py
    │   ├── query_codegen.py
    │   └── types.py
    ├── codemods
    │   ├── __init__.py
    │   ├── annotated_unions.py
    │   └── update_imports.py
    ├── dataloader.py
    ├── directive.py
    ├── django
    │   ├── __init__.py
    │   ├── apps.py
    │   ├── context.py
    │   ├── test
    │   │   ├── __init__.py
    │   │   └── client.py
    │   └── views.py
    ├── exceptions
    │   ├── __init__.py
    │   ├── conflicting_arguments.py
    │   ├── duplicated_type_name.py
    │   ├── exception.py
    │   ├── exception_source.py
    │   ├── handler.py
    │   ├── invalid_argument_type.py
    │   ├── invalid_superclass_interface.py
    │   ├── invalid_union_type.py
    │   ├── missing_arguments_annotations.py
    │   ├── missing_dependencies.py
    │   ├── missing_field_annotation.py
    │   ├── missing_return_annotation.py
    │   ├── object_is_not_a_class.py
    │   ├── object_is_not_an_enum.py
    │   ├── permission_fail_silently_requires_optional.py
    │   ├── private_strawberry_field.py
    │   ├── scalar_already_registered.py
    │   ├── syntax.py
    │   ├── unresolved_field_type.py
    │   └── utils
    │   │   ├── __init__.py
    │   │   └── source_finder.py
    ├── experimental
    │   ├── __init__.py
    │   └── pydantic
    │   │   ├── __init__.py
    │   │   ├── _compat.py
    │   │   ├── conversion.py
    │   │   ├── conversion_types.py
    │   │   ├── error_type.py
    │   │   ├── exceptions.py
    │   │   ├── fields.py
    │   │   ├── object_type.py
    │   │   └── utils.py
    ├── ext
    │   ├── LICENSE
    │   ├── __init__.py
    │   ├── dataclasses
    │   │   ├── LICENSE
    │   │   ├── README.md
    │   │   ├── __init__.py
    │   │   └── dataclasses.py
    │   └── mypy_plugin.py
    ├── extensions
    │   ├── __init__.py
    │   ├── add_validation_rules.py
    │   ├── base_extension.py
    │   ├── context.py
    │   ├── directives.py
    │   ├── disable_introspection.py
    │   ├── disable_validation.py
    │   ├── field_extension.py
    │   ├── mask_errors.py
    │   ├── max_aliases.py
    │   ├── max_tokens.py
    │   ├── parser_cache.py
    │   ├── pyinstrument.py
    │   ├── query_depth_limiter.py
    │   ├── runner.py
    │   ├── tracing
    │   │   ├── __init__.py
    │   │   ├── apollo.py
    │   │   ├── datadog.py
    │   │   ├── opentelemetry.py
    │   │   └── utils.py
    │   ├── utils.py
    │   └── validation_cache.py
    ├── fastapi
    │   ├── __init__.py
    │   ├── context.py
    │   └── router.py
    ├── federation
    │   ├── __init__.py
    │   ├── argument.py
    │   ├── enum.py
    │   ├── field.py
    │   ├── mutation.py
    │   ├── object_type.py
    │   ├── scalar.py
    │   ├── schema.py
    │   ├── schema_directive.py
    │   ├── schema_directives.py
    │   ├── types.py
    │   └── union.py
    ├── field_extensions
    │   ├── __init__.py
    │   └── input_mutation.py
    ├── file_uploads
    │   ├── __init__.py
    │   ├── scalars.py
    │   └── utils.py
    ├── flask
    │   ├── __init__.py
    │   └── views.py
    ├── http
    │   ├── __init__.py
    │   ├── async_base_view.py
    │   ├── base.py
    │   ├── exceptions.py
    │   ├── ides.py
    │   ├── parse_content_type.py
    │   ├── sync_base_view.py
    │   ├── temporal_response.py
    │   ├── types.py
    │   └── typevars.py
    ├── litestar
    │   ├── __init__.py
    │   └── controller.py
    ├── parent.py
    ├── permission.py
    ├── printer
    │   ├── __init__.py
    │   ├── ast_from_value.py
    │   └── printer.py
    ├── py.typed
    ├── quart
    │   ├── __init__.py
    │   └── views.py
    ├── relay
    │   ├── __init__.py
    │   ├── exceptions.py
    │   ├── fields.py
    │   ├── types.py
    │   └── utils.py
    ├── resolvers.py
    ├── sanic
    │   ├── __init__.py
    │   ├── context.py
    │   ├── utils.py
    │   └── views.py
    ├── scalars.py
    ├── schema
    │   ├── __init__.py
    │   ├── base.py
    │   ├── compat.py
    │   ├── config.py
    │   ├── exceptions.py
    │   ├── name_converter.py
    │   ├── schema.py
    │   ├── schema_converter.py
    │   ├── types
    │   │   ├── __init__.py
    │   │   ├── base_scalars.py
    │   │   ├── concrete_type.py
    │   │   └── scalar.py
    │   └── validation_rules
    │   │   ├── __init__.py
    │   │   └── one_of.py
    ├── schema_codegen
    │   └── __init__.py
    ├── schema_directive.py
    ├── schema_directives.py
    ├── static
    │   ├── apollo-sandbox.html
    │   ├── graphiql.html
    │   └── pathfinder.html
    ├── subscriptions
    │   ├── __init__.py
    │   └── protocols
    │   │   ├── __init__.py
    │   │   ├── graphql_transport_ws
    │   │       ├── __init__.py
    │   │       ├── handlers.py
    │   │       └── types.py
    │   │   └── graphql_ws
    │   │       ├── __init__.py
    │   │       ├── handlers.py
    │   │       └── types.py
    ├── test
    │   ├── __init__.py
    │   └── client.py
    ├── tools
    │   ├── __init__.py
    │   ├── create_type.py
    │   └── merge_types.py
    ├── types
    │   ├── __init__.py
    │   ├── arguments.py
    │   ├── auto.py
    │   ├── base.py
    │   ├── cast.py
    │   ├── enum.py
    │   ├── execution.py
    │   ├── field.py
    │   ├── fields
    │   │   ├── __init__.py
    │   │   └── resolver.py
    │   ├── graphql.py
    │   ├── info.py
    │   ├── lazy_type.py
    │   ├── maybe.py
    │   ├── mutation.py
    │   ├── nodes.py
    │   ├── object_type.py
    │   ├── private.py
    │   ├── scalar.py
    │   ├── type_resolver.py
    │   ├── union.py
    │   └── unset.py
    └── utils
    │   ├── __init__.py
    │   ├── aio.py
    │   ├── await_maybe.py
    │   ├── dataclasses.py
    │   ├── debug.py
    │   ├── deprecations.py
    │   ├── graphql_lexer.py
    │   ├── importer.py
    │   ├── inspect.py
    │   ├── locate_definition.py
    │   ├── logging.py
    │   ├── operation.py
    │   ├── str_converters.py
    │   └── typing.py
└── tests
    ├── __init__.py
    ├── a.py
    ├── asgi
        ├── __init__.py
        └── test_async.py
    ├── b.py
    ├── benchmarks
        ├── __init__.py
        ├── api.py
        ├── queries
        │   ├── items.graphql
        │   ├── many_fields.graphql
        │   ├── many_fields_directives.graphql
        │   └── simple.graphql
        ├── schema.py
        ├── test_arguments.py
        ├── test_complex_schema.py
        ├── test_execute.py
        ├── test_execute_sync.py
        ├── test_execute_with_extensions.py
        ├── test_generic_input.py
        └── test_subscriptions.py
    ├── c.py
    ├── channels
        ├── __init__.py
        ├── test_layers.py
        ├── test_router.py
        └── test_testing.py
    ├── cli
        ├── __init__.py
        ├── conftest.py
        ├── fixtures
        │   ├── __init__.py
        │   └── unions.py
        ├── snapshots
        │   ├── unions.py
        │   ├── unions_py38.py
        │   └── unions_typing_extension.py
        ├── test_codegen.py
        ├── test_export_schema.py
        ├── test_locate_definition.py
        ├── test_schema_codegen.py
        ├── test_server.py
        └── test_upgrade.py
    ├── codegen
        ├── __init__.py
        ├── conftest.py
        ├── lazy_type.py
        ├── queries
        │   ├── alias.graphql
        │   ├── basic.graphql
        │   ├── custom_scalar.graphql
        │   ├── enum.graphql
        │   ├── fragment.graphql
        │   ├── generic_types.graphql
        │   ├── interface.graphql
        │   ├── interface_fragments.graphql
        │   ├── interface_fragments_with_spread.graphql
        │   ├── interface_single_fragment.graphql
        │   ├── multiple_types.graphql
        │   ├── multiple_types_optional.graphql
        │   ├── mutation-fragment.graphql
        │   ├── mutation.graphql
        │   ├── mutation_with_object.graphql
        │   ├── nullable_list_of_non_scalars.graphql
        │   ├── optional_and_lists.graphql
        │   ├── union.graphql
        │   ├── union_return.graphql
        │   ├── union_with_one_type.graphql
        │   ├── union_with_typename.graphql
        │   ├── union_with_typename_and_fragment.graphql
        │   ├── variables.graphql
        │   └── with_directives.graphql
        ├── snapshots
        │   ├── python
        │   │   ├── alias.py
        │   │   ├── basic.py
        │   │   ├── custom_scalar.py
        │   │   ├── enum.py
        │   │   ├── fragment.py
        │   │   ├── generic_types.py
        │   │   ├── interface.py
        │   │   ├── interface_fragments.py
        │   │   ├── interface_fragments_with_spread.py
        │   │   ├── interface_single_fragment.py
        │   │   ├── multiple_types.py
        │   │   ├── multiple_types_optional.py
        │   │   ├── mutation-fragment.py
        │   │   ├── mutation.py
        │   │   ├── mutation_with_object.py
        │   │   ├── nullable_list_of_non_scalars.py
        │   │   ├── optional_and_lists.py
        │   │   ├── union.py
        │   │   ├── union_return.py
        │   │   ├── union_with_one_type.py
        │   │   ├── union_with_typename.py
        │   │   ├── union_with_typename_and_fragment.py
        │   │   ├── variables.py
        │   │   └── with_directives.py
        │   └── typescript
        │   │   ├── alias.ts
        │   │   ├── basic.ts
        │   │   ├── custom_scalar.ts
        │   │   ├── enum.ts
        │   │   ├── fragment.ts
        │   │   ├── generic_types.ts
        │   │   ├── interface.ts
        │   │   ├── interface_fragments.ts
        │   │   ├── interface_fragments_with_spread.ts
        │   │   ├── interface_single_fragment.ts
        │   │   ├── multiple_types.ts
        │   │   ├── multiple_types_optional.ts
        │   │   ├── mutation-fragment.ts
        │   │   ├── mutation.ts
        │   │   ├── mutation_with_object.ts
        │   │   ├── nullable_list_of_non_scalars.ts
        │   │   ├── optional_and_lists.ts
        │   │   ├── union.ts
        │   │   ├── union_return.ts
        │   │   ├── union_with_one_type.ts
        │   │   ├── union_with_typename.ts
        │   │   ├── union_with_typename_and_fragment.ts
        │   │   ├── variables.ts
        │   │   └── with_directives.ts
        ├── test_print_operation.py
        └── test_query_codegen.py
    ├── codemods
        ├── __init__.py
        ├── test_annotated_unions.py
        ├── test_annotated_unions_pipe.py
        └── test_imports.py
    ├── conftest.py
    ├── d.py
    ├── django
        ├── __init__.py
        ├── app
        │   ├── __init__.py
        │   ├── models.py
        │   └── urls.py
        ├── conftest.py
        ├── django_settings.py
        ├── test_dataloaders.py
        └── test_extensions.py
    ├── enums
        ├── __init__.py
        └── test_enum.py
    ├── exceptions
        ├── __init__.py
        ├── classes
        │   ├── __init__.py
        │   └── test_exception_class_missing_optional_dependencies_error.py
        ├── test_exception_handler.py
        ├── test_exception_source.py
        └── test_threading_exception_handler.py
    ├── experimental
        ├── __init__.py
        └── pydantic
        │   ├── __init__.py
        │   ├── schema
        │       ├── __init__.py
        │       ├── test_1_and_2.py
        │       ├── test_basic.py
        │       ├── test_computed.py
        │       ├── test_defaults.py
        │       ├── test_federation.py
        │       ├── test_forward_reference.py
        │       └── test_mutation.py
        │   ├── test_basic.py
        │   ├── test_conversion.py
        │   ├── test_error_type.py
        │   ├── test_fields.py
        │   └── utils.py
    ├── extensions
        ├── __init__.py
        ├── test_custom_objects_for_setting_attribute.py
        ├── test_pyinstrument.py
        └── tracing
        │   ├── __init__.py
        │   └── test_opentelemetry.py
    ├── fastapi
        ├── __init__.py
        ├── app.py
        ├── test_async.py
        ├── test_context.py
        ├── test_openapi.py
        └── test_router.py
    ├── federation
        ├── __init__.py
        ├── printer
        │   ├── __init__.py
        │   ├── test_additional_directives.py
        │   ├── test_authenticated.py
        │   ├── test_compose_directive.py
        │   ├── test_entities.py
        │   ├── test_inaccessible.py
        │   ├── test_interface.py
        │   ├── test_interface_object.py
        │   ├── test_keys.py
        │   ├── test_link.py
        │   ├── test_one_of.py
        │   ├── test_override.py
        │   ├── test_policy.py
        │   ├── test_provides.py
        │   ├── test_requires.py
        │   ├── test_requires_scopes.py
        │   ├── test_shareable.py
        │   └── test_tag.py
        ├── test_entities.py
        ├── test_schema.py
        └── test_types.py
    ├── fields
        ├── __init__.py
        ├── test_arguments.py
        ├── test_field_basics.py
        ├── test_field_defaults.py
        ├── test_field_descriptions.py
        ├── test_field_exceptions.py
        ├── test_field_names.py
        ├── test_permissions.py
        └── test_resolvers.py
    ├── file_uploads
        ├── __init__.py
        └── test_utils.py
    ├── fixtures
        ├── __init__.py
        └── sample_package
        │   ├── __init__.py
        │   └── sample_module.py
    ├── http
        ├── __init__.py
        ├── clients
        │   ├── __init__.py
        │   ├── aiohttp.py
        │   ├── asgi.py
        │   ├── async_django.py
        │   ├── async_flask.py
        │   ├── base.py
        │   ├── chalice.py
        │   ├── channels.py
        │   ├── django.py
        │   ├── fastapi.py
        │   ├── flask.py
        │   ├── litestar.py
        │   ├── quart.py
        │   └── sanic.py
        ├── conftest.py
        ├── context.py
        ├── test_async_base_view.py
        ├── test_graphql_ide.py
        ├── test_graphql_over_http_spec.py
        ├── test_http.py
        ├── test_multipart_subscription.py
        ├── test_mutation.py
        ├── test_parse_content_type.py
        ├── test_process_result.py
        ├── test_query.py
        ├── test_query_via_get.py
        └── test_upload.py
    ├── litestar
        ├── __init__.py
        ├── app.py
        ├── conftest.py
        ├── test_context.py
        ├── test_response_headers.py
        └── test_response_status.py
    ├── objects
        ├── __init__.py
        ├── generics
        │   ├── __init__.py
        │   ├── test_generic_objects.py
        │   └── test_names.py
        ├── test_inheritance.py
        ├── test_interfaces.py
        ├── test_object_instantiation.py
        └── test_types.py
    ├── plugins
        ├── __init__.py
        └── strawberry_exceptions.py
    ├── python_312
        ├── __init__.py
        ├── test_generic_objects.py
        ├── test_generics_schema.py
        ├── test_inspect.py
        └── test_python_generics.py
    ├── relay
        ├── __init__.py
        ├── schema.py
        ├── schema_future_annotations.py
        ├── snapshots
        │   ├── schema.gql
        │   └── schema_future_annotations.gql
        ├── test_connection.py
        ├── test_custom_edge.py
        ├── test_exceptions.py
        ├── test_fields.py
        ├── test_id.py
        ├── test_schema.py
        ├── test_types.py
        └── test_utils.py
    ├── sanic
        ├── __init__.py
        └── test_file_upload.py
    ├── schema
        ├── __init__.py
        ├── extensions
        │   ├── __init__.py
        │   ├── schema_extensions
        │   │   ├── __init__.py
        │   │   ├── conftest.py
        │   │   ├── test_extensions.py
        │   │   └── test_subscription.py
        │   ├── test_apollo.py
        │   ├── test_datadog.py
        │   ├── test_disable_introspection.py
        │   ├── test_field_extensions.py
        │   ├── test_imports.py
        │   ├── test_input_mutation.py
        │   ├── test_input_mutation_federation.py
        │   ├── test_input_mutation_future.py
        │   ├── test_mask_errors.py
        │   ├── test_max_aliases.py
        │   ├── test_max_tokens.py
        │   ├── test_opentelemetry.py
        │   ├── test_parser_cache.py
        │   ├── test_query_depth_limiter.py
        │   └── test_validation_cache.py
        ├── test_annotated
        │   ├── __init__.py
        │   ├── type_a.py
        │   └── type_b.py
        ├── test_arguments.py
        ├── test_basic.py
        ├── test_camel_casing.py
        ├── test_config.py
        ├── test_custom_scalar.py
        ├── test_dataloaders.py
        ├── test_directives.py
        ├── test_duplicated_types.py
        ├── test_enum.py
        ├── test_execution.py
        ├── test_execution_errors.py
        ├── test_extensions.py
        ├── test_fields.py
        ├── test_generics.py
        ├── test_generics_nested.py
        ├── test_get_extensions.py
        ├── test_info.py
        ├── test_input.py
        ├── test_interface.py
        ├── test_lazy
        │   ├── __init__.py
        │   ├── schema.py
        │   ├── test_lazy.py
        │   ├── test_lazy_generic.py
        │   ├── type_a.py
        │   ├── type_b.py
        │   ├── type_c.py
        │   ├── type_d.py
        │   └── type_e.py
        ├── test_lazy_types
        │   ├── __init__.py
        │   ├── test_cyclic.py
        │   ├── test_lazy_enums.py
        │   ├── type_a.py
        │   └── type_b.py
        ├── test_list.py
        ├── test_maybe.py
        ├── test_mutation.py
        ├── test_name_converter.py
        ├── test_one_of.py
        ├── test_permission.py
        ├── test_private_field.py
        ├── test_pydantic.py
        ├── test_resolvers.py
        ├── test_scalars.py
        ├── test_schema_generation.py
        ├── test_schema_hooks.py
        ├── test_subscription.py
        ├── test_union.py
        ├── test_union_deprecated.py
        ├── test_unresolved_fields.py
        └── types
        │   ├── __init__.py
        │   ├── test_date.py
        │   ├── test_datetime.py
        │   ├── test_decimal.py
        │   ├── test_time.py
        │   └── test_uuid.py
    ├── schema_codegen
        ├── __init__.py
        ├── snapshots
        │   └── long_descriptions.py
        ├── test_descriptions.py
        ├── test_enum.py
        ├── test_federation.py
        ├── test_input_types.py
        ├── test_names.py
        ├── test_order.py
        ├── test_root_types_extend.py
        ├── test_scalar.py
        ├── test_schema.py
        ├── test_types.py
        └── test_union.py
    ├── test
        ├── __init__.py
        ├── conftest.py
        └── test_client.py
    ├── test_aio.py
    ├── test_auto.py
    ├── test_dataloaders.py
    ├── test_deprecations.py
    ├── test_forward_references.py
    ├── test_info.py
    ├── test_inspect.py
    ├── test_printer
        ├── __init__.py
        ├── test_basic.py
        ├── test_one_of.py
        └── test_schema_directives.py
    ├── test_repr.py
    ├── test_type.py
    ├── tools
        ├── __init__.py
        ├── test_create_type.py
        └── test_merge_types.py
    ├── typecheckers
        ├── __init__.py
        ├── test_auto.py
        ├── test_directives.py
        ├── test_enum.py
        ├── test_fastapi.py
        ├── test_federation.py
        ├── test_federation_fields.py
        ├── test_federation_params.py
        ├── test_fields.py
        ├── test_fields_input.py
        ├── test_fields_keyword.py
        ├── test_fields_resolver.py
        ├── test_fields_resolver_async.py
        ├── test_info.py
        ├── test_interface.py
        ├── test_maybe.py
        ├── test_params.py
        ├── test_private.py
        ├── test_relay.py
        ├── test_scalars.py
        ├── test_type.py
        ├── test_union.py
        └── utils
        │   ├── __init__.py
        │   ├── marks.py
        │   ├── mypy.py
        │   ├── pyright.py
        │   ├── result.py
        │   └── typecheck.py
    ├── types
        ├── __init__.py
        ├── cross_module_resolvers
        │   ├── README.md
        │   ├── __init__.py
        │   ├── a_mod.py
        │   ├── b_mod.py
        │   ├── c_mod.py
        │   ├── test_cross_module_resolvers.py
        │   └── x_mod.py
        ├── resolving
        │   ├── __init__.py
        │   ├── test_enums.py
        │   ├── test_forward_references.py
        │   ├── test_generics.py
        │   ├── test_lists.py
        │   ├── test_literals.py
        │   ├── test_optionals.py
        │   ├── test_string_annotations.py
        │   ├── test_union_pipe.py
        │   ├── test_unions.py
        │   └── test_unions_deprecated.py
        ├── test_annotation.py
        ├── test_argument_types.py
        ├── test_cast.py
        ├── test_convert_to_dictionary.py
        ├── test_deferred_annotations.py
        ├── test_execution.py
        ├── test_field_types.py
        ├── test_lazy_types.py
        ├── test_lazy_types_future_annotations.py
        ├── test_object_types.py
        ├── test_parent_type.py
        ├── test_parent_type_future_annotations.py
        └── test_resolver_types.py
    ├── utils
        ├── __init__.py
        ├── test_arguments_converter.py
        ├── test_get_first_operation.py
        ├── test_get_operation_type.py
        ├── test_importer.py
        ├── test_inspect.py
        ├── test_locate_definition.py
        ├── test_logging.py
        ├── test_pretty_print.py
        ├── test_typing.py
        └── test_typing_forward_refs.py
    ├── views
        ├── __init__.py
        └── schema.py
    └── websockets
        ├── __init__.py
        ├── conftest.py
        ├── test_graphql_transport_ws.py
        ├── test_graphql_ws.py
        ├── test_websockets.py
        └── views.py


/.alexignore:
--------------------------------------------------------------------------------
1 | CHANGELOG.md
2 | TWEET.md
3 | 


--------------------------------------------------------------------------------
/.alexrc:
--------------------------------------------------------------------------------
 1 | {
 2 |   "allow": [
 3 |     "black",
 4 |     "hook",
 5 |     "hooks",
 6 |     "failure",
 7 |     "period",
 8 |     "execute",
 9 |     "executed",
10 |     "executes",
11 |     "execution",
12 |     "reject",
13 |     "special",
14 |     "primitive",
15 |     "invalid",
16 |     "failed"
17 |   ]
18 | }
19 | 


--------------------------------------------------------------------------------
/.codecov.yml:
--------------------------------------------------------------------------------
 1 | codecov:
 2 |   notify:
 3 |     require_ci_to_pass: yes
 4 | 
 5 | coverage:
 6 |   precision: 2
 7 |   round: down
 8 |   range: "70...100"
 9 | 
10 |   status:
11 |     project: yes
12 |     patch: yes
13 |     changes: no
14 | 
15 | comment:
16 |   layout: "header, diff"
17 |   behavior: default
18 |   require_changes: no
19 | 
20 | ignore:
21 |   - "strawberry/ext/mypy_plugin.py"
22 |   - "setup.py"
23 |   - "strawberry/experimental/pydantic/conversion_types.py"
24 | 


--------------------------------------------------------------------------------
/.coveragerc:
--------------------------------------------------------------------------------
 1 | # .coveragerc to control coverage.py
 2 | [run]
 3 | branch = True
 4 | 
 5 | [report]
 6 | # Regexes for lines to exclude from consideration
 7 | exclude_lines =
 8 |     # Have to re-enable the standard pragma
 9 |     pragma: no cover
10 | 
11 |     # Don't complain about missing debug-only code:
12 |     def __repr__
13 |     if self\.debug
14 | 
15 |     # Don't complain if tests don't hit defensive assertion code:
16 |     raise AssertionError
17 |     raise NotImplementedError
18 |     raise UnsupportedTypeError
19 | 
20 |     # Don't complain if non-runnable code isn't run:
21 |     if 0:
22 |     if __name__ == .__main__.:
23 | 
24 |     # Don't complain about abstract methods, they aren't run:
25 |     @(abc\.)?abstractmethod
26 | 
27 |     # Don't complain about TYPE_CHECKING
28 |     if TYPE_CHECKING:
29 | 
30 |     @overload
31 | 
32 |     # Those are not supposed to be hit
33 |     assert_never\(\w+\)
34 | 
35 | ignore_errors = True
36 | 
37 | omit =
38 |   ./.venv/**
39 |   noxfile.py
40 | 
41 | [html]
42 | directory = coverage_html_report
43 | 


--------------------------------------------------------------------------------
/.devcontainer/Dockerfile:
--------------------------------------------------------------------------------
1 | ARG VARIANT=3.13
2 | FROM mcr.microsoft.com/devcontainers/python:${VARIANT}
3 | 
4 | RUN pip3 install poetry pre-commit
5 | RUN poetry config virtualenvs.in-project true
6 | 


--------------------------------------------------------------------------------
/.devcontainer/devcontainer.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "name": "Strawberry GraphQL",
 3 |   "build": {
 4 |     "dockerfile": "Dockerfile"
 5 |   },
 6 | 
 7 |   "customizations": {
 8 |     "vscode": {
 9 |       "settings": {
10 |         "terminal.integrated.shell.linux": "/bin/bash",
11 |         "python.pythonPath": "/usr/local/bin/python",
12 |         "python.linting.enabled": false,
13 |         "python.linting.pylintEnabled": false,
14 |         "ruff.enable": true,
15 |         "ruff.organizeImports": true,
16 |         "[python]": {
17 |           "editor.formatOnSave": true,
18 |           "editor.defaultFormatter": "charliermarsh.ruff",
19 |           "editor.codeActionsOnSave": {
20 |             "source.organizeImports.ruff": true
21 |           }
22 |         }
23 |       },
24 |       "extensions": [
25 |         "ms-python.python",
26 |         "ms-python.vscode-pylance",
27 |         "charliermarsh.ruff",
28 |         "eamodio.gitlens"
29 |       ]
30 |     }
31 |   },
32 | 
33 |   "postCreateCommand": "sh ./.devcontainer/post-install.sh"
34 | }
35 | 


--------------------------------------------------------------------------------
/.devcontainer/post-install.sh:
--------------------------------------------------------------------------------
1 | poetry install --with dev,integrations
2 | pre-commit install --install-hooks
3 | 


--------------------------------------------------------------------------------
/.dockerignore:
--------------------------------------------------------------------------------
1 | .git
2 | .github
3 | .benchmarks
4 | .devcotainer
5 | .venv
6 | .mypy_cache
7 | .nox
8 | .ruff_cache
9 | 


--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
 1 | root = true
 2 | 
 3 | [*]
 4 | charset = utf-8
 5 | indent_style = space
 6 | 
 7 | [*.py]
 8 | indent_size = 4
 9 | trim_trailing_whitespace = true
10 | max_line_length = 88
11 | insert_final_newline = true
12 | 
13 | [*.yml]
14 | indent_size = 2
15 | insert_final_newline = true
16 | 


--------------------------------------------------------------------------------
/.github/bot-action/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM python:3.9-alpine
2 | 
3 | RUN pip install httpx==0.18.2
4 | 
5 | 
6 | COPY . /action
7 | 
8 | ENTRYPOINT ["python", "/action/main.py"]
9 | 


--------------------------------------------------------------------------------
/.github/bot-action/action.yml:
--------------------------------------------------------------------------------
 1 | name: 'Strawberry Bot Action'
 2 | inputs:
 3 |   pr_number:
 4 |     required: true
 5 |   status:
 6 |     required: true
 7 |   change_type:
 8 |     required: true
 9 |   changelog_base64:
10 |     required: true
11 |   tweet:
12 |     required: false
13 |   release_card_url:
14 |     required: false
15 | runs:
16 |   using: 'docker'
17 |   image: 'Dockerfile'
18 | 


--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
 1 | version: 2
 2 | updates:
 3 |   - package-ecosystem: pip
 4 |     directory: "/"
 5 |     schedule:
 6 |       interval: daily
 7 |     open-pull-requests-limit: 10
 8 |     groups:
 9 |       all-dependencies:
10 |         patterns:
11 |           - "*"
12 |     allow:
13 |       - dependency-type: direct
14 | 


--------------------------------------------------------------------------------
/.github/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/.github/logo.png


--------------------------------------------------------------------------------
/.github/pyproject.toml:
--------------------------------------------------------------------------------
1 | [tool.ruff]
2 | extend = "../pyproject.toml"
3 | 
4 | [tool.ruff.lint]
5 | extend-ignore = ["T201"]
6 | 


--------------------------------------------------------------------------------
/.github/release-check-action/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM docker.io/python:3.8-alpine
2 | 
3 | RUN pip install httpx==0.7.*
4 | 
5 | COPY . /action
6 | 
7 | ENTRYPOINT ["python", "/action/check.py"]
8 | 


--------------------------------------------------------------------------------
/.github/release-check-action/action.yml:
--------------------------------------------------------------------------------
1 | name: "Strawberry Release Check Action"
2 | description: "Check that the RELEASE.md file is valid"
3 | runs:
4 |   using: "docker"
5 |   image: "Dockerfile"
6 | 


--------------------------------------------------------------------------------
/.github/release-check-action/check.py:
--------------------------------------------------------------------------------
 1 | import base64
 2 | import pathlib
 3 | 
 4 | from config import GITHUB_WORKSPACE, RELEASE_FILE_PATH
 5 | from release import InvalidReleaseFileError, get_release_info
 6 | 
 7 | release_file = pathlib.Path(GITHUB_WORKSPACE) / RELEASE_FILE_PATH
 8 | 
 9 | release_info = None
10 | status = "MISSING"
11 | 
12 | if not release_file.exists():
13 |     status = "MISSING"
14 | else:
15 |     try:
16 |         info = get_release_info(release_file)
17 |         release_info = {
18 |             "changeType": info.change_type.name,
19 |             "changelog": info.changelog,
20 |         }
21 | 
22 |         status = "OK"
23 |     except InvalidReleaseFileError:
24 |         status = "INVALID"
25 | 
26 | 
27 | print(f"Status is {status}")
28 | print(f"::set-output name=release_status::{status}")
29 | 
30 | if release_info:
31 |     changelog = release_info["changelog"]
32 |     encoded_changelog = base64.b64encode(changelog.encode("utf-8")).decode("ascii")
33 | 
34 |     print(f"::set-output name=changelog::{encoded_changelog}")
35 |     print(f"::set-output name=change_type::{info.change_type.name}")
36 | else:
37 |     print('::set-output name=changelog::""')
38 | 


--------------------------------------------------------------------------------
/.github/release-check-action/config.py:
--------------------------------------------------------------------------------
1 | import os
2 | 
3 | RELEASE_FILE_PATH = "RELEASE.md"
4 | GITHUB_SHA = os.environ["GITHUB_SHA"]
5 | GITHUB_EVENT_PATH = os.environ["GITHUB_EVENT_PATH"]
6 | GITHUB_WORKSPACE = os.environ["GITHUB_WORKSPACE"]
7 | API_URL = "https://strawberry-bot-r3o3etjz6a-ew.a.run.app/graphql"
8 | 


--------------------------------------------------------------------------------
/.github/release-check-action/release.py:
--------------------------------------------------------------------------------
 1 | from __future__ import annotations
 2 | 
 3 | import dataclasses
 4 | import re
 5 | from enum import Enum
 6 | from typing import TYPE_CHECKING
 7 | 
 8 | if TYPE_CHECKING:
 9 |     from pathlib import Path
10 | 
11 | 
12 | RELEASE_TYPE_REGEX = re.compile(r"^[Rr]elease [Tt]ype: (major|minor|patch)
quot;)
13 | 
14 | 
15 | class InvalidReleaseFileError(Exception):
16 |     pass
17 | 
18 | 
19 | class ChangeType(Enum):
20 |     MAJOR = "major"
21 |     MINOR = "minor"
22 |     PATCH = "patch"
23 | 
24 | 
25 | @dataclasses.dataclass
26 | class ReleaseInfo:
27 |     change_type: ChangeType
28 |     changelog: str
29 | 
30 | 
31 | # TODO: remove duplication when we migrate our deployer to GitHub Actions
32 | def get_release_info(file_path: Path) -> ReleaseInfo:
33 |     with file_path.open("r") as f:
34 |         line = f.readline()
35 |         match = RELEASE_TYPE_REGEX.match(line)
36 | 
37 |         if not match:
38 |             raise InvalidReleaseFileError
39 | 
40 |         change_type_key = match.group(1)
41 |         change_type = ChangeType[change_type_key.upper()]
42 |         changelog = "".join(f.readlines()).strip()
43 | 
44 |     return ReleaseInfo(change_type, changelog)
45 | 


--------------------------------------------------------------------------------
/.github/workflows/codeql-analysis.yml:
--------------------------------------------------------------------------------
 1 | name: 🔐 CodeQL
 2 | 
 3 | on:
 4 |   push:
 5 |     branches: [main]
 6 |   pull_request:
 7 |     branches: [main]
 8 |   schedule:
 9 |     - cron: '0 18 * * 5'
10 | 
11 | jobs:
12 |   analyze:
13 |     runs-on: ubuntu-latest
14 | 
15 |     permissions:
16 |       security-events: write
17 |       actions: read
18 |       contents: read
19 | 
20 |     steps:
21 |       - name: Checkout repository
22 |         uses: actions/checkout@v3
23 | 
24 |       - name: Initialize CodeQL
25 |         uses: github/codeql-action/init@v2
26 |         with:
27 |           languages: python
28 | 
29 |       - name: Perform CodeQL Analysis
30 |         uses: github/codeql-action/analyze@v2
31 | 


--------------------------------------------------------------------------------
/.github/workflows/invite-contributors.yml:
--------------------------------------------------------------------------------
 1 | name: 👥 Invite contributors
 2 | 
 3 | on:
 4 |   push:
 5 |     branches:
 6 |       - main
 7 | 
 8 | jobs:
 9 |   invite-contributor:
10 |     name: Invite contributors
11 |     runs-on: ubuntu-latest
12 | 
13 |     steps:
14 |       - name: Invite contributors
15 |         uses: strawberry-graphql/invite-to-org-action@v4
16 |         with:
17 |           organisation: "strawberry-graphql"
18 |           comment: |
19 |             Thanks for contributing to Strawberry! 🎉 You've been invited to join
20 |             the Strawberry GraphQL organisation 😊
21 | 
22 |             You can also request a free sticker by filling this form: https://forms.gle/dmnfQUPoY5gZbVT67
23 | 
24 |             And don't forget to join our discord server: https://strawberry.rocks/discord 🔥
25 |           team-slug: "strawberry-contributors"
26 |           github-token: ${{ secrets.BOT_TOKEN }}
27 | 


--------------------------------------------------------------------------------
/.github/workflows/issue-manager.yml:
--------------------------------------------------------------------------------
 1 | name: Issue Manager
 2 | 
 3 | on:
 4 |   schedule:
 5 |     - cron: "0 0 * * *"
 6 |   issue_comment:
 7 |     types:
 8 |       - created
 9 |   issues:
10 |     types:
11 |       - labeled
12 |   pull_request_target:
13 |     types:
14 |       - labeled
15 |   workflow_dispatch:
16 | 
17 | jobs:
18 |   issue-manager:
19 |     runs-on: ubuntu-latest
20 |     steps:
21 |       - uses: tiangolo/issue-manager@0.5.0
22 |         with:
23 |           token: ${{ secrets.GITHUB_TOKEN }}
24 |           config: >
25 |             {
26 |               "info-needed": {
27 |                 "delay": "P14D",
28 |                 "message": "Hi, this issue requires extra info to be actionable. We're closing this issue because it has not been actionable for a while now. Feel free to provide the requested information and we'll happily open it again! 😊"
29 |               }
30 |             }
31 | 


--------------------------------------------------------------------------------
/.github/workflows/slash-commands.yml:
--------------------------------------------------------------------------------
 1 | name: 💬 Slash Command Dispatch
 2 | 
 3 | on:
 4 |   issue_comment:
 5 |     types: [created]
 6 | 
 7 | jobs:
 8 |   slashCommandDispatch:
 9 |     runs-on: ubuntu-latest
10 |     steps:
11 |       - name: Slash Command Dispatch
12 |         uses: peter-evans/slash-command-dispatch@v2
13 |         with:
14 |           token: ${{ secrets.BOT_TOKEN }}
15 |           reaction-token: ${{ secrets.BOT_TOKEN }}
16 |           permission: admin
17 |           commands: |
18 |             pre-release
19 | 


--------------------------------------------------------------------------------
/.gitpod.yml:
--------------------------------------------------------------------------------
1 | tasks:
2 |   - before: |
3 |       curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python -
4 |       source $HOME/.poetry/env
5 |       pip install pre-commit
6 |     init: |
7 |       poetry install
8 |       pre-commit install --install-hooks
9 | 


--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 |   "proseWrap": "always",
3 |   "printWidth": 80
4 | }
5 | 


--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
 1 | MIT License
 2 | 
 3 | Copyright (c) 2018 Patrick Arminio
 4 | 
 5 | Permission is hereby granted, free of charge, to any person obtaining a copy
 6 | of this software and associated documentation files (the "Software"), to deal
 7 | in the Software without restriction, including without limitation the rights
 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 | 
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 | 
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 | 


--------------------------------------------------------------------------------
/docs/breaking-changes.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | title: List of breaking changes and deprecations
 3 | ---
 4 | 
 5 | # List of breaking changes and deprecations
 6 | 
 7 | - [Version 0.268.0 - 10 May 2025](./breaking-changes/0.268.0.md)
 8 | - [Version 0.249.0 - 18 November 2024](./breaking-changes/0.249.0.md)
 9 | - [Version 0.243.0 - 25 September 2024](./breaking-changes/0.243.0.md)
10 | - [Version 0.240.0 - 10 September 2024](./breaking-changes/0.240.0.md)
11 | - [Version 0.236.0 - 17 July 2024](./breaking-changes/0.236.0.md)
12 | - [Version 0.233.0 - 29 May 2024](./breaking-changes/0.233.0.md)
13 | - [Version 0.217.0 - 18 December 2023](./breaking-changes/0.217.0.md)
14 | - [Version 0.213.0 - 8 November 2023](./breaking-changes/0.213.0.md)
15 | - [Version 0.180.0 - 31 May 2023](./breaking-changes/0.180.0.md)
16 | - [Version 0.169.0 - 5 April 2023](./breaking-changes/0.169.0.md)
17 | - [Version 0.159.0 - 22 February 2023](./breaking-changes/0.159.0.md)
18 | - [Version 0.146.0 - 5 December 2022](./breaking-changes/0.146.0.md)
19 | 


--------------------------------------------------------------------------------
/docs/breaking-changes/0.169.0.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | title: 0.169.0 Breaking changes
 3 | slug: breaking-changes/0.169.0
 4 | ---
 5 | 
 6 | # v0.169.0 Introduces a couple of breaking changes in the HTTP integrations
 7 | 
 8 | ## Flask
 9 | 
10 | Both `get_root_value` and `get_context` now receive the request as a parameter.
11 | 
12 | If you're customizing these methods you can change the signature to:
13 | 
14 | ```python
15 | def get_root_value(self, request: Request) -> Any: ...
16 | 
17 | 
18 | def get_context(self, request: Request, response: Response) -> Any: ...
19 | ```
20 | 
21 | The same is true for the async version of the view.
22 | 
23 | ## Sanic
24 | 
25 | The `get_root_value` method now receives the request as a parameter and it is
26 | async.
27 | 
28 | If you're customizing this method you can change the signature to:
29 | 
30 | ```python
31 | async def get_root_value(self, request: Request) -> Any: ...
32 | ```
33 | 


--------------------------------------------------------------------------------
/docs/breaking-changes/0.180.0.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | title: 0.180.0 Breaking changes
 3 | slug: breaking-changes/0.180.0
 4 | ---
 5 | 
 6 | # v0.180.0 introduces a breaking change for the Django Channels HTTP integration
 7 | 
 8 | The context object is now a `dict`. This means that you should access the
 9 | context value using the `["key"]` syntax instead of the `.key` syntax.
10 | 
11 | For the HTTP integration, there is also no `ws` key anymore and `request` is a
12 | custom request object containing the full request instead of a
13 | `GraphQLHTTPConsumer` instance. If you need to access the `GraphQLHTTPConsumer`
14 | instance in a HTTP connection, you can access it via
15 | `info.context["request"].consumer`.
16 | 
17 | For the WebSockets integration, the context keys did not change, e.g. the values
18 | for `info.context["ws"]`, `info.context["request"]` and
19 | `info.context["connection_params"]` are the same as before.
20 | 
21 | If you still want to use the `.key` syntax, you can override `get_context()` to
22 | return a custom dataclass there. See the Channels integration documentation for
23 | an example.
24 | 


--------------------------------------------------------------------------------
/docs/breaking-changes/0.213.0.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | title: 0.213.0 Deprecation
 3 | slug: breaking-changes/0.213.0
 4 | ---
 5 | 
 6 | # v0.213.0 introduces a deprecation for `graphiql` parameter
 7 | 
 8 | All HTTP integration now will use `graphql_ide` instead of `graphiql` parameter.
 9 | If you're not using the `graphiql` parameter, you can safely ignore this
10 | deprecation.
11 | 
12 | If you're using the `graphiql` parameter, you should change it to `graphql_ide`
13 | instead.
14 | 
15 | Here's an example of the changes:
16 | 
17 | ```diff
18 | -graphql_app = GraphQLRouter(schema, graphiql=True)
19 | +graphql_app = GraphQLRouter(schema, graphql_ide="graphiql")
20 | 
21 | -graphql_app = GraphQLRouter(schema, graphiql=False)
22 | +graphql_app = GraphQLRouter(schema, graphql_ide=None)
23 | ```
24 | 


--------------------------------------------------------------------------------
/docs/breaking-changes/0.217.0.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | title: 0.217 Breaking Changes
 3 | slug: breaking-changes/0.217.0
 4 | ---
 5 | 
 6 | # v0.217.0 changes how kwargs are passed to `has_permission` method
 7 | 
 8 | Previously the `kwargs` argument keys for the `has_permission` method were using
 9 | camel casing (depending on your schema configuration), now they will always
10 | follow the python name defined in your resolvers.
11 | 
12 | ```python
13 | class IsAuthorized(BasePermission):
14 |     message = "User is not authorized"
15 | 
16 |     def has_permission(
17 |         self, source, info, **kwargs: typing.Any
18 |     ) -> bool:  # pragma: no cover
19 |         # kwargs will have a key called "a_key"
20 |         # instead of `aKey`
21 | 
22 |         return False
23 | 
24 | 
25 | @strawberry.type
26 | class Query:
27 |     @strawberry.field(permission_classes=[IsAuthorized])
28 |     def name(self, a_key: str) -> str:  # pragma: no cover
29 |         return "Erik"
30 | ```
31 | 


--------------------------------------------------------------------------------
/docs/breaking-changes/0.233.0.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | title: 0.233.0 Breaking Changes
 3 | slug: breaking-changes/0.233.0
 4 | ---
 5 | 
 6 | # v0.233.0 changes the `info` argument in `resolve_reference` in Federation
 7 | 
 8 | In this release we have updated the `info` object passed to the
 9 | `resolve_reference` function in Federation to be a `strawberry.Info` object
10 | instead of the one coming from GraphQL-core.
11 | 
12 | If you need to access the original `info` object you can do so by accessing the
13 | `_raw_info` attribute.
14 | 
15 | ```python
16 | import strawberry
17 | 
18 | 
19 | @strawberry.federation.type(keys=["upc"])
20 | class Product:
21 |     upc: str
22 | 
23 |     @classmethod
24 |     def resolve_reference(cls, info: strawberry.Info, upc: str) -> "Product":
25 |         # Access the original info object
26 |         original_info = info._raw_info
27 | 
28 |         return Product(upc=upc)
29 | ```
30 | 


--------------------------------------------------------------------------------
/docs/breaking-changes/0.236.0.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | title: 0.236.0 Breaking Changes
 3 | slug: breaking-changes/0.236.0
 4 | ---
 5 | 
 6 | # v0.236.0 changes some of the imports
 7 | 
 8 | This release changes the location of some files in the codebase, this is to make
 9 | the codebase more organized and easier to navigate.
10 | 
11 | Technically most of these changes should not affect you, but if you were
12 | importing some of the files directly you will need to update the imports.
13 | 
14 | We created a codemod to help you with that, feel free to try and submit bugs if
15 | we missed something.
16 | 
17 | ```bash
18 | strawberry upgrade update-imports
19 | ```
20 | 


--------------------------------------------------------------------------------
/docs/breaking-changes/0.240.0.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | title: 0.240.0 Breaking Changes
 3 | slug: breaking-changes/0.240.0
 4 | ---
 5 | 
 6 | # v0.240.0 updates `Schema.subscribe`'s signature
 7 | 
 8 | In order to support schema extensions in subscriptions and errors that can be
 9 | raised before the execution of the subscription, we had to update the signature
10 | of `Schema.subscribe`.
11 | 
12 | Previously it was:
13 | 
14 | ```python
15 | async def subscribe(
16 |     self,
17 |     query: str,
18 |     variable_values: Optional[Dict[str, Any]] = None,
19 |     context_value: Optional[Any] = None,
20 |     root_value: Optional[Any] = None,
21 |     operation_name: Optional[str] = None,
22 | ) -> Union[AsyncIterator[GraphQLExecutionResult], GraphQLExecutionResult]:
23 | ```
24 | 
25 | Now it is:
26 | 
27 | ```python
28 | async def subscribe(
29 |     self,
30 |     query: Optional[str],
31 |     variable_values: Optional[Dict[str, Any]] = None,
32 |     context_value: Optional[Any] = None,
33 |     root_value: Optional[Any] = None,
34 |     operation_name: Optional[str] = None,
35 | ) -> Union[AsyncGenerator[ExecutionResult, None], PreExecutionError]:
36 | ```
37 | 


--------------------------------------------------------------------------------
/docs/breaking-changes/0.249.0.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | title: 0.249.0 Breaking Changes
 3 | slug: breaking-changes/0.249.0
 4 | ---
 5 | 
 6 | # v0.249.0 Breaking Changes
 7 | 
 8 | After a year-long deprecation period, the `SentryTracingExtension` has been
 9 | removed in favor of the official Sentry SDK integration.
10 | 
11 | To migrate, remove the `SentryTracingExtension` from your Strawberry schema and
12 | then follow the
13 | [official Sentry SDK integration guide](https://docs.sentry.io/platforms/python/integrations/strawberry/).
14 | 


--------------------------------------------------------------------------------
/docs/breaking-changes/0.251.0.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | title: 0.251.0 Breaking Changes
 3 | slug: breaking-changes/0.251.0
 4 | ---
 5 | 
 6 | # v0.251.0 Breaking Changes
 7 | 
 8 | We slightly changed the signature of the `encode_json` method used to customize
 9 | the JSON encoder used by our HTTP views.
10 | 
11 | Originally, the method was only meant to encode HTTP response data. Starting
12 | with this release, it's also used to encode WebSocket messages.
13 | 
14 | Previously, the method signature was:
15 | 
16 | ```python
17 | def encode_json(self, response_data: GraphQLHTTPResponse) -> str: ...
18 | ```
19 | 
20 | To upgrade your code, change the method signature to the following and make sure
21 | your method can handle the same inputs as the built-in `json.dumps` method:
22 | 
23 | ```python
24 | def encode_json(self, data: object) -> str: ...
25 | ```
26 | 


--------------------------------------------------------------------------------
/docs/codegen/schema-codegen.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | title: Schema codegen
 3 | ---
 4 | 
 5 | # Schema codegen
 6 | 
 7 | Strawberry supports code generation from SDL files.
 8 | 
 9 | Let's assume we have the following SDL file:
10 | 
11 | ```graphql
12 | type Query {
13 |   user: User
14 | }
15 | 
16 | type User {
17 |   id: ID!
18 |   name: String!
19 | }
20 | ```
21 | 
22 | by running the following command:
23 | 
24 | ```shell
25 | strawberry schema-codegen schema.graphql
26 | ```
27 | 
28 | we'll get the following output:
29 | 
30 | ```python
31 | import strawberry
32 | 
33 | 
34 | @strawberry.type
35 | class Query:
36 |     user: User | None
37 | 
38 | 
39 | @strawberry.type
40 | class User:
41 |     id: strawberry.ID
42 |     name: str
43 | 
44 | 
45 | schema = strawberry.Schema(query=Query)
46 | ```
47 | 


--------------------------------------------------------------------------------
/docs/concepts/async.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | title: Async
 3 | ---
 4 | 
 5 | # Async
 6 | 
 7 | Async is a concurrent programming design that has been supported in Python since
 8 | version 3.4. To learn more about async in Python refer to
 9 | [Real Python’s Async walkthrough](https://realpython.com/async-io-python/).
10 | 
11 | Strawberry supports both async and non async resolvers, so you can mix and match
12 | them in your code. Here’s an example of an async resolver:
13 | 
14 | ```python
15 | import asyncio
16 | import strawberry
17 | 
18 | 
19 | async def resolve_hello(root) -> str:
20 |     await asyncio.sleep(1)
21 | 
22 |     return "Hello world"
23 | 
24 | 
25 | @strawberry.type
26 | class Query:
27 |     hello: str = strawberry.field(resolver=resolve_hello)
28 | 
29 | 
30 | schema = strawberry.Schema(Query)
31 | ```
32 | 


--------------------------------------------------------------------------------
/docs/editors/mypy.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | title: Mypy
 3 | ---
 4 | 
 5 | # Mypy
 6 | 
 7 | Strawberry comes with support for
 8 | [Mypy](https://mypy.readthedocs.io/en/stable/), a popular static type checker
 9 | for Python.
10 | 
11 | This guide will explain how to configure Mypy to work with Strawberry.
12 | 
13 | ## Install Mypy
14 | 
15 | The first thing we need to do is to install
16 | [Mypy](https://mypy.readthedocs.io/en/stable/), this is the tool that will
17 | perform the type checking.
18 | 
19 | Once the tool is installed, we need to configure it to enable type checking and
20 | use the Strawberry plugin. To do so we need to create a `mypy.ini` file in the
21 | root of our project and add the following settings:
22 | 
23 | ```ini
24 | [mypy]
25 | plugins = strawberry.ext.mypy_plugin
26 | ```
27 | 
28 | You can also configure Mypy inside the `pyproject.toml` file, like so:
29 | 
30 | ```toml
31 | [tool.mypy]
32 | plugins = ["strawberry.ext.mypy_plugin"]
33 | ```
34 | 
35 | Once you have configured the settings, you can run `mypy` and you should be
36 | getting type checking errors.
37 | 


--------------------------------------------------------------------------------
/docs/editors/pylance.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/docs/editors/pylance.png


--------------------------------------------------------------------------------
/docs/errors/_template.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | title: Some Error
 3 | ---
 4 | 
 5 | # Some Error Error
 6 | 
 7 | ## Description
 8 | 
 9 | This error is thrown when ... for example the following code will throw this
10 | error:
11 | 
12 | ```python
13 | import strawberry
14 | 
15 | schema = strawberry.Schema(query=Query)
16 | ```
17 | 


--------------------------------------------------------------------------------
/docs/errors/conflicting-arguments.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | title: Conflicting Arguments Error
 3 | ---
 4 | 
 5 | # Conflicting Arguments Error
 6 | 
 7 | ## Description
 8 | 
 9 | This error is thrown when you define a resolver with multiple arguments that
10 | conflict with each other, like "self", "root", or any arguments annotated with
11 | strawberry.Parent.
12 | 
13 | For example the following code will throw this error:
14 | 
15 | ```python
16 | import strawberry
17 | 
18 | 
19 | @strawberry.type
20 | class Query:
21 |     @strawberry.field
22 |     def hello(
23 |         self, root, parent: strawberry.Parent[str]
24 |     ) -> str:  #  <-- self, root, and parent all identify the same input
25 |         return f"hello world"
26 | ```
27 | 


--------------------------------------------------------------------------------
/docs/errors/invalid-argument-type.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | title: Invalid Argument Type Error
 3 | ---
 4 | 
 5 | # Invalid Argument Type Error
 6 | 
 7 | ## Description
 8 | 
 9 | This error is thrown when an argument is of the wrong type, it usually happens
10 | when passing **unions** or **interfaces** as an argument, for example the
11 | following code will throw this error:
12 | 
13 | ```python
14 | import strawberry
15 | 
16 | from typing import Union, Annotated
17 | 
18 | 
19 | @strawberry.type
20 | class TypeA:
21 |     id: strawberry.ID
22 | 
23 | 
24 | ExampleUnion = Annotated[Union[TypeA], strawberry.union("ExampleUnion")]
25 | 
26 | 
27 | @strawberry.type
28 | class Query:
29 |     @strawberry.field
30 |     def example(self, data: Example) -> str:
31 |         return "this is an example"
32 | 
33 | 
34 | schema = strawberry.Schema(query=Query)
35 | ```
36 | 
37 | ## Using union types as arguments
38 | 
39 | The latest [GraphQL specification](https://spec.graphql.org/October2021/)
40 | doesn't allow using unions as arguments. There's currently an
41 | [RFC for adding a `oneOf` directive](https://github.com/graphql/graphql-spec/pull/825)
42 | that might work for your use case, but it's not yet implemented in the spec and
43 | Strawberry
44 | 


--------------------------------------------------------------------------------
/docs/errors/invalid-superclass-interface.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | title: Invalid Superclass Interface Error
 3 | ---
 4 | 
 5 | # Invalid Superclass Interface Error
 6 | 
 7 | ## Description
 8 | 
 9 | This error is thrown when you define a class that has the `strawberry.input`
10 | decorator but also inherits from one or more classes with the
11 | `strawberry.interface` decorator. The underlying reason for this is that in
12 | GraphQL, input types cannot implement interfaces. For example, the following
13 | code will throw this error:
14 | 
15 | ```python
16 | import strawberry
17 | 
18 | 
19 | @strawberry.interface
20 | class SomeInterface:
21 |     some_field: str
22 | 
23 | 
24 | @strawberry.input
25 | class SomeInput(SomeInterface):
26 |     another_field: int
27 | ```
28 | 


--------------------------------------------------------------------------------
/docs/errors/missing-arguments-annotations.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | title: Missing arguments annotation Error
 3 | ---
 4 | 
 5 | # Missing arguments annotation Error
 6 | 
 7 | ## Description
 8 | 
 9 | This error is thrown when an argument is missing an annotation, for example the
10 | following code will throw this error:
11 | 
12 | ```python
13 | import strawberry
14 | 
15 | 
16 | @strawberry.type
17 | class Query:
18 |     @strawberry.field
19 |     def hello(self, name) -> str:  #  <-- note name here is missing an annotation
20 |         return f"hello {name}"
21 | 
22 | 
23 | schema = strawberry.Schema(query=Query)
24 | ```
25 | 
26 | This happens because Strawberry needs to know the type of every argument to be
27 | able to generate the correct GraphQL type.
28 | 
29 | ## How to fix this error
30 | 
31 | You can fix this error by adding an annotation to the argument, for example, the
32 | following code will fix this error:
33 | 
34 | ```python
35 | import strawberry
36 | 
37 | 
38 | @strawberry.type
39 | class Query:
40 |     @strawberry.field
41 |     def hello(self, name: str) -> str:
42 |         return f"hello {name}"
43 | 
44 | 
45 | schema = strawberry.Schema(query=Query)
46 | ```
47 | 


--------------------------------------------------------------------------------
/docs/errors/missing-field-annotation.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | title: Missing field annotation Error
 3 | ---
 4 | 
 5 | # Missing field annotation Error
 6 | 
 7 | ## Description
 8 | 
 9 | This error is thrown when a field on a class is missing an annotation, for
10 | example the following code will throw this error:
11 | 
12 | ```python
13 | import strawberry
14 | 
15 | 
16 | @strawberry.type
17 | class Query:
18 |     name: str
19 |     age = strawberry.field(
20 |         name="ageInYears"
21 |     )  # note that here we don't have a type for this field
22 | 
23 | 
24 | schema = strawberry.Schema(query=Query)
25 | ```
26 | 
27 | This happens because Strawberry needs to know the type of every field for a type
28 | to be able to generate the correct GraphQL type.
29 | 
30 | ## How to fix this error
31 | 
32 | You can fix this error by adding an annotation to the field, for example, the
33 | following code will fix this error:
34 | 
35 | ```python
36 | import strawberry
37 | 
38 | 
39 | @strawberry.type
40 | class Query:
41 |     name: str
42 |     age: int = strawberry.field(name="ageInYears")
43 | 
44 | 
45 | schema = strawberry.Schema(query=Query)
46 | ```
47 | 


--------------------------------------------------------------------------------
/docs/errors/missing-return-annotation.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | title: Missing return annotation Error
 3 | ---
 4 | 
 5 | # Missing return annotation Error
 6 | 
 7 | ## Description
 8 | 
 9 | This error is thrown when a resolver and it's corresponding field don't have a
10 | return annotation, for example the following code will throw this error:
11 | 
12 | ```python
13 | import strawberry
14 | 
15 | 
16 | @strawberry.type
17 | class Query:
18 |     @strawberry.field
19 |     def example(self):
20 |         return "this is an example"
21 | 
22 | 
23 | schema = strawberry.Schema(query=Query)
24 | ```
25 | 
26 | This happens because Strawberry needs to know the return type of the resolver to
27 | be able to generate the correct GraphQL type.
28 | 
29 | ## How to fix this error
30 | 
31 | You can fix this error by adding a return annotation to the resolver, for
32 | example, the following code will fix this error:
33 | 
34 | ```python
35 | import strawberry
36 | 
37 | 
38 | @strawberry.type
39 | class Query:
40 |     @strawberry.field
41 |     def example(self) -> str:
42 |         return "this is an example"
43 | 
44 | 
45 | schema = strawberry.Schema(query=Query)
46 | ```
47 | 


--------------------------------------------------------------------------------
/docs/errors/object-is-not-an-enum.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | title: Object is not an Enum Error
 3 | ---
 4 | 
 5 | # Object is not an Enum Error
 6 | 
 7 | ## Description
 8 | 
 9 | This error is thrown when applying `@strawberry.enum` to a non-enum object, for
10 | example the following code will throw this error:
11 | 
12 | ```python
13 | import strawberry
14 | 
15 | 
16 | # note the lack of @strawberry.enum here:
17 | class NotAnEnum:
18 |     A = "A"
19 | 
20 | 
21 | @strawberry.type
22 | class Query:
23 |     field: NotAnEnum
24 | 
25 | 
26 | schema = strawberry.Schema(query=Query)
27 | ```
28 | 
29 | This happens because Strawberry expects all enums to be subclasses of `Enum`.
30 | 
31 | ## How to fix this error
32 | 
33 | You can fix this error by making sure the class you're applying
34 | `@strawberry.enum` to is a subclass of `Enum`. For example, the following code
35 | will fix this error:
36 | 
37 | ```python
38 | import strawberry
39 | 
40 | 
41 | @strawberry.enum
42 | class NotAnEnum:
43 |     A = "A"
44 | 
45 | 
46 | @strawberry.type
47 | class Query:
48 |     field: NotAnEnum
49 | 
50 | 
51 | schema = strawberry.Schema(query=Query)
52 | ```
53 | 


--------------------------------------------------------------------------------
/docs/errors/object-is-not-class.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | title: Object is not an Class Error
 3 | ---
 4 | 
 5 | # Object is not an Class Error
 6 | 
 7 | ## Description
 8 | 
 9 | This error is thrown when applying `@strawberry.type/interface/input` to a
10 | non-class object, for example the following code will throw this error:
11 | 
12 | ```python
13 | import strawberry
14 | 
15 | 
16 | @strawberry.type
17 | def a_function(): ...
18 | 
19 | 
20 | @strawberry.type
21 | class Query:
22 |     field: a_function
23 | 
24 | 
25 | schema = strawberry.Schema(query=Query)
26 | ```
27 | 
28 | This happens because Strawberry expects all enums to be subclasses of `Enum`.
29 | 
30 | ## How to fix this error
31 | 
32 | You can fix this error by making sure the class you're applying
33 | `@strawberry.type/interface/input` to is a class. For example, the following
34 | code will fix this error:
35 | 
36 | ```python
37 | import strawberry
38 | 
39 | 
40 | @strawberry.type
41 | class AFunction:
42 |     field: int
43 | 
44 | 
45 | @strawberry.type
46 | class Query:
47 |     field: AFunction
48 | 
49 | 
50 | schema = strawberry.Schema(query=Query)
51 | ```
52 | 


--------------------------------------------------------------------------------
/docs/errors/unsupported-type.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | title: Unsupported Type Error
 3 | ---
 4 | 
 5 | # Unsupported Type Error
 6 | 
 7 | ## Description
 8 | 
 9 | This error is thrown when trying to convert arguments with a type that
10 | Strawberry doesn't know about. It shouldn't happen with normal usage of
11 | Strawberry.
12 | 


--------------------------------------------------------------------------------
/docs/extensions.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | title: Extensions
 3 | ---
 4 | 
 5 | # Extensions
 6 | 
 7 | Extensions allow you, as an application developer, to customise the GraphQL
 8 | execution flow based on your needs. Strawberry provides multiple built in
 9 | extensions that allow you to extend the capability of your GraphQL server.
10 | 
11 | If you can't find what you need among the
12 | [built-in extensions](#built-in-extensions), you can also build your own custom
13 | extension based on a standard interface. Check out the
14 | [schema extensions](./guides/custom-extensions.md) and
15 | [field extensions](./guides/field-extensions.md) guides to find out more.
16 | 
17 | ## Built-in extensions
18 | 
19 | <ExtensionsList />
20 | 


--------------------------------------------------------------------------------
/docs/extensions/_template.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | title: Extension Name
 3 | summary: A summary of the extension.
 4 | tags: comma,separated,list,of,tags
 5 | ---
 6 | 
 7 | # `ExtensionName`
 8 | 
 9 | This extension does ...
10 | 
11 | ## Usage example:
12 | 
13 | ```python
14 | import strawberry
15 | from strawberry.extensions import ExtensionName
16 | 
17 | 
18 | @strawberry.type
19 | class Query:
20 |     @strawberry.field
21 |     def hello(self) -> str:
22 |         return "Hello, world!"
23 | 
24 | 
25 | schema = strawberry.Schema(
26 |     Query,
27 |     extensions=[
28 |         ExtensionName(),
29 |     ],
30 | )
31 | ```
32 | 
33 | ## API reference:
34 | 
35 | ```python
36 | class ExtensionName(an_argument=None): ...
37 | ```
38 | 
39 | #### `an_argument: Optional[str] = None`
40 | 
41 | Description of the argument.
42 | 
43 | ## More examples:
44 | 
45 | <details>
46 |   <summary>Using `an_argument`</summary>
47 | 
48 | ```python
49 | import strawberry
50 | from strawberry.extensions import ValidationCache
51 | 
52 | schema = strawberry.Schema(
53 |     Query,
54 |     extensions=[
55 |         ExtensionName(an_argument="something"),
56 |     ],
57 | )
58 | ```
59 | 
60 | </details>
61 | 


--------------------------------------------------------------------------------
/docs/extensions/disable-validation.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | title: Disable Validation
 3 | summary: Disable all query validation.
 4 | tags: performance,validation
 5 | ---
 6 | 
 7 | # `DisableValidation`
 8 | 
 9 | This extensions disables all query validation. This can be useful to improve
10 | performance in some specific cases, for example when dealing with internal APIs
11 | where queries can be trusted.
12 | 
13 | <Warning>
14 | 
15 | Only do this if you know what you are doing! Disabling validation breaks the
16 | safety of having typed schema. If you are trying to improve performance you
17 | might want to consider using the [ValidationCache](./validation-cache) instead.
18 | 
19 | </Warning>
20 | 
21 | ## Usage example:
22 | 
23 | ```python
24 | import strawberry
25 | from strawberry.extensions import DisableValidation
26 | 
27 | 
28 | @strawberry.type
29 | class Query:
30 |     @strawberry.field
31 |     def hello(self) -> str:
32 |         return "Hello, world!"
33 | 
34 | 
35 | schema = strawberry.Schema(
36 |     Query,
37 |     extensions=[
38 |         DisableValidation(),
39 |     ],
40 | )
41 | ```
42 | 
43 | ## API reference:
44 | 
45 | _No arguments_
46 | 


--------------------------------------------------------------------------------
/docs/extensions/max-aliases-limiter.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | title: Max Aliases Limiter
 3 | summary:
 4 |   Add a validator to limit the maximum number of aliases in a GraphQL document.
 5 | tags: security
 6 | ---
 7 | 
 8 | # `MaxAliasesLimiter`
 9 | 
10 | This extension adds a validator to limit the maximum number of aliases in a
11 | GraphQL document.
12 | 
13 | ## Usage example:
14 | 
15 | ```python
16 | import strawberry
17 | from strawberry.extensions import MaxAliasesLimiter
18 | 
19 | 
20 | @strawberry.type
21 | class Query:
22 |     @strawberry.field
23 |     def hello(self) -> str:
24 |         return "Hello, world!"
25 | 
26 | 
27 | schema = strawberry.Schema(
28 |     Query,
29 |     extensions=[
30 |         MaxAliasesLimiter(max_alias_count=15),
31 |     ],
32 | )
33 | ```
34 | 
35 | ## API reference:
36 | 
37 | ```python
38 | class MaxAliasesLimiter(max_alias_count): ...
39 | ```
40 | 
41 | #### `max_alias_count: int`
42 | 
43 | The maximum allowed number of aliases in a GraphQL document.
44 | 


--------------------------------------------------------------------------------
/docs/extensions/pyinstrument.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | title: PyInstrument
 3 | summary: Easily Instrument your Schema
 4 | tags: instrumentation,profiling
 5 | ---
 6 | 
 7 | # `PyInstrument`
 8 | 
 9 | This extension allows you to instrument your schema and inspect the call stack.
10 | 
11 | ## Usage example:
12 | 
13 | ```python
14 | import strawberry
15 | from strawberry.extensions import pyinstrument
16 | 
17 | 
18 | @strawberry.type
19 | class Query:
20 |     @strawberry.field
21 |     def hello(self) -> str:
22 |         return "Hello, world!"
23 | 
24 | 
25 | schema = strawberry.Schema(
26 |     Query,
27 |     extensions=[
28 |         pyinstrument.PyInstrument(report_path="pyinstrument.html"),
29 |     ],
30 | )
31 | ```
32 | 
33 | ## API reference:
34 | 
35 | ```python
36 | class PyInstrument(report_Path=Path("pyinstrument.html")): ...
37 | ```
38 | 
39 | #### `report_path: Path = Path("pyinstrument.html")`
40 | 
41 | Path to write the HTML PyInstrument report
42 | 


--------------------------------------------------------------------------------
/docs/extensions/sentry-tracing.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | title: Sentry Tracing
 3 | summary: Add Sentry tracing to your GraphQL server.
 4 | tags: tracing
 5 | ---
 6 | 
 7 | # `SentryTracingExtension`
 8 | 
 9 | <Warning>
10 | 
11 | As of Sentry 1.32.0, Strawberry is officially supported by the Sentry SDK.
12 | Therefore, Strawberry's `SentryTracingExtension` has been deprecated in version
13 | 0.210.0 and finally removed with Strawberry 0.249.0 in favor of the official
14 | Sentry SDK integration.
15 | 
16 | For more details, please refer to the
17 | [documentation for the official Sentry Strawberry integration](https://docs.sentry.io/platforms/python/integrations/strawberry/).
18 | 
19 | </Warning>
20 | 


--------------------------------------------------------------------------------
/docs/federation/custom_directives.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | title: Exposing directives on the supergraph (Apollo Federation)
 3 | ---
 4 | 
 5 | # Exposing directives on the supergraph (Apollo Federation)
 6 | 
 7 | By default (most)
 8 | [schema directives are hidden from the supergraph schema](https://www.apollographql.com/docs/federation/federated-types/federated-directives/#composedirective).
 9 | If you need to expose a directive to the supergraph, you can use the `compose`
10 | parameter on the `@strawberry.federation.schema_directives` decorator, here's an
11 | example:
12 | 
13 | ```python
14 | import strawberry
15 | 
16 | 
17 | @strawberry.federation.schema_directive(
18 |     locations=[Location.OBJECT], name="cacheControl", compose=True
19 | )
20 | class CacheControl:
21 |     max_age: int
22 | ```
23 | 
24 | This will create a `cacheControl` directive and it will also use
25 | [`@composeDirective`](https://www.apollographql.com/docs/federation/federated-types/federated-directives/#composedirective)
26 | on the schema to make sure it is included in the supergraph schema.
27 | 


--------------------------------------------------------------------------------
/docs/federation/introduction.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | title: Apollo Federation
 3 | ---
 4 | 
 5 | # Apollo Federation
 6 | 
 7 | Strawberry supports
 8 | [Apollo Federation](https://www.apollographql.com/docs/federation/) out of the
 9 | box, that means that you can create services using Strawberry and federate them
10 | via Apollo Gateway or Apollo Router.
11 | 
12 | Strawberry is a schema first library, to use Apollo Federation you need to add
13 | directives to your schema, types and fields. Strawberry has built support for
14 | directives, but it also provide shortcuts for Apollo Federation.
15 | 
16 | All shortcuts live under the `strawberry.federation` module. For example if you
17 | want to create an
18 | [Entity](https://www.apollographql.com/docs/federation/entities) you can do:
19 | 
20 | ```python
21 | @strawberry.federation.type(keys=["id"])
22 | class Book:
23 |     id: strawberry.ID
24 |     title: str
25 | ```
26 | 
27 | And strawberry will automatically add the right directives to the type and
28 | schema.
29 | 
30 | # Getting started
31 | 
32 | If you want to get started with Apollo Federation, you can use our
33 | [Apollo Federation guide](../guides/federation.md).
34 | 


--------------------------------------------------------------------------------
/docs/general/multipart-subscriptions.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | title: Multipart subscriptions
 3 | ---
 4 | 
 5 | # Multipart subscriptions
 6 | 
 7 | Strawberry supports subscription over multipart responses. This is an
 8 | [alternative protocol](https://www.apollographql.com/docs/router/executing-operations/subscription-multipart-protocol/)
 9 | created by [Apollo](https://www.apollographql.com/) to support subscriptions
10 | over HTTP, and it is supported by default by Apollo Client.
11 | 
12 | # Support
13 | 
14 | We support multipart subscriptions out of the box in the following HTTP
15 | libraries:
16 | 
17 | - Django (only in the Async view)
18 | - ASGI
19 | - Litestar
20 | - FastAPI
21 | - AioHTTP
22 | - Quart
23 | 
24 | # Usage
25 | 
26 | Multipart subscriptions are automatically enabled when using Subscription, so no
27 | additional configuration is required.
28 | 


--------------------------------------------------------------------------------
/docs/general/upgrades.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | title: Upgrading Strawberry
 3 | ---
 4 | 
 5 | # Upgrading Strawberry
 6 | 
 7 | <!--alex ignore-->
 8 | 
 9 | We try to keep Strawberry as backwards compatible as possible, but sometimes we
10 | need to make updates to the public API. While we try to deprecate APIs before
11 | removing them, we also want to make it as easy as possible to upgrade to the
12 | latest version of Strawberry.
13 | 
14 | For this reason, we provide a CLI command to run Codemods that can automatically
15 | upgrade your codebase to use the updated APIs.
16 | 
17 | Keep an eye on our release notes and the
18 | [breaking changes](../breaking-changes.md) page to see if a new Codemod is
19 | available, or if manual changes are required.
20 | 
21 | Here's an example of how to upgrade your codebase by running a Codemod using the
22 | Strawberry CLI's `upgrade` command:
23 | 
24 | ```shell
25 | strawberry upgrade annotated-union .
26 | ```
27 | 


--------------------------------------------------------------------------------
/docs/guides/convert-to-dictionary.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | title: Convert to Dictionary
 3 | ---
 4 | 
 5 | # Convert to Dictionary
 6 | 
 7 | Strawberry provides a utility function to convert a Strawberry object to a
 8 | dictionary.
 9 | 
10 | You can use `strawberry.asdict(...)` function:
11 | 
12 | ```python
13 | @strawberry.type
14 | class User:
15 |     name: str
16 |     age: int
17 | 
18 | 
19 | # should be {"name": "Lorem", "age": 25}
20 | user_dict = strawberry.asdict(User(name="Lorem", age=25))
21 | ```
22 | 


--------------------------------------------------------------------------------
/docs/images/index-query-example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/docs/images/index-query-example.png


--------------------------------------------------------------------------------
/docs/images/index-server.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/docs/images/index-server.png


--------------------------------------------------------------------------------
/docs/images/subscriptions-count-websocket.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/docs/images/subscriptions-count-websocket.png


--------------------------------------------------------------------------------
/docs/integrations/starlette.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | title: Starlette
 3 | ---
 4 | 
 5 | # Starlette
 6 | 
 7 | Strawberry provides support for [Starlette](https://www.starlette.io/) with the
 8 | ASGI integration.
 9 | 
10 | See below example for integrating Starlette with Strawberry:
11 | 
12 | ```python
13 | from starlette.applications import Starlette
14 | from strawberry.asgi import GraphQL
15 | 
16 | from api.schema import schema
17 | 
18 | graphql_app = GraphQL(schema)
19 | 
20 | app = Starlette()
21 | app.add_route("/graphql", graphql_app)
22 | app.add_websocket_route("/graphql", graphql_app)
23 | ```
24 | 
25 | For more information about Strawberry ASGI refer to
26 | [the documentation on ASGI](./asgi.md)
27 | 


--------------------------------------------------------------------------------
/federation-compatibility/Dockerfile:
--------------------------------------------------------------------------------
 1 | FROM python:3.10-slim
 2 | WORKDIR /web
 3 | 
 4 | RUN apt update && apt install -y gcc python3-dev
 5 | RUN pip install poetry
 6 | 
 7 | COPY strawberry ./strawberry
 8 | COPY pyproject.toml ./
 9 | COPY poetry.lock ./
10 | COPY README.md ./
11 | 
12 | RUN poetry install --with integrations
13 | 
14 | COPY federation-compatibility/schema.py ./
15 | 
16 | EXPOSE 4001
17 | 
18 | CMD poetry run strawberry server -p 4001 -h 0.0.0.0 schema:schema
19 | 


--------------------------------------------------------------------------------
/federation-compatibility/docker-compose.yml:
--------------------------------------------------------------------------------
1 | services:
2 |   products:
3 |     build:
4 |       context: .
5 |       dockerfile: federation-compatibility/Dockerfile
6 |     ports:
7 |       - 4001:4001
8 | 


--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
 1 | #!/usr/bin/env python
 2 | 
 3 | # we use poetry for our build, but this file seems to be required
 4 | # in order to get GitHub dependencies graph to work
 5 | 
 6 | import setuptools
 7 | 
 8 | if __name__ == "__main__":
 9 |     setuptools.setup(name="strawberry-graphql")
10 | 


--------------------------------------------------------------------------------
/strawberry/__main__.py:
--------------------------------------------------------------------------------
1 | from .cli import run
2 | 
3 | if __name__ == "__main__":
4 |     run()
5 | 


--------------------------------------------------------------------------------
/strawberry/aiohttp/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/strawberry/aiohttp/__init__.py


--------------------------------------------------------------------------------
/strawberry/aiohttp/test/__init__.py:
--------------------------------------------------------------------------------
1 | from .client import GraphQLTestClient
2 | 
3 | __all__ = ["GraphQLTestClient"]
4 | 


--------------------------------------------------------------------------------
/strawberry/asgi/test/__init__.py:
--------------------------------------------------------------------------------
1 | from .client import GraphQLTestClient
2 | 
3 | __all__ = ["GraphQLTestClient"]
4 | 


--------------------------------------------------------------------------------
/strawberry/chalice/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/strawberry/chalice/__init__.py


--------------------------------------------------------------------------------
/strawberry/channels/__init__.py:
--------------------------------------------------------------------------------
 1 | from .handlers.base import ChannelsConsumer
 2 | from .handlers.http_handler import (
 3 |     ChannelsRequest,
 4 |     GraphQLHTTPConsumer,
 5 |     SyncGraphQLHTTPConsumer,
 6 | )
 7 | from .handlers.ws_handler import GraphQLWSConsumer
 8 | from .router import GraphQLProtocolTypeRouter
 9 | 
10 | __all__ = [
11 |     "ChannelsConsumer",
12 |     "ChannelsRequest",
13 |     "GraphQLHTTPConsumer",
14 |     "GraphQLProtocolTypeRouter",
15 |     "GraphQLWSConsumer",
16 |     "SyncGraphQLHTTPConsumer",
17 | ]
18 | 


--------------------------------------------------------------------------------
/strawberry/channels/handlers/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/strawberry/channels/handlers/__init__.py


--------------------------------------------------------------------------------
/strawberry/cli/__init__.py:
--------------------------------------------------------------------------------
 1 | try:
 2 |     from .app import app
 3 |     from .commands.codegen import codegen as codegen  # noqa: PLC0414
 4 |     from .commands.export_schema import export_schema as export_schema  # noqa: PLC0414
 5 |     from .commands.locate_definition import (
 6 |         locate_definition as locate_definition,  # noqa: PLC0414
 7 |     )
 8 |     from .commands.schema_codegen import (
 9 |         schema_codegen as schema_codegen,  # noqa: PLC0414
10 |     )
11 |     from .commands.server import server as server  # noqa: PLC0414
12 |     from .commands.upgrade import upgrade as upgrade  # noqa: PLC0414
13 | 
14 |     def run() -> None:
15 |         app()
16 | 
17 | except ModuleNotFoundError as exc:
18 |     from strawberry.exceptions import MissingOptionalDependenciesError
19 | 
20 |     raise MissingOptionalDependenciesError(extras=["cli"]) from exc
21 | 


--------------------------------------------------------------------------------
/strawberry/cli/app.py:
--------------------------------------------------------------------------------
1 | import typer
2 | 
3 | app = typer.Typer(no_args_is_help=True)
4 | 


--------------------------------------------------------------------------------
/strawberry/cli/commands/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/strawberry/cli/commands/__init__.py


--------------------------------------------------------------------------------
/strawberry/cli/commands/export_schema.py:
--------------------------------------------------------------------------------
 1 | from pathlib import Path
 2 | 
 3 | import typer
 4 | 
 5 | from strawberry.cli.app import app
 6 | from strawberry.cli.utils import load_schema
 7 | from strawberry.printer import print_schema
 8 | 
 9 | 
10 | @app.command(help="Exports the schema")
11 | def export_schema(
12 |     schema: str,
13 |     app_dir: str = typer.Option(
14 |         ".",
15 |         "--app-dir",
16 |         show_default=True,
17 |         help=(
18 |             "Look for the module in the specified directory, by adding this to the "
19 |             "PYTHONPATH. Defaults to the current working directory. "
20 |             "Works the same as `--app-dir` in uvicorn."
21 |         ),
22 |     ),
23 |     output: Path = typer.Option(
24 |         None,
25 |         "--output",
26 |         "-o",
27 |         help="File to save the exported schema. If not provided, prints to console.",
28 |     ),
29 | ) -> None:
30 |     schema_symbol = load_schema(schema, app_dir)
31 | 
32 |     schema_text = print_schema(schema_symbol)
33 | 
34 |     if output:
35 |         Path(output).write_text(schema_text + "\n", encoding="utf-8")
36 |         typer.echo(f"Schema exported to {output}")
37 |     else:
38 |         print(schema_text)  # noqa: T201
39 | 


--------------------------------------------------------------------------------
/strawberry/cli/commands/locate_definition.py:
--------------------------------------------------------------------------------
 1 | import sys
 2 | 
 3 | import typer
 4 | from rich.console import Console
 5 | 
 6 | from strawberry.cli.app import app
 7 | from strawberry.cli.utils import load_schema
 8 | from strawberry.utils.locate_definition import (
 9 |     locate_definition as locate_definition_util,
10 | )
11 | 
12 | err_console = Console(stderr=True)
13 | 
14 | 
15 | @app.command(help="Locate a definition in the schema (output: path:line:column)")
16 | def locate_definition(
17 |     schema: str,
18 |     symbol: str,
19 |     app_dir: str = typer.Option(
20 |         ".",
21 |         "--app-dir",
22 |         show_default=True,
23 |         help=(
24 |             "Look for the module in the specified directory, by adding this to the "
25 |             "PYTHONPATH. Defaults to the current working directory. "
26 |             "Works the same as `--app-dir` in uvicorn."
27 |         ),
28 |     ),
29 | ) -> None:
30 |     schema_symbol = load_schema(schema, app_dir)
31 | 
32 |     if location := locate_definition_util(schema_symbol, symbol):
33 |         typer.echo(location)
34 |     else:
35 |         err_console.print(f"Definition not found: {symbol}")
36 |         sys.exit(1)
37 | 


--------------------------------------------------------------------------------
/strawberry/cli/commands/schema_codegen.py:
--------------------------------------------------------------------------------
 1 | from pathlib import Path
 2 | from typing import Optional
 3 | 
 4 | import typer
 5 | 
 6 | from strawberry.cli.app import app
 7 | from strawberry.schema_codegen import codegen
 8 | 
 9 | 
10 | @app.command(help="Generate code from a query")
11 | def schema_codegen(
12 |     schema: Path = typer.Argument(exists=True),
13 |     output: Optional[Path] = typer.Option(
14 |         None,
15 |         "-o",
16 |         "--output",
17 |         file_okay=True,
18 |         dir_okay=False,
19 |         writable=True,
20 |         resolve_path=True,
21 |     ),
22 | ) -> None:
23 |     generated_output = codegen(schema.read_text())
24 | 
25 |     if output is None:
26 |         typer.echo(generated_output)
27 |         return
28 | 
29 |     output.parent.mkdir(parents=True, exist_ok=True)
30 |     output.write_text(generated_output)
31 | 
32 |     typer.echo(f"Code generated at `{output.name}`")
33 | 


--------------------------------------------------------------------------------
/strawberry/cli/commands/upgrade/_fake_progress.py:
--------------------------------------------------------------------------------
 1 | from typing import Any
 2 | 
 3 | from rich.progress import TaskID
 4 | 
 5 | 
 6 | class FakeProgress:
 7 |     """A fake progress bar that does nothing.
 8 | 
 9 |     This is used when the user has only one file to process.
10 |     """
11 | 
12 |     def advance(self, task_id: TaskID) -> None:
13 |         pass
14 | 
15 |     def add_task(self, *args: Any, **kwargs: Any) -> TaskID:
16 |         return TaskID(0)
17 | 
18 |     def __enter__(self) -> "FakeProgress":
19 |         return self
20 | 
21 |     def __exit__(self, *args: object, **kwargs: Any) -> None:
22 |         pass
23 | 


--------------------------------------------------------------------------------
/strawberry/cli/constants.py:
--------------------------------------------------------------------------------
1 | DEBUG_SERVER_SCHEMA_ENV_VAR_KEY = "STRAWBERRY_DEBUG_SERVER_SCHEMA"
2 | DEBUG_SERVER_LOG_OPERATIONS = "STRAWBERRY_DEBUG_SERVER_LOG_OPERATIONS"
3 | 


--------------------------------------------------------------------------------
/strawberry/cli/debug_server.py:
--------------------------------------------------------------------------------
 1 | import os
 2 | from typing import Any
 3 | 
 4 | from starlette.applications import Starlette
 5 | from starlette.middleware.cors import CORSMiddleware
 6 | 
 7 | from strawberry import Schema
 8 | from strawberry.asgi import GraphQL
 9 | from strawberry.cli.constants import (
10 |     DEBUG_SERVER_LOG_OPERATIONS,
11 |     DEBUG_SERVER_SCHEMA_ENV_VAR_KEY,
12 | )
13 | from strawberry.utils.importer import import_module_symbol
14 | 
15 | app = Starlette(debug=True)
16 | app.add_middleware(
17 |     CORSMiddleware, allow_headers=["*"], allow_origins=["*"], allow_methods=["*"]
18 | )
19 | 
20 | schema_import_string = os.environ[DEBUG_SERVER_SCHEMA_ENV_VAR_KEY]
21 | schema_symbol = import_module_symbol(schema_import_string, default_symbol_name="schema")
22 | log_operations = os.environ[DEBUG_SERVER_LOG_OPERATIONS] == "True"
23 | 
24 | assert isinstance(schema_symbol, Schema)
25 | graphql_app = GraphQL[Any, Any](schema_symbol, debug=log_operations)
26 | 
27 | paths = ["/", "/graphql"]
28 | for path in paths:
29 |     app.add_route(path, graphql_app)  # type: ignore
30 |     app.add_websocket_route(path, graphql_app)  # type: ignore
31 | 


--------------------------------------------------------------------------------
/strawberry/cli/utils/__init__.py:
--------------------------------------------------------------------------------
 1 | import sys
 2 | 
 3 | import rich
 4 | import typer
 5 | 
 6 | from strawberry import Schema
 7 | from strawberry.utils.importer import import_module_symbol
 8 | 
 9 | 
10 | def load_schema(schema: str, app_dir: str) -> Schema:
11 |     sys.path.insert(0, app_dir)
12 | 
13 |     try:
14 |         schema_symbol = import_module_symbol(schema, default_symbol_name="schema")
15 |     except (ImportError, AttributeError) as exc:
16 |         message = str(exc)
17 | 
18 |         rich.print(f"[red]Error: {message}")
19 |         raise typer.Exit(2)  # noqa: B904
20 | 
21 |     if callable(schema_symbol):
22 |         try:
23 |             schema_symbol = schema_symbol()
24 |         except Exception as exc:  # noqa: BLE001
25 |             message = f"Error invoking schema_symbol: {exc}"
26 |             rich.print(f"[red]Error: {message}")
27 |             raise typer.Exit(2)  # noqa: B904
28 | 
29 |     if not isinstance(schema_symbol, Schema):
30 |         message = "The `schema` must be an instance of strawberry.Schema"
31 |         rich.print(f"[red]Error: {message}")
32 |         raise typer.Exit(2)
33 | 
34 |     return schema_symbol
35 | 


--------------------------------------------------------------------------------
/strawberry/cli/utils/load_schema.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/strawberry/cli/utils/load_schema.py


--------------------------------------------------------------------------------
/strawberry/codegen/__init__.py:
--------------------------------------------------------------------------------
 1 | from .query_codegen import (
 2 |     CodegenFile,
 3 |     CodegenResult,
 4 |     ConsolePlugin,
 5 |     QueryCodegen,
 6 |     QueryCodegenPlugin,
 7 | )
 8 | 
 9 | __all__ = [
10 |     "CodegenFile",
11 |     "CodegenResult",
12 |     "ConsolePlugin",
13 |     "QueryCodegen",
14 |     "QueryCodegenPlugin",
15 | ]
16 | 


--------------------------------------------------------------------------------
/strawberry/codegen/exceptions.py:
--------------------------------------------------------------------------------
 1 | class CodegenError(Exception):
 2 |     pass
 3 | 
 4 | 
 5 | class NoOperationProvidedError(CodegenError):
 6 |     pass
 7 | 
 8 | 
 9 | class NoOperationNameProvidedError(CodegenError):
10 |     pass
11 | 
12 | 
13 | class MultipleOperationsProvidedError(CodegenError):
14 |     pass
15 | 
16 | 
17 | __all__ = [
18 |     "CodegenError",
19 |     "MultipleOperationsProvidedError",
20 |     "NoOperationNameProvidedError",
21 |     "NoOperationProvidedError",
22 | ]
23 | 


--------------------------------------------------------------------------------
/strawberry/codegen/plugins/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/strawberry/codegen/plugins/__init__.py


--------------------------------------------------------------------------------
/strawberry/codemods/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/strawberry/codemods/__init__.py


--------------------------------------------------------------------------------
/strawberry/django/__init__.py:
--------------------------------------------------------------------------------
 1 | from typing import Any
 2 | 
 3 | try:
 4 |     # import modules and objects from external strawberry-graphql-django
 5 |     # package so that it can be used through strawberry.django namespace
 6 |     from strawberry_django import *  # noqa: F403
 7 | except ModuleNotFoundError:
 8 |     import importlib
 9 | 
10 |     def __getattr__(name: str) -> Any:
11 |         # try to import submodule and raise exception only if it does not exist
12 |         import_symbol = f"{__name__}.{name}"
13 |         try:
14 |             return importlib.import_module(import_symbol)
15 |         except ModuleNotFoundError as e:
16 |             raise AttributeError(
17 |                 f"Attempted import of {import_symbol} failed. Make sure to install the"
18 |                 "'strawberry-graphql-django' package to use the Strawberry Django "
19 |                 "extension API."
20 |             ) from e
21 | 


--------------------------------------------------------------------------------
/strawberry/django/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig  # pragma: no cover
2 | 
3 | 
4 | class StrawberryConfig(AppConfig):  # pragma: no cover
5 |     name = "strawberry"
6 | 


--------------------------------------------------------------------------------
/strawberry/django/context.py:
--------------------------------------------------------------------------------
 1 | from __future__ import annotations
 2 | 
 3 | from dataclasses import dataclass
 4 | from typing import TYPE_CHECKING, Any
 5 | 
 6 | if TYPE_CHECKING:
 7 |     from django.http import HttpRequest, HttpResponse
 8 | 
 9 | 
10 | @dataclass
11 | class StrawberryDjangoContext:
12 |     request: HttpRequest
13 |     response: HttpResponse
14 | 
15 |     def __getitem__(self, key: str) -> Any:
16 |         # __getitem__ override needed to avoid issues for who's
17 |         # using info.context["request"]
18 |         return super().__getattribute__(key)
19 | 
20 |     def get(self, key: str) -> Any:
21 |         """Enable .get notation for accessing the request."""
22 |         return super().__getattribute__(key)
23 | 
24 | 
25 | __all__ = ["StrawberryDjangoContext"]
26 | 


--------------------------------------------------------------------------------
/strawberry/django/test/__init__.py:
--------------------------------------------------------------------------------
1 | from .client import GraphQLTestClient
2 | 
3 | __all__ = ["GraphQLTestClient"]
4 | 


--------------------------------------------------------------------------------
/strawberry/django/test/client.py:
--------------------------------------------------------------------------------
 1 | from typing import Any, Optional
 2 | 
 3 | from strawberry.test import BaseGraphQLTestClient
 4 | 
 5 | 
 6 | class GraphQLTestClient(BaseGraphQLTestClient):
 7 |     def request(
 8 |         self,
 9 |         body: dict[str, object],
10 |         headers: Optional[dict[str, object]] = None,
11 |         files: Optional[dict[str, object]] = None,
12 |     ) -> Any:
13 |         if files:
14 |             return self._client.post(
15 |                 self.url, data=body, format="multipart", headers=headers
16 |             )
17 | 
18 |         return self._client.post(
19 |             self.url, data=body, content_type="application/json", headers=headers
20 |         )
21 | 
22 | 
23 | __all__ = ["GraphQLTestClient"]
24 | 


--------------------------------------------------------------------------------
/strawberry/exceptions/exception_source.py:
--------------------------------------------------------------------------------
 1 | from dataclasses import dataclass
 2 | from pathlib import Path
 3 | 
 4 | 
 5 | @dataclass
 6 | class ExceptionSource:
 7 |     path: Path
 8 |     code: str
 9 |     start_line: int
10 |     end_line: int
11 |     error_line: int
12 |     error_column: int
13 |     error_column_end: int
14 | 
15 |     @property
16 |     def path_relative_to_cwd(self) -> Path:
17 |         if self.path.is_absolute():
18 |             return self.path.relative_to(Path.cwd())
19 | 
20 |         return self.path
21 | 


--------------------------------------------------------------------------------
/strawberry/exceptions/missing_dependencies.py:
--------------------------------------------------------------------------------
 1 | from __future__ import annotations
 2 | 
 3 | from typing import Optional
 4 | 
 5 | 
 6 | class MissingOptionalDependenciesError(Exception):
 7 |     """Some optional dependencies that are required for a particular task are missing."""
 8 | 
 9 |     def __init__(
10 |         self,
11 |         *,
12 |         packages: Optional[list[str]] = None,
13 |         extras: Optional[list[str]] = None,
14 |     ) -> None:
15 |         """Initialize the error.
16 | 
17 |         Args:
18 |             packages: List of packages that are required but missing.
19 |             extras: List of extras that are required but missing.
20 |         """
21 |         packages = packages or []
22 | 
23 |         if extras:
24 |             packages.append(f"'strawberry-graphql[{','.join(extras)}]'")
25 | 
26 |         hint = f" (hint: pip install {' '.join(packages)})" if packages else ""
27 | 
28 |         self.message = f"Some optional dependencies are missing{hint}"
29 | 


--------------------------------------------------------------------------------
/strawberry/exceptions/utils/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/strawberry/exceptions/utils/__init__.py


--------------------------------------------------------------------------------
/strawberry/experimental/__init__.py:
--------------------------------------------------------------------------------
1 | try:
2 |     from . import pydantic
3 | except ModuleNotFoundError:
4 |     pass
5 | else:
6 |     __all__ = ["pydantic"]
7 | 


--------------------------------------------------------------------------------
/strawberry/experimental/pydantic/__init__.py:
--------------------------------------------------------------------------------
 1 | from .error_type import error_type
 2 | from .exceptions import UnregisteredTypeException
 3 | from .object_type import input, interface, type  # noqa: A004
 4 | 
 5 | __all__ = [
 6 |     "UnregisteredTypeException",
 7 |     "error_type",
 8 |     "input",
 9 |     "interface",
10 |     "type",
11 | ]
12 | 


--------------------------------------------------------------------------------
/strawberry/experimental/pydantic/conversion_types.py:
--------------------------------------------------------------------------------
 1 | from __future__ import annotations
 2 | 
 3 | from typing import TYPE_CHECKING, Any, Optional, TypeVar
 4 | from typing_extensions import Protocol
 5 | 
 6 | from pydantic import BaseModel
 7 | 
 8 | if TYPE_CHECKING:
 9 |     from strawberry.types.base import StrawberryObjectDefinition
10 | 
11 | 
12 | PydanticModel = TypeVar("PydanticModel", bound=BaseModel)
13 | 
14 | 
15 | class StrawberryTypeFromPydantic(Protocol[PydanticModel]):
16 |     """This class does not exist in runtime.
17 | 
18 |     It only makes the methods below visible for IDEs.
19 |     """
20 | 
21 |     def __init__(self, **kwargs: Any) -> None: ...
22 | 
23 |     @staticmethod
24 |     def from_pydantic(
25 |         instance: PydanticModel, extra: Optional[dict[str, Any]] = None
26 |     ) -> StrawberryTypeFromPydantic[PydanticModel]: ...
27 | 
28 |     def to_pydantic(self, **kwargs: Any) -> PydanticModel: ...
29 | 
30 |     @property
31 |     def __strawberry_definition__(self) -> StrawberryObjectDefinition: ...
32 | 
33 |     @property
34 |     def _pydantic_type(self) -> type[PydanticModel]: ...
35 | 


--------------------------------------------------------------------------------
/strawberry/ext/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/strawberry/ext/__init__.py


--------------------------------------------------------------------------------
/strawberry/ext/dataclasses/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/strawberry/ext/dataclasses/__init__.py


--------------------------------------------------------------------------------
/strawberry/extensions/disable_introspection.py:
--------------------------------------------------------------------------------
 1 | from graphql.validation import NoSchemaIntrospectionCustomRule
 2 | 
 3 | from strawberry.extensions import AddValidationRules
 4 | 
 5 | 
 6 | class DisableIntrospection(AddValidationRules):
 7 |     """Disable introspection queries.
 8 | 
 9 |     Example:
10 | 
11 |     ```python
12 |     import strawberry
13 |     from strawberry.extensions import DisableIntrospection
14 | 
15 | 
16 |     @strawberry.type
17 |     class Query:
18 |         @strawberry.field
19 |         def hello(self) -> str:
20 |             return "Hello, world!"
21 | 
22 | 
23 |     schema = strawberry.Schema(
24 |         Query,
25 |         extensions=[
26 |             DisableIntrospection(),
27 |         ],
28 |     )
29 |     ```
30 |     """
31 | 
32 |     def __init__(self) -> None:
33 |         super().__init__([NoSchemaIntrospectionCustomRule])
34 | 
35 | 
36 | __all__ = ["DisableIntrospection"]
37 | 


--------------------------------------------------------------------------------
/strawberry/extensions/disable_validation.py:
--------------------------------------------------------------------------------
 1 | from collections.abc import Iterator
 2 | 
 3 | from strawberry.extensions.base_extension import SchemaExtension
 4 | 
 5 | 
 6 | class DisableValidation(SchemaExtension):
 7 |     """Disable query validation.
 8 | 
 9 |     Example:
10 | 
11 |     ```python
12 |     import strawberry
13 |     from strawberry.extensions import DisableValidation
14 | 
15 |     schema = strawberry.Schema(
16 |         Query,
17 |         extensions=[
18 |             DisableValidation,
19 |         ],
20 |     )
21 |     ```
22 |     """
23 | 
24 |     def __init__(self) -> None:
25 |         # There aren't any arguments to this extension yet but we might add
26 |         # some in the future
27 |         pass
28 | 
29 |     def on_operation(self) -> Iterator[None]:
30 |         self.execution_context.validation_rules = ()  # remove all validation_rules
31 |         yield
32 | 
33 | 
34 | __all__ = ["DisableValidation"]
35 | 


--------------------------------------------------------------------------------
/strawberry/extensions/pyinstrument.py:
--------------------------------------------------------------------------------
 1 | from __future__ import annotations
 2 | 
 3 | from pathlib import Path
 4 | from typing import TYPE_CHECKING
 5 | 
 6 | from pyinstrument import Profiler
 7 | 
 8 | from strawberry.extensions.base_extension import SchemaExtension
 9 | 
10 | if TYPE_CHECKING:
11 |     from collections.abc import Iterator
12 | 
13 | 
14 | class PyInstrument(SchemaExtension):
15 |     """Extension to profile the execution time of resolvers using PyInstrument."""
16 | 
17 |     def __init__(
18 |         self,
19 |         report_path: Path = Path("pyinstrument.html"),
20 |     ) -> None:
21 |         self._report_path = report_path
22 | 
23 |     def on_operation(self) -> Iterator[None]:
24 |         profiler = Profiler()
25 |         profiler.start()
26 | 
27 |         yield
28 | 
29 |         profiler.stop()
30 | 
31 |         self._report_path.write_text(profiler.output_html())
32 | 
33 | 
34 | __all__ = ["PyInstrument"]
35 | 


--------------------------------------------------------------------------------
/strawberry/extensions/tracing/utils.py:
--------------------------------------------------------------------------------
 1 | from __future__ import annotations
 2 | 
 3 | from typing import TYPE_CHECKING, Any, Callable
 4 | 
 5 | from strawberry.extensions.utils import is_introspection_field
 6 | from strawberry.resolvers import is_default_resolver
 7 | 
 8 | if TYPE_CHECKING:
 9 |     from graphql import GraphQLResolveInfo
10 | 
11 | 
12 | def should_skip_tracing(resolver: Callable[..., Any], info: GraphQLResolveInfo) -> bool:
13 |     if info.field_name not in info.parent_type.fields:
14 |         return True
15 |     resolver = info.parent_type.fields[info.field_name].resolve
16 |     return (
17 |         is_introspection_field(info)
18 |         or is_default_resolver(resolver)
19 |         or resolver is None
20 |     )
21 | 
22 | 
23 | __all__ = ["should_skip_tracing"]
24 | 


--------------------------------------------------------------------------------
/strawberry/extensions/utils.py:
--------------------------------------------------------------------------------
 1 | from __future__ import annotations
 2 | 
 3 | from typing import TYPE_CHECKING, Union
 4 | 
 5 | if TYPE_CHECKING:
 6 |     from graphql import GraphQLResolveInfo
 7 | 
 8 | 
 9 | def is_introspection_key(key: Union[str, int]) -> bool:
10 |     # from: https://spec.graphql.org/June2018/#sec-Schema
11 |     # > All types and directives defined within a schema must not have a name which
12 |     # > begins with "__" (two underscores), as this is used exclusively
13 |     # > by GraphQL`s introspection system.
14 | 
15 |     return str(key).startswith("__")
16 | 
17 | 
18 | def is_introspection_field(info: GraphQLResolveInfo) -> bool:
19 |     path = info.path
20 | 
21 |     while path:
22 |         if is_introspection_key(path.key):
23 |             return True
24 |         path = path.prev
25 | 
26 |     return False
27 | 
28 | 
29 | def get_path_from_info(info: GraphQLResolveInfo) -> list[str]:
30 |     path = info.path
31 |     elements = []
32 | 
33 |     while path:
34 |         elements.append(path.key)
35 |         path = path.prev
36 | 
37 |     return elements[::-1]
38 | 
39 | 
40 | __all__ = ["get_path_from_info", "is_introspection_field", "is_introspection_key"]
41 | 


--------------------------------------------------------------------------------
/strawberry/fastapi/__init__.py:
--------------------------------------------------------------------------------
1 | from strawberry.fastapi.context import BaseContext
2 | from strawberry.fastapi.router import GraphQLRouter
3 | 
4 | __all__ = ["BaseContext", "GraphQLRouter"]
5 | 


--------------------------------------------------------------------------------
/strawberry/fastapi/context.py:
--------------------------------------------------------------------------------
 1 | from typing import Any, Optional, Union
 2 | 
 3 | from starlette.background import BackgroundTasks
 4 | from starlette.requests import Request
 5 | from starlette.responses import Response
 6 | from starlette.websockets import WebSocket
 7 | 
 8 | CustomContext = Union["BaseContext", dict[str, Any]]
 9 | MergedContext = Union[
10 |     "BaseContext", dict[str, Union[Any, BackgroundTasks, Request, Response, WebSocket]]
11 | ]
12 | 
13 | 
14 | class BaseContext:
15 |     connection_params: Optional[Any] = None
16 | 
17 |     def __init__(self) -> None:
18 |         self.request: Optional[Union[Request, WebSocket]] = None
19 |         self.background_tasks: Optional[BackgroundTasks] = None
20 |         self.response: Optional[Response] = None
21 | 
22 | 
23 | __all__ = ["BaseContext"]
24 | 


--------------------------------------------------------------------------------
/strawberry/federation/__init__.py:
--------------------------------------------------------------------------------
 1 | from .argument import argument
 2 | from .enum import enum, enum_value
 3 | from .field import field
 4 | from .mutation import mutation
 5 | from .object_type import input, interface, interface_object, type  # noqa: A004
 6 | from .scalar import scalar
 7 | from .schema import Schema
 8 | from .schema_directive import schema_directive
 9 | from .union import union
10 | 
11 | __all__ = [
12 |     "Schema",
13 |     "argument",
14 |     "enum",
15 |     "enum_value",
16 |     "field",
17 |     "input",
18 |     "interface",
19 |     "interface_object",
20 |     "mutation",
21 |     "scalar",
22 |     "schema_directive",
23 |     "type",
24 |     "union",
25 | ]
26 | 


--------------------------------------------------------------------------------
/strawberry/federation/argument.py:
--------------------------------------------------------------------------------
 1 | from collections.abc import Iterable
 2 | from typing import Optional
 3 | 
 4 | from strawberry.types.arguments import StrawberryArgumentAnnotation
 5 | 
 6 | 
 7 | def argument(
 8 |     description: Optional[str] = None,
 9 |     name: Optional[str] = None,
10 |     deprecation_reason: Optional[str] = None,
11 |     directives: Iterable[object] = (),
12 |     inaccessible: bool = False,
13 |     tags: Optional[Iterable[str]] = (),
14 | ) -> StrawberryArgumentAnnotation:
15 |     from strawberry.federation.schema_directives import Inaccessible, Tag
16 | 
17 |     directives = list(directives)
18 | 
19 |     if inaccessible:
20 |         directives.append(Inaccessible())
21 | 
22 |     if tags:
23 |         directives.extend(Tag(name=tag) for tag in tags)
24 | 
25 |     return StrawberryArgumentAnnotation(
26 |         description=description,
27 |         name=name,
28 |         deprecation_reason=deprecation_reason,
29 |         directives=directives,
30 |     )
31 | 
32 | 
33 | __all__ = ["argument"]
34 | 


--------------------------------------------------------------------------------
/strawberry/federation/mutation.py:
--------------------------------------------------------------------------------
1 | from .field import field
2 | 
3 | mutation = field
4 | 
5 | __all__ = ["mutation"]
6 | 


--------------------------------------------------------------------------------
/strawberry/federation/types.py:
--------------------------------------------------------------------------------
 1 | from enum import Enum
 2 | 
 3 | from strawberry.types.enum import enum
 4 | from strawberry.types.scalar import scalar
 5 | 
 6 | FieldSet = scalar(str, name="_FieldSet")
 7 | 
 8 | LinkImport = scalar(object, name="link__Import")
 9 | 
10 | 
11 | @enum(name="link__Purpose")
12 | class LinkPurpose(Enum):
13 |     SECURITY = "SECURITY"
14 |     EXECUTION = "EXECUTION"
15 | 
16 | 
17 | __all__ = ["FieldSet", "LinkImport", "LinkPurpose"]
18 | 


--------------------------------------------------------------------------------
/strawberry/field_extensions/__init__.py:
--------------------------------------------------------------------------------
1 | from .input_mutation import InputMutationExtension
2 | 
3 | __all__ = [
4 |     "InputMutationExtension",
5 | ]
6 | 


--------------------------------------------------------------------------------
/strawberry/file_uploads/__init__.py:
--------------------------------------------------------------------------------
1 | from .scalars import Upload
2 | 
3 | __all__ = ["Upload"]
4 | 


--------------------------------------------------------------------------------
/strawberry/file_uploads/scalars.py:
--------------------------------------------------------------------------------
1 | from typing import NewType
2 | 
3 | from strawberry.types.scalar import scalar
4 | 
5 | Upload = scalar(NewType("Upload", bytes), parse_value=lambda x: x)
6 | 
7 | __all__ = ["Upload"]
8 | 


--------------------------------------------------------------------------------
/strawberry/flask/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/strawberry/flask/__init__.py


--------------------------------------------------------------------------------
/strawberry/http/exceptions.py:
--------------------------------------------------------------------------------
 1 | class HTTPException(Exception):
 2 |     def __init__(self, status_code: int, reason: str) -> None:
 3 |         self.status_code = status_code
 4 |         self.reason = reason
 5 | 
 6 | 
 7 | class NonTextMessageReceived(Exception):
 8 |     pass
 9 | 
10 | 
11 | class NonJsonMessageReceived(Exception):
12 |     pass
13 | 
14 | 
15 | class WebSocketDisconnected(Exception):
16 |     pass
17 | 
18 | 
19 | __all__ = ["HTTPException"]
20 | 


--------------------------------------------------------------------------------
/strawberry/http/ides.py:
--------------------------------------------------------------------------------
 1 | import pathlib
 2 | from typing import Optional
 3 | from typing_extensions import Literal
 4 | 
 5 | GraphQL_IDE = Literal["graphiql", "apollo-sandbox", "pathfinder"]
 6 | 
 7 | 
 8 | def get_graphql_ide_html(
 9 |     graphql_ide: Optional[GraphQL_IDE] = "graphiql",
10 | ) -> str:
11 |     here = pathlib.Path(__file__).parents[1]
12 | 
13 |     if graphql_ide == "apollo-sandbox":
14 |         path = here / "static/apollo-sandbox.html"
15 |     elif graphql_ide == "pathfinder":
16 |         path = here / "static/pathfinder.html"
17 |     else:
18 |         path = here / "static/graphiql.html"
19 | 
20 |     return path.read_text(encoding="utf-8")
21 | 
22 | 
23 | __all__ = ["GraphQL_IDE", "get_graphql_ide_html"]
24 | 


--------------------------------------------------------------------------------
/strawberry/http/parse_content_type.py:
--------------------------------------------------------------------------------
 1 | from email.message import Message
 2 | 
 3 | 
 4 | def parse_content_type(content_type: str) -> tuple[str, dict[str, str]]:
 5 |     """Parse a content type header into a mime-type and a dictionary of parameters."""
 6 |     email = Message()
 7 |     email["content-type"] = content_type
 8 | 
 9 |     params = email.get_params()
10 | 
11 |     assert params
12 | 
13 |     mime_type, _ = params.pop(0)
14 | 
15 |     return mime_type, dict(params)
16 | 


--------------------------------------------------------------------------------
/strawberry/http/temporal_response.py:
--------------------------------------------------------------------------------
 1 | from dataclasses import dataclass, field
 2 | 
 3 | 
 4 | @dataclass
 5 | class TemporalResponse:
 6 |     status_code: int = 200
 7 |     headers: dict[str, str] = field(default_factory=dict)
 8 | 
 9 | 
10 | __all__ = ["TemporalResponse"]
11 | 


--------------------------------------------------------------------------------
/strawberry/http/types.py:
--------------------------------------------------------------------------------
 1 | from collections.abc import Mapping
 2 | from typing import Any, Optional
 3 | from typing_extensions import Literal, TypedDict
 4 | 
 5 | HTTPMethod = Literal[
 6 |     "GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS", "TRACE"
 7 | ]
 8 | 
 9 | QueryParams = Mapping[str, Optional[str]]
10 | 
11 | 
12 | class FormData(TypedDict):
13 |     files: Mapping[str, Any]
14 |     form: Mapping[str, Any]
15 | 
16 | 
17 | __all__ = ["FormData", "HTTPMethod", "QueryParams"]
18 | 


--------------------------------------------------------------------------------
/strawberry/http/typevars.py:
--------------------------------------------------------------------------------
 1 | from typing_extensions import TypeVar
 2 | 
 3 | Request = TypeVar("Request", contravariant=True)
 4 | Response = TypeVar("Response")
 5 | SubResponse = TypeVar("SubResponse")
 6 | WebSocketRequest = TypeVar("WebSocketRequest")
 7 | WebSocketResponse = TypeVar("WebSocketResponse")
 8 | Context = TypeVar("Context", default=None)
 9 | RootValue = TypeVar("RootValue", default=None)
10 | 
11 | 
12 | __all__ = [
13 |     "Context",
14 |     "Request",
15 |     "Response",
16 |     "RootValue",
17 |     "SubResponse",
18 |     "WebSocketRequest",
19 |     "WebSocketResponse",
20 | ]
21 | 


--------------------------------------------------------------------------------
/strawberry/litestar/__init__.py:
--------------------------------------------------------------------------------
 1 | from .controller import (
 2 |     BaseContext,
 3 |     HTTPContextType,
 4 |     WebSocketContextType,
 5 |     make_graphql_controller,
 6 | )
 7 | 
 8 | __all__ = [
 9 |     "BaseContext",
10 |     "HTTPContextType",
11 |     "WebSocketContextType",
12 |     "make_graphql_controller",
13 | ]
14 | 


--------------------------------------------------------------------------------
/strawberry/printer/__init__.py:
--------------------------------------------------------------------------------
1 | from .printer import print_schema
2 | 
3 | __all__ = ["print_schema"]
4 | 


--------------------------------------------------------------------------------
/strawberry/py.typed:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/strawberry/py.typed


--------------------------------------------------------------------------------
/strawberry/quart/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/strawberry/quart/__init__.py


--------------------------------------------------------------------------------
/strawberry/relay/__init__.py:
--------------------------------------------------------------------------------
 1 | from .fields import ConnectionExtension, NodeExtension, connection, node
 2 | from .types import (
 3 |     Connection,
 4 |     Edge,
 5 |     GlobalID,
 6 |     GlobalIDValueError,
 7 |     ListConnection,
 8 |     Node,
 9 |     NodeID,
10 |     NodeType,
11 |     PageInfo,
12 | )
13 | from .utils import from_base64, to_base64
14 | 
15 | __all__ = [
16 |     "Connection",
17 |     "ConnectionExtension",
18 |     "Edge",
19 |     "GlobalID",
20 |     "GlobalIDValueError",
21 |     "ListConnection",
22 |     "Node",
23 |     "NodeExtension",
24 |     "NodeID",
25 |     "NodeType",
26 |     "PageInfo",
27 |     "connection",
28 |     "from_base64",
29 |     "node",
30 |     "to_base64",
31 | ]
32 | 


--------------------------------------------------------------------------------
/strawberry/resolvers.py:
--------------------------------------------------------------------------------
 1 | from typing import Any, Callable
 2 | 
 3 | 
 4 | def is_default_resolver(func: Callable[..., Any]) -> bool:
 5 |     """Check whether the function is a default resolver or a user provided one."""
 6 |     return getattr(func, "_is_default", False)
 7 | 
 8 | 
 9 | __all__ = ["is_default_resolver"]
10 | 


--------------------------------------------------------------------------------
/strawberry/sanic/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/strawberry/sanic/__init__.py


--------------------------------------------------------------------------------
/strawberry/sanic/context.py:
--------------------------------------------------------------------------------
 1 | import warnings
 2 | from typing_extensions import TypedDict
 3 | 
 4 | from sanic.request import Request
 5 | from strawberry.http.temporal_response import TemporalResponse
 6 | 
 7 | 
 8 | class StrawberrySanicContext(TypedDict):
 9 |     request: Request
10 |     response: TemporalResponse
11 | 
12 |     # see https://github.com/python/mypy/issues/13066 for the type ignore
13 |     def __getattr__(self, key: str) -> object:  # type: ignore
14 |         # a warning will be raised because this is not supported anymore
15 |         # but we need to keep it for backwards compatibility
16 | 
17 |         warnings.warn(
18 |             "Accessing context attributes via the dot notation is deprecated, "
19 |             "please use context.get('key') or context['key'] instead",
20 |             DeprecationWarning,
21 |             stacklevel=2,
22 |         )
23 | 
24 |         return super().__getitem__(key)
25 | 
26 | 
27 | __all__ = ["StrawberrySanicContext"]
28 | 


--------------------------------------------------------------------------------
/strawberry/sanic/utils.py:
--------------------------------------------------------------------------------
 1 | from __future__ import annotations
 2 | 
 3 | from typing import TYPE_CHECKING, Any, Optional, Union, cast
 4 | 
 5 | if TYPE_CHECKING:
 6 |     from sanic.request import File, Request
 7 | 
 8 | 
 9 | def convert_request_to_files_dict(request: Request) -> dict[str, Any]:
10 |     """Converts the request.files dictionary to a dictionary of sanic Request objects.
11 | 
12 |     `request.files` has the following format, even if only a single file is uploaded:
13 | 
14 |     ```python
15 |     {
16 |         "textFile": [
17 |             sanic.request.File(type="text/plain", body=b"strawberry", name="textFile.txt")
18 |         ]
19 |     }
20 |     ```
21 | 
22 |     Note that the dictionary entries are lists.
23 |     """
24 |     request_files = cast("Optional[dict[str, list[File]]]", request.files)
25 | 
26 |     if not request_files:
27 |         return {}
28 | 
29 |     files_dict: dict[str, Union[File, list[File]]] = {}
30 | 
31 |     for field_name, file_list in request_files.items():
32 |         assert len(file_list) == 1
33 | 
34 |         files_dict[field_name] = file_list[0]
35 | 
36 |     return files_dict
37 | 
38 | 
39 | __all__ = ["convert_request_to_files_dict"]
40 | 


--------------------------------------------------------------------------------
/strawberry/schema/__init__.py:
--------------------------------------------------------------------------------
1 | from .base import BaseSchema
2 | from .schema import Schema
3 | 
4 | __all__ = ["BaseSchema", "Schema"]
5 | 


--------------------------------------------------------------------------------
/strawberry/schema/config.py:
--------------------------------------------------------------------------------
 1 | from __future__ import annotations
 2 | 
 3 | from dataclasses import InitVar, dataclass, field
 4 | from typing import Any, Callable
 5 | 
 6 | from strawberry.types.info import Info
 7 | 
 8 | from .name_converter import NameConverter
 9 | 
10 | 
11 | @dataclass
12 | class StrawberryConfig:
13 |     auto_camel_case: InitVar[bool] = None  # pyright: reportGeneralTypeIssues=false
14 |     name_converter: NameConverter = field(default_factory=NameConverter)
15 |     default_resolver: Callable[[Any, str], object] = getattr
16 |     relay_max_results: int = 100
17 |     relay_use_legacy_global_id: bool = False
18 |     disable_field_suggestions: bool = False
19 |     info_class: type[Info] = Info
20 |     _unsafe_disable_same_type_validation: bool = False
21 | 
22 |     def __post_init__(
23 |         self,
24 |         auto_camel_case: bool,
25 |     ) -> None:
26 |         if auto_camel_case is not None:
27 |             self.name_converter.auto_camel_case = auto_camel_case
28 | 
29 |         if not issubclass(self.info_class, Info):
30 |             raise TypeError("`info_class` must be a subclass of strawberry.Info")
31 | 
32 | 
33 | __all__ = ["StrawberryConfig"]
34 | 


--------------------------------------------------------------------------------
/strawberry/schema/types/__init__.py:
--------------------------------------------------------------------------------
1 | from .concrete_type import ConcreteType
2 | 
3 | __all__ = ["ConcreteType"]
4 | 


--------------------------------------------------------------------------------
/strawberry/schema/types/concrete_type.py:
--------------------------------------------------------------------------------
 1 | from __future__ import annotations
 2 | 
 3 | import dataclasses
 4 | from typing import TYPE_CHECKING, Union
 5 | 
 6 | from graphql import GraphQLField, GraphQLInputField, GraphQLType
 7 | 
 8 | if TYPE_CHECKING:
 9 |     from strawberry.types.base import StrawberryObjectDefinition
10 |     from strawberry.types.enum import EnumDefinition
11 |     from strawberry.types.scalar import ScalarDefinition
12 |     from strawberry.types.union import StrawberryUnion
13 | 
14 | Field = Union[GraphQLInputField, GraphQLField]
15 | 
16 | 
17 | @dataclasses.dataclass
18 | class ConcreteType:
19 |     definition: Union[
20 |         StrawberryObjectDefinition, EnumDefinition, ScalarDefinition, StrawberryUnion
21 |     ]
22 |     implementation: GraphQLType
23 | 
24 | 
25 | TypeMap = dict[str, ConcreteType]
26 | 
27 | 
28 | __all__ = ["ConcreteType", "Field", "GraphQLType", "TypeMap"]
29 | 


--------------------------------------------------------------------------------
/strawberry/schema/validation_rules/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/strawberry/schema/validation_rules/__init__.py


--------------------------------------------------------------------------------
/strawberry/schema_directives.py:
--------------------------------------------------------------------------------
1 | from strawberry.schema_directive import Location, schema_directive
2 | 
3 | 
4 | @schema_directive(locations=[Location.INPUT_OBJECT], name="oneOf")
5 | class OneOf: ...
6 | 
7 | 
8 | __all__ = ["OneOf"]
9 | 


--------------------------------------------------------------------------------
/strawberry/static/apollo-sandbox.html:
--------------------------------------------------------------------------------
 1 | <!DOCTYPE html>
 2 | <html>
 3 |   <head>
 4 |     <title>Strawberry Apollo Sandbox</title>
 5 |     <link
 6 |       rel="icon"
 7 |       href="data:image/svg+xml,
 8 |         <svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22>
 9 |             <!-- Strawberry Emoji as a HTML Entity (hex)  -->
10 |             <text y=%22.9em%22 font-size=%2280%22>&#x1f353;</text>
11 |         </svg>"
12 |     />
13 |     <style>
14 |       body {
15 |         height: 100%;
16 |         margin: 0;
17 |         width: 100%;
18 |         overflow: hidden;
19 |       }
20 | 
21 |       #embedded-sandbox {
22 |         width: 100vw;
23 |         height: 100vh;
24 |       }
25 |     </style>
26 |   </head>
27 | 
28 |   <body>
29 |     <div id="embedded-sandbox"></div>
30 | 
31 |     <script src="https://embeddable-sandbox.cdn.apollographql.com/_latest/embeddable-sandbox.umd.production.min.js"></script>
32 |     <script>
33 |       new window.EmbeddedSandbox({
34 |         target: "#embedded-sandbox",
35 |         initialEndpoint: window.location.href,
36 |         hideCookieToggle: false,
37 |       });
38 |     </script>
39 |   </body>
40 | </html>
41 | 


--------------------------------------------------------------------------------
/strawberry/subscriptions/__init__.py:
--------------------------------------------------------------------------------
1 | GRAPHQL_TRANSPORT_WS_PROTOCOL = "graphql-transport-ws"
2 | GRAPHQL_WS_PROTOCOL = "graphql-ws"
3 | 
4 | 
5 | __all__ = [
6 |     "GRAPHQL_TRANSPORT_WS_PROTOCOL",
7 |     "GRAPHQL_WS_PROTOCOL",
8 | ]
9 | 


--------------------------------------------------------------------------------
/strawberry/subscriptions/protocols/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/strawberry/subscriptions/protocols/__init__.py


--------------------------------------------------------------------------------
/strawberry/subscriptions/protocols/graphql_transport_ws/__init__.py:
--------------------------------------------------------------------------------
1 | # Code 4406 is "Subprotocol not acceptable"
2 | WS_4406_PROTOCOL_NOT_ACCEPTABLE = 4406
3 | 
4 | 
5 | __all__ = [
6 |     "WS_4406_PROTOCOL_NOT_ACCEPTABLE",
7 | ]
8 | 


--------------------------------------------------------------------------------
/strawberry/subscriptions/protocols/graphql_ws/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/strawberry/subscriptions/protocols/graphql_ws/__init__.py


--------------------------------------------------------------------------------
/strawberry/test/__init__.py:
--------------------------------------------------------------------------------
1 | from .client import BaseGraphQLTestClient, Body, Response
2 | 
3 | __all__ = ["BaseGraphQLTestClient", "Body", "Response"]
4 | 


--------------------------------------------------------------------------------
/strawberry/tools/__init__.py:
--------------------------------------------------------------------------------
1 | from .create_type import create_type
2 | from .merge_types import merge_types
3 | 
4 | __all__ = [
5 |     "create_type",
6 |     "merge_types",
7 | ]
8 | 


--------------------------------------------------------------------------------
/strawberry/tools/merge_types.py:
--------------------------------------------------------------------------------
 1 | import warnings
 2 | from collections import Counter
 3 | from itertools import chain
 4 | 
 5 | import strawberry
 6 | from strawberry.types.base import has_object_definition
 7 | 
 8 | 
 9 | def merge_types(name: str, types: tuple[type, ...]) -> type:
10 |     """Merge multiple Strawberry types into one.
11 | 
12 |     For example, given two queries `A` and `B`, one can merge them into a
13 |     super type as follows:
14 | 
15 |         merge_types("SuperQuery", (B, A))
16 | 
17 |     This is essentially the same as:
18 | 
19 |         class SuperQuery(B, A):
20 |             ...
21 |     """
22 |     if not types:
23 |         raise ValueError("Can't merge types if none are supplied")
24 | 
25 |     fields = chain(
26 |         *(t.__strawberry_definition__.fields for t in types if has_object_definition(t))
27 |     )
28 |     counter = Counter(f.name for f in fields)
29 |     dupes = [f for f, c in counter.most_common() if c > 1]
30 |     if dupes:
31 |         warnings.warn(
32 |             "{} has overridden fields: {}".format(name, ", ".join(dupes)), stacklevel=2
33 |         )
34 | 
35 |     return strawberry.type(type(name, types, {}))
36 | 
37 | 
38 | __all__ = ["merge_types"]
39 | 


--------------------------------------------------------------------------------
/strawberry/types/__init__.py:
--------------------------------------------------------------------------------
 1 | from .base import get_object_definition, has_object_definition
 2 | from .execution import ExecutionContext, ExecutionResult, SubscriptionExecutionResult
 3 | from .info import Info
 4 | 
 5 | __all__ = [
 6 |     "ExecutionContext",
 7 |     "ExecutionResult",
 8 |     "Info",
 9 |     "Info",
10 |     "SubscriptionExecutionResult",
11 |     "get_object_definition",
12 |     "has_object_definition",
13 | ]
14 | 


--------------------------------------------------------------------------------
/strawberry/types/cast.py:
--------------------------------------------------------------------------------
 1 | from __future__ import annotations
 2 | 
 3 | from typing import Any, TypeVar, overload
 4 | 
 5 | _T = TypeVar("_T", bound=object)
 6 | 
 7 | TYPE_CAST_ATTRIBUTE = "__as_strawberry_type__"
 8 | 
 9 | 
10 | @overload
11 | def cast(type_: type, obj: None) -> None: ...
12 | 
13 | 
14 | @overload
15 | def cast(type_: type, obj: _T) -> _T: ...
16 | 
17 | 
18 | def cast(type_: type, obj: _T | None) -> _T | None:
19 |     """Cast an object to given type.
20 | 
21 |     This is used to mark an object as a cast object, so that the type can be
22 |     picked up when resolving unions/interfaces in case of ambiguity, which can
23 |     happen when returning an alike object instead of an instance of the type
24 |     (e.g. returning a Django, Pydantic or SQLAlchemy object)
25 |     """
26 |     if obj is None:
27 |         return None
28 | 
29 |     setattr(obj, TYPE_CAST_ATTRIBUTE, type_)
30 |     return obj
31 | 
32 | 
33 | def get_strawberry_type_cast(obj: Any) -> type | None:
34 |     """Get the type of a cast object."""
35 |     return getattr(obj, TYPE_CAST_ATTRIBUTE, None)
36 | 


--------------------------------------------------------------------------------
/strawberry/types/fields/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/strawberry/types/fields/__init__.py


--------------------------------------------------------------------------------
/strawberry/types/graphql.py:
--------------------------------------------------------------------------------
 1 | from __future__ import annotations
 2 | 
 3 | import enum
 4 | from typing import TYPE_CHECKING
 5 | 
 6 | if TYPE_CHECKING:
 7 |     from strawberry.http.types import HTTPMethod
 8 | 
 9 | 
10 | class OperationType(enum.Enum):
11 |     QUERY = "query"
12 |     MUTATION = "mutation"
13 |     SUBSCRIPTION = "subscription"
14 | 
15 |     @staticmethod
16 |     def from_http(method: HTTPMethod) -> set[OperationType]:
17 |         if method == "GET":
18 |             return {
19 |                 OperationType.QUERY,
20 |                 # subscriptions are supported via GET in the multipart protocol
21 |                 OperationType.SUBSCRIPTION,
22 |             }
23 | 
24 |         if method == "POST":
25 |             return {
26 |                 OperationType.QUERY,
27 |                 OperationType.MUTATION,
28 |                 OperationType.SUBSCRIPTION,
29 |             }
30 | 
31 |         raise ValueError(f"Unsupported HTTP method: {method}")  # pragma: no cover
32 | 
33 | 
34 | __all__ = ["OperationType"]
35 | 


--------------------------------------------------------------------------------
/strawberry/types/private.py:
--------------------------------------------------------------------------------
 1 | from typing import Annotated, TypeVar
 2 | 
 3 | from strawberry.utils.typing import type_has_annotation
 4 | 
 5 | 
 6 | class StrawberryPrivate: ...
 7 | 
 8 | 
 9 | T = TypeVar("T")
10 | 
11 | Private = Annotated[T, StrawberryPrivate()]
12 | """Represents a field that won't be exposed in the GraphQL schema.
13 | 
14 | Example:
15 | 
16 | ```python
17 | import strawberry
18 | 
19 | 
20 | @strawberry.type
21 | class User:
22 |     name: str
23 |     age: strawberry.Private[int]
24 | ```
25 | """
26 | 
27 | 
28 | def is_private(type_: object) -> bool:
29 |     return type_has_annotation(type_, StrawberryPrivate)
30 | 
31 | 
32 | __all__ = ["Private", "is_private"]
33 | 


--------------------------------------------------------------------------------
/strawberry/utils/__init__.py:
--------------------------------------------------------------------------------
1 | from graphql.version import VersionInfo, version_info
2 | 
3 | IS_GQL_33 = version_info >= VersionInfo.from_str("3.3.0a0")
4 | IS_GQL_32 = not IS_GQL_33
5 | 


--------------------------------------------------------------------------------
/strawberry/utils/await_maybe.py:
--------------------------------------------------------------------------------
 1 | import inspect
 2 | from collections.abc import AsyncIterator, Awaitable, Iterator
 3 | from typing import TypeVar, Union
 4 | 
 5 | T = TypeVar("T")
 6 | 
 7 | AwaitableOrValue = Union[Awaitable[T], T]
 8 | AsyncIteratorOrIterator = Union[AsyncIterator[T], Iterator[T]]
 9 | 
10 | 
11 | async def await_maybe(value: AwaitableOrValue[T]) -> T:
12 |     if inspect.isawaitable(value):
13 |         return await value
14 | 
15 |     return value
16 | 
17 | 
18 | __all__ = ["AsyncIteratorOrIterator", "AwaitableOrValue", "await_maybe"]
19 | 


--------------------------------------------------------------------------------
/strawberry/utils/dataclasses.py:
--------------------------------------------------------------------------------
 1 | from __future__ import annotations
 2 | 
 3 | import sys
 4 | from dataclasses import (  # type: ignore
 5 |     _FIELD,
 6 |     _FIELD_INITVAR,
 7 |     _FIELDS,
 8 |     _POST_INIT_NAME,
 9 |     _set_new_attribute,
10 | )
11 | from typing import Any
12 | 
13 | from strawberry.ext.dataclasses.dataclasses import dataclass_init_fn
14 | 
15 | 
16 | def add_custom_init_fn(cls: Any) -> None:
17 |     fields = [
18 |         f
19 |         for f in getattr(cls, _FIELDS).values()
20 |         if f._field_type in (_FIELD, _FIELD_INITVAR)
21 |     ]
22 |     globals_ = sys.modules[cls.__module__].__dict__
23 | 
24 |     _set_new_attribute(
25 |         cls,
26 |         "__init__",
27 |         dataclass_init_fn(
28 |             fields=fields,
29 |             frozen=False,
30 |             has_post_init=hasattr(cls, _POST_INIT_NAME),
31 |             self_name="__dataclass_self__" if "self" in fields else "self",
32 |             globals_=globals_,
33 |         ),
34 |     )
35 | 
36 | 
37 | __all__ = ["add_custom_init_fn"]
38 | 


--------------------------------------------------------------------------------
/strawberry/utils/deprecations.py:
--------------------------------------------------------------------------------
 1 | from __future__ import annotations
 2 | 
 3 | import warnings
 4 | from typing import Any, Optional
 5 | 
 6 | 
 7 | class DEPRECATION_MESSAGES:  # noqa: N801
 8 |     _TYPE_DEFINITION = (
 9 |         "_type_definition is deprecated, use __strawberry_definition__ instead"
10 |     )
11 | 
12 | 
13 | class DeprecatedDescriptor:
14 |     def __init__(self, msg: str, alias: object, attr_name: str) -> None:
15 |         self.msg = msg
16 |         self.alias = alias
17 |         self.attr_name = attr_name
18 | 
19 |     def warn(self) -> None:
20 |         warnings.warn(self.msg, stacklevel=2)
21 | 
22 |     def __get__(self, obj: Optional[object], type: Optional[type] = None) -> Any:
23 |         self.warn()
24 |         return self.alias
25 | 
26 |     def inject(self, klass: type) -> None:
27 |         setattr(klass, self.attr_name, self)
28 | 
29 | 
30 | __all__ = ["DEPRECATION_MESSAGES", "DeprecatedDescriptor"]
31 | 


--------------------------------------------------------------------------------
/strawberry/utils/importer.py:
--------------------------------------------------------------------------------
 1 | import importlib
 2 | from typing import Optional
 3 | 
 4 | 
 5 | def import_module_symbol(
 6 |     selector: str, default_symbol_name: Optional[str] = None
 7 | ) -> object:
 8 |     if ":" in selector:
 9 |         module_name, symbol_name = selector.split(":", 1)
10 |     elif default_symbol_name:
11 |         module_name, symbol_name = selector, default_symbol_name
12 |     else:
13 |         raise ValueError("Selector does not include a symbol name")
14 | 
15 |     module = importlib.import_module(module_name)
16 |     symbol = module
17 | 
18 |     for attribute_name in symbol_name.split("."):
19 |         symbol = getattr(symbol, attribute_name)
20 | 
21 |     return symbol
22 | 
23 | 
24 | __all__ = ["import_module_symbol"]
25 | 


--------------------------------------------------------------------------------
/strawberry/utils/logging.py:
--------------------------------------------------------------------------------
 1 | from __future__ import annotations
 2 | 
 3 | import logging
 4 | from typing import TYPE_CHECKING, Any, Optional
 5 | 
 6 | if TYPE_CHECKING:
 7 |     from typing import Final
 8 | 
 9 |     from graphql.error import GraphQLError
10 | 
11 |     from strawberry.types import ExecutionContext
12 | 
13 | 
14 | class StrawberryLogger:
15 |     logger: Final[logging.Logger] = logging.getLogger("strawberry.execution")
16 | 
17 |     @classmethod
18 |     def error(
19 |         cls,
20 |         error: GraphQLError,
21 |         execution_context: Optional[ExecutionContext] = None,
22 |         # https://www.python.org/dev/peps/pep-0484/#arbitrary-argument-lists-and-default-argument-values
23 |         **logger_kwargs: Any,
24 |     ) -> None:
25 |         cls.logger.error(error, exc_info=error.original_error, **logger_kwargs)
26 | 
27 | 
28 | __all__ = ["StrawberryLogger"]
29 | 


--------------------------------------------------------------------------------
/strawberry/utils/str_converters.py:
--------------------------------------------------------------------------------
 1 | import re
 2 | 
 3 | 
 4 | # Adapted from this response in Stackoverflow
 5 | # http://stackoverflow.com/a/19053800/1072990
 6 | def to_camel_case(snake_str: str) -> str:
 7 |     components = snake_str.split("_")
 8 |     # We capitalize the first letter of each component except the first one
 9 |     # with the 'capitalize' method and join them together.
10 |     return components[0] + "".join(x.capitalize() if x else "_" for x in components[1:])
11 | 
12 | 
13 | TO_KEBAB_CASE_RE = re.compile("((?<=[a-z0-9])[A-Z]|(?!^)[A-Z](?=[a-z]))")
14 | 
15 | 
16 | def to_kebab_case(name: str) -> str:
17 |     return TO_KEBAB_CASE_RE.sub(r"-\1", name).lower()
18 | 
19 | 
20 | def capitalize_first(name: str) -> str:
21 |     return name[0].upper() + name[1:]
22 | 
23 | 
24 | def to_snake_case(name: str) -> str:
25 |     name = re.sub("(.)([A-Z][a-z]+)", r"\1_\2", name)
26 |     return re.sub("([a-z0-9])([A-Z])", r"\1_\2", name).lower()
27 | 
28 | 
29 | __all__ = ["capitalize_first", "to_camel_case", "to_kebab_case", "to_snake_case"]
30 | 


--------------------------------------------------------------------------------
/tests/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/tests/__init__.py


--------------------------------------------------------------------------------
/tests/a.py:
--------------------------------------------------------------------------------
 1 | from __future__ import annotations
 2 | 
 3 | from typing import TYPE_CHECKING, Annotated, Optional
 4 | 
 5 | import strawberry
 6 | 
 7 | if TYPE_CHECKING:
 8 |     from tests.b import B
 9 | 
10 | 
11 | @strawberry.type
12 | class A:
13 |     id: strawberry.ID
14 | 
15 |     @strawberry.field
16 |     async def b(self) -> Annotated[B, strawberry.lazy("tests.b")]:
17 |         from tests.b import B
18 | 
19 |         return B(id=self.id)
20 | 
21 |     @strawberry.field
22 |     async def optional_b(self) -> Annotated[B, strawberry.lazy("tests.b")] | None:
23 |         from tests.b import B
24 | 
25 |         return B(id=self.id)
26 | 
27 |     @strawberry.field
28 |     async def optional_b2(self) -> Optional[Annotated[B, strawberry.lazy("tests.b")]]:
29 |         from tests.b import B
30 | 
31 |         return B(id=self.id)
32 | 


--------------------------------------------------------------------------------
/tests/asgi/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/tests/asgi/__init__.py


--------------------------------------------------------------------------------
/tests/asgi/test_async.py:
--------------------------------------------------------------------------------
 1 | from __future__ import annotations
 2 | 
 3 | from typing import TYPE_CHECKING, Optional
 4 | 
 5 | import pytest
 6 | 
 7 | import strawberry
 8 | 
 9 | if TYPE_CHECKING:
10 |     from starlette.testclient import TestClient
11 | 
12 | 
13 | @pytest.fixture
14 | def test_client() -> TestClient:
15 |     from starlette.testclient import TestClient
16 | 
17 |     from strawberry.asgi import GraphQL
18 | 
19 |     @strawberry.type
20 |     class Query:
21 |         @strawberry.field
22 |         async def hello(self, name: Optional[str] = None) -> str:
23 |             return f"Hello {name or 'world'}"
24 | 
25 |     async_schema = strawberry.Schema(Query)
26 |     app = GraphQL[None, None](async_schema)
27 |     return TestClient(app)
28 | 
29 | 
30 | def test_simple_query(test_client: TestClient):
31 |     response = test_client.post("/", json={"query": "{ hello }"})
32 | 
33 |     assert response.json() == {"data": {"hello": "Hello world"}}
34 | 


--------------------------------------------------------------------------------
/tests/b.py:
--------------------------------------------------------------------------------
 1 | from __future__ import annotations
 2 | 
 3 | from typing import TYPE_CHECKING, Annotated, Optional
 4 | 
 5 | import strawberry
 6 | 
 7 | if TYPE_CHECKING:
 8 |     from tests.a import A
 9 | 
10 | 
11 | @strawberry.type
12 | class B:
13 |     id: strawberry.ID
14 | 
15 |     @strawberry.field
16 |     async def a(self) -> Annotated[A, strawberry.lazy("tests.a"), object()]:
17 |         from tests.a import A
18 | 
19 |         return A(id=self.id)
20 | 
21 |     @strawberry.field
22 |     async def a_list(
23 |         self,
24 |     ) -> list[Annotated[A, strawberry.lazy("tests.a")]]:  # pragma: no cover
25 |         from tests.a import A
26 | 
27 |         return [A(id=self.id)]
28 | 
29 |     @strawberry.field
30 |     async def optional_a(
31 |         self,
32 |     ) -> Annotated[A, strawberry.lazy("tests.a"), object()] | None:
33 |         from tests.a import A
34 | 
35 |         return A(id=self.id)
36 | 
37 |     @strawberry.field
38 |     async def optional_a2(
39 |         self,
40 |     ) -> Optional[Annotated[A, strawberry.lazy("tests.a"), object()]]:
41 |         from tests.a import A
42 | 
43 |         return A(id=self.id)
44 | 


--------------------------------------------------------------------------------
/tests/benchmarks/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/tests/benchmarks/__init__.py


--------------------------------------------------------------------------------
/tests/benchmarks/queries/items.graphql:
--------------------------------------------------------------------------------
1 | query Items($count: Int!) {
2 |   items(count: $count) {
3 |     name
4 |     index
5 |   }
6 | }
7 | 


--------------------------------------------------------------------------------
/tests/benchmarks/queries/many_fields.graphql:
--------------------------------------------------------------------------------
 1 | {
 2 |   people {
 3 |     age
 4 |     description
 5 |     address
 6 |     name
 7 |     propA
 8 |     propB
 9 |     propC
10 |     propD
11 |     propE
12 |     propF
13 |     propG
14 |     propH
15 |     propI
16 |     propJ
17 |   }
18 | }
19 | 


--------------------------------------------------------------------------------
/tests/benchmarks/queries/many_fields_directives.graphql:
--------------------------------------------------------------------------------
 1 | {
 2 |   people {
 3 |     age
 4 |     description
 5 |     address
 6 |     name
 7 |     propA
 8 |     propB
 9 |     propC
10 |     propD
11 |     propE
12 |     propF
13 |     propG @uppercase
14 |     propH @uppercase
15 |     propI
16 |     propJ
17 |   }
18 | }
19 | 


--------------------------------------------------------------------------------
/tests/benchmarks/queries/simple.graphql:
--------------------------------------------------------------------------------
1 | {
2 |   hello
3 | }
4 | 


--------------------------------------------------------------------------------
/tests/benchmarks/test_arguments.py:
--------------------------------------------------------------------------------
 1 | import pytest
 2 | from pytest_codspeed import BenchmarkFixture
 3 | 
 4 | from strawberry.schema.config import StrawberryConfig
 5 | from strawberry.schema.types.scalar import DEFAULT_SCALAR_REGISTRY
 6 | from strawberry.types.arguments import convert_argument
 7 | from strawberry.types.base import StrawberryList
 8 | 
 9 | 
10 | @pytest.mark.parametrize("ntypes", [2**k for k in range(14, 23, 2)])
11 | def test_convert_argument_large_list(benchmark: BenchmarkFixture, ntypes):
12 |     test_value = list(range(ntypes))
13 |     type_ = StrawberryList(int)
14 | 
15 |     def run():
16 |         result = convert_argument(
17 |             test_value, type_, DEFAULT_SCALAR_REGISTRY, StrawberryConfig()
18 |         )
19 |         assert test_value == result
20 | 
21 |     benchmark(run)
22 | 


--------------------------------------------------------------------------------
/tests/c.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 | 
3 | import strawberry
4 | 
5 | 
6 | @strawberry.type
7 | class C:
8 |     id: strawberry.ID
9 | 


--------------------------------------------------------------------------------
/tests/channels/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/tests/channels/__init__.py


--------------------------------------------------------------------------------
/tests/cli/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/tests/cli/__init__.py


--------------------------------------------------------------------------------
/tests/cli/conftest.py:
--------------------------------------------------------------------------------
 1 | from __future__ import annotations
 2 | 
 3 | import sys
 4 | from typing import TYPE_CHECKING
 5 | 
 6 | import pytest
 7 | from pytest_mock import MockFixture
 8 | from typer.testing import CliRunner
 9 | 
10 | if TYPE_CHECKING:
11 |     from starlette.testclient import TestClient
12 |     from typer import Typer
13 | 
14 | 
15 | @pytest.fixture
16 | def cli_runner(mocker: MockFixture) -> CliRunner:
17 |     # Mock of uvicorn.run
18 |     uvicorn_run_patch = mocker.patch("uvicorn.run")
19 |     uvicorn_run_patch.return_value = True
20 |     return CliRunner()
21 | 
22 | 
23 | @pytest.fixture
24 | def debug_server_client(mocker: MockFixture) -> TestClient:
25 |     from starlette.testclient import TestClient
26 | 
27 |     schema_import_path = "tests.fixtures.sample_package.sample_module"
28 |     mocker.patch.object(sys, "argv", ["strawberry", "server", schema_import_path])
29 | 
30 |     from strawberry.cli.debug_server import app
31 | 
32 |     return TestClient(app)
33 | 
34 | 
35 | @pytest.fixture
36 | def cli_app() -> Typer:
37 |     from strawberry.cli.app import app
38 | 
39 |     return app
40 | 


--------------------------------------------------------------------------------
/tests/cli/fixtures/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/tests/cli/fixtures/__init__.py


--------------------------------------------------------------------------------
/tests/cli/fixtures/unions.py:
--------------------------------------------------------------------------------
 1 | import strawberry
 2 | 
 3 | # create a few types and then a union type
 4 | 
 5 | 
 6 | @strawberry.type
 7 | class Foo:
 8 |     a: str
 9 | 
10 | 
11 | @strawberry.type
12 | class Bar:
13 |     b: str
14 | 
15 | 
16 | @strawberry.type
17 | class Baz:
18 |     c: str
19 | 
20 | 
21 | @strawberry.type
22 | class Qux:
23 |     d: str
24 | 
25 | 
26 | # this is the union type
27 | 
28 | Union1 = strawberry.union(name="Union1", types=(Foo, Bar, Baz, Qux))
29 | Union2 = strawberry.union(name="Union2", types=(Baz, Qux))
30 | 


--------------------------------------------------------------------------------
/tests/cli/snapshots/unions.py:
--------------------------------------------------------------------------------
 1 | import strawberry
 2 | from typing import Annotated
 3 | 
 4 | # create a few types and then a union type
 5 | 
 6 | 
 7 | @strawberry.type
 8 | class Foo:
 9 |     a: str
10 | 
11 | 
12 | @strawberry.type
13 | class Bar:
14 |     b: str
15 | 
16 | 
17 | @strawberry.type
18 | class Baz:
19 |     c: str
20 | 
21 | 
22 | @strawberry.type
23 | class Qux:
24 |     d: str
25 | 
26 | 
27 | # this is the union type
28 | 
29 | Union1 = Annotated[Foo | Bar | Baz | Qux, strawberry.union(name="Union1")]
30 | Union2 = Annotated[Baz | Qux, strawberry.union(name="Union2")]
31 | 


--------------------------------------------------------------------------------
/tests/cli/snapshots/unions_py38.py:
--------------------------------------------------------------------------------
 1 | import strawberry
 2 | from typing import Annotated, Union
 3 | 
 4 | # create a few types and then a union type
 5 | 
 6 | 
 7 | @strawberry.type
 8 | class Foo:
 9 |     a: str
10 | 
11 | 
12 | @strawberry.type
13 | class Bar:
14 |     b: str
15 | 
16 | 
17 | @strawberry.type
18 | class Baz:
19 |     c: str
20 | 
21 | 
22 | @strawberry.type
23 | class Qux:
24 |     d: str
25 | 
26 | 
27 | # this is the union type
28 | 
29 | Union1 = Annotated[Union[Foo, Bar, Baz, Qux], strawberry.union(name="Union1")]
30 | Union2 = Annotated[Union[Baz, Qux], strawberry.union(name="Union2")]
31 | 


--------------------------------------------------------------------------------
/tests/cli/snapshots/unions_typing_extension.py:
--------------------------------------------------------------------------------
 1 | import strawberry
 2 | from typing_extensions import Annotated
 3 | 
 4 | # create a few types and then a union type
 5 | 
 6 | 
 7 | @strawberry.type
 8 | class Foo:
 9 |     a: str
10 | 
11 | 
12 | @strawberry.type
13 | class Bar:
14 |     b: str
15 | 
16 | 
17 | @strawberry.type
18 | class Baz:
19 |     c: str
20 | 
21 | 
22 | @strawberry.type
23 | class Qux:
24 |     d: str
25 | 
26 | 
27 | # this is the union type
28 | 
29 | Union1 = Annotated[Foo | Bar | Baz | Qux, strawberry.union(name="Union1")]
30 | Union2 = Annotated[Baz | Qux, strawberry.union(name="Union2")]
31 | 


--------------------------------------------------------------------------------
/tests/codegen/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/tests/codegen/__init__.py


--------------------------------------------------------------------------------
/tests/codegen/lazy_type.py:
--------------------------------------------------------------------------------
1 | import strawberry
2 | 
3 | 
4 | @strawberry.type
5 | class LaziestType:
6 |     something: bool
7 | 


--------------------------------------------------------------------------------
/tests/codegen/queries/alias.graphql:
--------------------------------------------------------------------------------
1 | query OperationName {
2 |   id
3 |   second_id: id
4 |   a_float: float
5 |   lazy {
6 |     lazy: something
7 |   }
8 | }
9 | 


--------------------------------------------------------------------------------
/tests/codegen/queries/basic.graphql:
--------------------------------------------------------------------------------
 1 | query OperationName {
 2 |   id
 3 |   integer
 4 |   float
 5 |   boolean
 6 |   uuid
 7 |   date
 8 |   datetime
 9 |   time
10 |   decimal
11 |   lazy {
12 |     something
13 |   }
14 | }
15 | 


--------------------------------------------------------------------------------
/tests/codegen/queries/custom_scalar.graphql:
--------------------------------------------------------------------------------
1 | query OperationName {
2 |   json
3 | }
4 | 


--------------------------------------------------------------------------------
/tests/codegen/queries/enum.graphql:
--------------------------------------------------------------------------------
1 | query OperationName {
2 |   enum
3 | }
4 | 


--------------------------------------------------------------------------------
/tests/codegen/queries/fragment.graphql:
--------------------------------------------------------------------------------
 1 | fragment PersonName on Person {
 2 |   name
 3 | }
 4 | 
 5 | query OperationName {
 6 |   person {
 7 |     ...PersonName
 8 |   }
 9 | }
10 | 


--------------------------------------------------------------------------------
/tests/codegen/queries/generic_types.graphql:
--------------------------------------------------------------------------------
 1 | query ListLifeGeneric {
 2 |   listLife {
 3 |     items1 {
 4 |       name
 5 |       age
 6 |     }
 7 |     items2 {
 8 |       name
 9 |       age
10 |     }
11 |   }
12 | }
13 | 


--------------------------------------------------------------------------------
/tests/codegen/queries/interface.graphql:
--------------------------------------------------------------------------------
1 | query OperationName {
2 |   interface {
3 |     id
4 |   }
5 | }
6 | 


--------------------------------------------------------------------------------
/tests/codegen/queries/interface_fragments.graphql:
--------------------------------------------------------------------------------
 1 | query OperationName {
 2 |   interface {
 3 |     id
 4 |     ... on BlogPost {
 5 |       title
 6 |     }
 7 |     ... on Image {
 8 |       url
 9 |     }
10 |   }
11 | }
12 | 


--------------------------------------------------------------------------------
/tests/codegen/queries/interface_fragments_with_spread.graphql:
--------------------------------------------------------------------------------
 1 | fragment PartialBlogPost on BlogPost {
 2 |   title
 3 | }
 4 | 
 5 | query OperationName {
 6 |   interface {
 7 |     id
 8 |     ... on BlogPost {
 9 |       ...PartialBlogPost
10 |     }
11 |     ... on Image {
12 |       url
13 |     }
14 |   }
15 | }
16 | 


--------------------------------------------------------------------------------
/tests/codegen/queries/interface_single_fragment.graphql:
--------------------------------------------------------------------------------
1 | query OperationName {
2 |   interface {
3 |     id
4 |     ... on BlogPost {
5 |       title
6 |     }
7 |   }
8 | }
9 | 


--------------------------------------------------------------------------------
/tests/codegen/queries/multiple_types.graphql:
--------------------------------------------------------------------------------
1 | query OperationName {
2 |   person {
3 |     name
4 |   }
5 |   listOfPeople {
6 |     name
7 |   }
8 | }
9 | 


--------------------------------------------------------------------------------
/tests/codegen/queries/multiple_types_optional.graphql:
--------------------------------------------------------------------------------
1 | query OperationName {
2 |   optionalPerson {
3 |     name
4 |   }
5 | }
6 | 


--------------------------------------------------------------------------------
/tests/codegen/queries/mutation-fragment.graphql:
--------------------------------------------------------------------------------
 1 | fragment IdFragment on BlogPost {
 2 |   id
 3 | }
 4 | 
 5 | mutation addBook($input: String!) {
 6 |   addBook(input: $input) {
 7 |     ...IdFragment
 8 |   }
 9 | }
10 | 


--------------------------------------------------------------------------------
/tests/codegen/queries/mutation.graphql:
--------------------------------------------------------------------------------
1 | mutation addBook($input: String!) {
2 |   addBook(input: $input) {
3 |     id
4 |   }
5 | }
6 | 


--------------------------------------------------------------------------------
/tests/codegen/queries/mutation_with_object.graphql:
--------------------------------------------------------------------------------
1 | mutation AddBlogPosts($input: [BlogPostInput!]!) {
2 |   addBlogPosts(input: {posts: $input}) {
3 |     posts {
4 |       title
5 |     }
6 |   }
7 | }
8 | 


--------------------------------------------------------------------------------
/tests/codegen/queries/nullable_list_of_non_scalars.graphql:
--------------------------------------------------------------------------------
1 | query OperationName {
2 |   optionalListOfPeople {
3 |     name
4 |     age
5 |   }
6 | }
7 | 


--------------------------------------------------------------------------------
/tests/codegen/queries/optional_and_lists.graphql:
--------------------------------------------------------------------------------
1 | query OperationName {
2 |   optionalInt
3 |   listOfInt
4 |   listOfOptionalInt
5 |   optionalListOfOptionalInt
6 | }
7 | 


--------------------------------------------------------------------------------
/tests/codegen/queries/union.graphql:
--------------------------------------------------------------------------------
 1 | query OperationName {
 2 |   union {
 3 |     ... on Animal {
 4 |       age
 5 |     }
 6 |     ... on Person {
 7 |       name
 8 |     }
 9 |   }
10 |   optionalUnion {
11 |     ... on Animal {
12 |       age
13 |     }
14 |     ... on Person {
15 |       name
16 |     }
17 |   }
18 | }
19 | 


--------------------------------------------------------------------------------
/tests/codegen/queries/union_return.graphql:
--------------------------------------------------------------------------------
1 | query OperationName {
2 |   getPersonOrAnimal {
3 |     ... on Person {
4 |       name
5 |       age
6 |     }
7 |   }
8 | }
9 | 


--------------------------------------------------------------------------------
/tests/codegen/queries/union_with_one_type.graphql:
--------------------------------------------------------------------------------
1 | query OperationName {
2 |   union {
3 |     ... on Animal {
4 |       age
5 |       name
6 |     }
7 |   }
8 | }
9 | 


--------------------------------------------------------------------------------
/tests/codegen/queries/union_with_typename.graphql:
--------------------------------------------------------------------------------
 1 | query OperationName {
 2 |   __typename
 3 |   union {
 4 |     ... on Animal {
 5 |       age
 6 |     }
 7 |     ... on Person {
 8 |       name
 9 |     }
10 |   }
11 |   optionalUnion {
12 |     ... on Animal {
13 |       age
14 |     }
15 |     ... on Person {
16 |       name
17 |     }
18 |   }
19 | }
20 | 


--------------------------------------------------------------------------------
/tests/codegen/queries/union_with_typename_and_fragment.graphql:
--------------------------------------------------------------------------------
 1 | fragment AnimalProjection on Animal {
 2 |   age
 3 | }
 4 | 
 5 | query OperationName {
 6 |   __typename
 7 |   union {
 8 |     ... on Animal {
 9 |       ...AnimalProjection
10 |     }
11 |     ... on Person {
12 |       name
13 |     }
14 |   }
15 |   optionalUnion {
16 |     ... on Animal {
17 |       ...AnimalProjection
18 |     }
19 |     ... on Person {
20 |       name
21 |     }
22 |   }
23 | }
24 | 


--------------------------------------------------------------------------------
/tests/codegen/queries/variables.graphql:
--------------------------------------------------------------------------------
1 | query OperationName($id: ID, $input: ExampleInput!, $ids: [ID!]!, $ids2: [ID], $ids3: [[ID]]) {
2 |   withInputs(id: $id, input: $input)
3 | }
4 | 


--------------------------------------------------------------------------------
/tests/codegen/queries/with_directives.graphql:
--------------------------------------------------------------------------------
1 | query OperationName @owner(name: "Patrick", age: 30, items: [1, 2, 3], enum: NAME, bool: true) {
2 |   person {
3 |     name @root
4 |   }
5 | }
6 | 


--------------------------------------------------------------------------------
/tests/codegen/snapshots/python/alias.py:
--------------------------------------------------------------------------------
 1 | class OperationNameResultLazy:
 2 |     # alias for something
 3 |     lazy: bool
 4 | 
 5 | class OperationNameResult:
 6 |     id: str
 7 |     # alias for id
 8 |     second_id: str
 9 |     # alias for float
10 |     a_float: float
11 |     lazy: OperationNameResultLazy
12 | 


--------------------------------------------------------------------------------
/tests/codegen/snapshots/python/basic.py:
--------------------------------------------------------------------------------
 1 | from uuid import UUID
 2 | from datetime import date, datetime, time
 3 | from decimal import Decimal
 4 | 
 5 | class OperationNameResultLazy:
 6 |     something: bool
 7 | 
 8 | class OperationNameResult:
 9 |     id: str
10 |     integer: int
11 |     float: float
12 |     boolean: bool
13 |     uuid: UUID
14 |     date: date
15 |     datetime: datetime
16 |     time: time
17 |     decimal: Decimal
18 |     lazy: OperationNameResultLazy
19 | 


--------------------------------------------------------------------------------
/tests/codegen/snapshots/python/custom_scalar.py:
--------------------------------------------------------------------------------
1 | from typing import NewType
2 | 
3 | JSON = NewType("JSON", str)
4 | 
5 | class OperationNameResult:
6 |     json: JSON
7 | 


--------------------------------------------------------------------------------
/tests/codegen/snapshots/python/enum.py:
--------------------------------------------------------------------------------
 1 | from enum import Enum
 2 | 
 3 | class Color(Enum):
 4 |     RED = "RED"
 5 |     GREEN = "GREEN"
 6 |     BLUE = "BLUE"
 7 | 
 8 | class OperationNameResult:
 9 |     enum: Color
10 | 


--------------------------------------------------------------------------------
/tests/codegen/snapshots/python/fragment.py:
--------------------------------------------------------------------------------
1 | class PersonName:
2 |     # typename: Person
3 |     name: str
4 | 
5 | class OperationNameResult:
6 |     person: PersonName
7 | 


--------------------------------------------------------------------------------
/tests/codegen/snapshots/python/generic_types.py:
--------------------------------------------------------------------------------
 1 | from typing import List
 2 | 
 3 | class ListLifeGenericResultListLifeItems1:
 4 |     name: str
 5 |     age: int
 6 | 
 7 | class ListLifeGenericResultListLifeItems2:
 8 |     name: str
 9 |     age: int
10 | 
11 | class ListLifeGenericResultListLife:
12 |     items1: list[ListLifeGenericResultListLifeItems1]
13 |     items2: list[ListLifeGenericResultListLifeItems2]
14 | 
15 | class ListLifeGenericResult:
16 |     list_life: ListLifeGenericResultListLife
17 | 


--------------------------------------------------------------------------------
/tests/codegen/snapshots/python/interface.py:
--------------------------------------------------------------------------------
1 | class OperationNameResultInterface:
2 |     id: str
3 | 
4 | class OperationNameResult:
5 |     interface: OperationNameResultInterface
6 | 


--------------------------------------------------------------------------------
/tests/codegen/snapshots/python/interface_fragments.py:
--------------------------------------------------------------------------------
 1 | from typing import Union
 2 | 
 3 | class OperationNameResultInterfaceBlogPost:
 4 |     # typename: BlogPost
 5 |     id: str
 6 |     title: str
 7 | 
 8 | class OperationNameResultInterfaceImage:
 9 |     # typename: Image
10 |     id: str
11 |     url: str
12 | 
13 | OperationNameResultInterface = Union[OperationNameResultInterfaceBlogPost, OperationNameResultInterfaceImage]
14 | 
15 | class OperationNameResult:
16 |     interface: OperationNameResultInterface
17 | 


--------------------------------------------------------------------------------
/tests/codegen/snapshots/python/interface_fragments_with_spread.py:
--------------------------------------------------------------------------------
 1 | from typing import Union
 2 | 
 3 | class PartialBlogPost:
 4 |     # typename: BlogPost
 5 |     title: str
 6 | 
 7 | class OperationNameResultInterfaceBlogPost:
 8 |     # typename: BlogPost
 9 |     id: str
10 |     title: str
11 | 
12 | class OperationNameResultInterfaceImage:
13 |     # typename: Image
14 |     id: str
15 |     url: str
16 | 
17 | OperationNameResultInterface = Union[OperationNameResultInterfaceBlogPost, OperationNameResultInterfaceImage]
18 | 
19 | class OperationNameResult:
20 |     interface: OperationNameResultInterface
21 | 


--------------------------------------------------------------------------------
/tests/codegen/snapshots/python/interface_single_fragment.py:
--------------------------------------------------------------------------------
1 | class OperationNameResultInterfaceBlogPost:
2 |     # typename: BlogPost
3 |     id: str
4 |     title: str
5 | 
6 | class OperationNameResult:
7 |     interface: OperationNameResultInterfaceBlogPost
8 | 


--------------------------------------------------------------------------------
/tests/codegen/snapshots/python/multiple_types.py:
--------------------------------------------------------------------------------
 1 | from typing import List
 2 | 
 3 | class OperationNameResultPerson:
 4 |     name: str
 5 | 
 6 | class OperationNameResultListOfPeople:
 7 |     name: str
 8 | 
 9 | class OperationNameResult:
10 |     person: OperationNameResultPerson
11 |     list_of_people: list[OperationNameResultListOfPeople]
12 | 


--------------------------------------------------------------------------------
/tests/codegen/snapshots/python/multiple_types_optional.py:
--------------------------------------------------------------------------------
1 | from typing import Optional
2 | 
3 | class OperationNameResultOptionalPerson:
4 |     name: str
5 | 
6 | class OperationNameResult:
7 |     optional_person: Optional[OperationNameResultOptionalPerson]
8 | 


--------------------------------------------------------------------------------
/tests/codegen/snapshots/python/mutation-fragment.py:
--------------------------------------------------------------------------------
 1 | class IdFragment:
 2 |     # typename: BlogPost
 3 |     id: str
 4 | 
 5 | class addBookResult:
 6 |     add_book: IdFragment
 7 | 
 8 | class addBookVariables:
 9 |     input: str
10 | 


--------------------------------------------------------------------------------
/tests/codegen/snapshots/python/mutation.py:
--------------------------------------------------------------------------------
1 | class addBookResultAddBook:
2 |     id: str
3 | 
4 | class addBookResult:
5 |     add_book: addBookResultAddBook
6 | 
7 | class addBookVariables:
8 |     input: str
9 | 


--------------------------------------------------------------------------------
/tests/codegen/snapshots/python/mutation_with_object.py:
--------------------------------------------------------------------------------
 1 | from typing import List, Optional
 2 | from enum import Enum
 3 | 
 4 | class AddBlogPostsResultAddBlogPostsPosts:
 5 |     title: str
 6 | 
 7 | class AddBlogPostsResultAddBlogPosts:
 8 |     posts: list[AddBlogPostsResultAddBlogPostsPosts]
 9 | 
10 | class AddBlogPostsResult:
11 |     add_blog_posts: AddBlogPostsResultAddBlogPosts
12 | 
13 | class Color(Enum):
14 |     RED = "RED"
15 |     GREEN = "GREEN"
16 |     BLUE = "BLUE"
17 | 
18 | class BlogPostInput:
19 |     title: str = "I replaced my doorbell.  You wouldn't believe what happened next!"
20 |     color: Color = Color.RED
21 |     pi: float = 3.14159
22 |     a_bool: bool = True
23 |     an_int: int = 42
24 |     an_optional_int: Optional[int] = None
25 | 
26 | class AddBlogPostsVariables:
27 |     input: list[BlogPostInput]
28 | 


--------------------------------------------------------------------------------
/tests/codegen/snapshots/python/nullable_list_of_non_scalars.py:
--------------------------------------------------------------------------------
1 | from typing import List, Optional
2 | 
3 | class OperationNameResultOptionalListOfPeople:
4 |     name: str
5 |     age: int
6 | 
7 | class OperationNameResult:
8 |     optional_list_of_people: Optional[list[OperationNameResultOptionalListOfPeople]]
9 | 


--------------------------------------------------------------------------------
/tests/codegen/snapshots/python/optional_and_lists.py:
--------------------------------------------------------------------------------
1 | from typing import List, Optional
2 | 
3 | class OperationNameResult:
4 |     optional_int: Optional[int]
5 |     list_of_int: list[int]
6 |     list_of_optional_int: list[Optional[int]]
7 |     optional_list_of_optional_int: Optional[list[Optional[int]]]
8 | 


--------------------------------------------------------------------------------
/tests/codegen/snapshots/python/union.py:
--------------------------------------------------------------------------------
 1 | from typing import Optional, Union
 2 | 
 3 | class OperationNameResultUnionAnimal:
 4 |     # typename: Animal
 5 |     age: int
 6 | 
 7 | class OperationNameResultUnionPerson:
 8 |     # typename: Person
 9 |     name: str
10 | 
11 | OperationNameResultUnion = Union[OperationNameResultUnionAnimal, OperationNameResultUnionPerson]
12 | 
13 | class OperationNameResultOptionalUnionAnimal:
14 |     # typename: Animal
15 |     age: int
16 | 
17 | class OperationNameResultOptionalUnionPerson:
18 |     # typename: Person
19 |     name: str
20 | 
21 | OperationNameResultOptionalUnion = Union[OperationNameResultOptionalUnionAnimal, OperationNameResultOptionalUnionPerson]
22 | 
23 | class OperationNameResult:
24 |     union: OperationNameResultUnion
25 |     optional_union: Optional[OperationNameResultOptionalUnion]
26 | 


--------------------------------------------------------------------------------
/tests/codegen/snapshots/python/union_return.py:
--------------------------------------------------------------------------------
1 | class OperationNameResultGetPersonOrAnimalPerson:
2 |     # typename: Person
3 |     name: str
4 |     age: int
5 | 
6 | class OperationNameResult:
7 |     get_person_or_animal: OperationNameResultGetPersonOrAnimalPerson
8 | 


--------------------------------------------------------------------------------
/tests/codegen/snapshots/python/union_with_one_type.py:
--------------------------------------------------------------------------------
1 | class OperationNameResultUnionAnimal:
2 |     # typename: Animal
3 |     age: int
4 |     name: str
5 | 
6 | class OperationNameResult:
7 |     union: OperationNameResultUnionAnimal
8 | 


--------------------------------------------------------------------------------
/tests/codegen/snapshots/python/union_with_typename.py:
--------------------------------------------------------------------------------
 1 | from typing import Optional, Union
 2 | 
 3 | class OperationNameResultUnionAnimal:
 4 |     # typename: Animal
 5 |     age: int
 6 | 
 7 | class OperationNameResultUnionPerson:
 8 |     # typename: Person
 9 |     name: str
10 | 
11 | OperationNameResultUnion = Union[OperationNameResultUnionAnimal, OperationNameResultUnionPerson]
12 | 
13 | class OperationNameResultOptionalUnionAnimal:
14 |     # typename: Animal
15 |     age: int
16 | 
17 | class OperationNameResultOptionalUnionPerson:
18 |     # typename: Person
19 |     name: str
20 | 
21 | OperationNameResultOptionalUnion = Union[OperationNameResultOptionalUnionAnimal, OperationNameResultOptionalUnionPerson]
22 | 
23 | class OperationNameResult:
24 |     union: OperationNameResultUnion
25 |     optional_union: Optional[OperationNameResultOptionalUnion]
26 | 


--------------------------------------------------------------------------------
/tests/codegen/snapshots/python/union_with_typename_and_fragment.py:
--------------------------------------------------------------------------------
 1 | from typing import Optional, Union
 2 | 
 3 | class AnimalProjection:
 4 |     # typename: Animal
 5 |     age: int
 6 | 
 7 | class OperationNameResultUnionPerson:
 8 |     # typename: Person
 9 |     name: str
10 | 
11 | OperationNameResultUnion = Union[AnimalProjection, OperationNameResultUnionPerson]
12 | 
13 | class OperationNameResultOptionalUnionPerson:
14 |     # typename: Person
15 |     name: str
16 | 
17 | OperationNameResultOptionalUnion = Union[AnimalProjection, OperationNameResultOptionalUnionPerson]
18 | 
19 | class OperationNameResult:
20 |     union: OperationNameResultUnion
21 |     optional_union: Optional[OperationNameResultOptionalUnion]
22 | 


--------------------------------------------------------------------------------
/tests/codegen/snapshots/python/variables.py:
--------------------------------------------------------------------------------
 1 | from typing import List, Optional
 2 | 
 3 | class OperationNameResult:
 4 |     with_inputs: bool
 5 | 
 6 | class PersonInput:
 7 |     name: str
 8 |     age: Optional[int] = None
 9 | 
10 | class ExampleInput:
11 |     id: str
12 |     name: str
13 |     age: int
14 |     person: Optional[PersonInput]
15 |     people: list[PersonInput]
16 |     optional_people: Optional[list[PersonInput]]
17 | 
18 | class OperationNameVariables:
19 |     id: Optional[str]
20 |     input: ExampleInput
21 |     ids: list[str]
22 |     ids2: Optional[list[Optional[str]]]
23 |     ids3: Optional[list[Optional[list[Optional[str]]]]]
24 | 


--------------------------------------------------------------------------------
/tests/codegen/snapshots/python/with_directives.py:
--------------------------------------------------------------------------------
1 | class OperationNameResultPerson:
2 |     name: str
3 | 
4 | class OperationNameResult:
5 |     person: OperationNameResultPerson
6 | 


--------------------------------------------------------------------------------
/tests/codegen/snapshots/typescript/alias.ts:
--------------------------------------------------------------------------------
 1 | type OperationNameResultLazy = {
 2 |     // alias for something
 3 |     lazy: boolean
 4 | }
 5 | 
 6 | type OperationNameResult = {
 7 |     id: string
 8 |     // alias for id
 9 |     second_id: string
10 |     // alias for float
11 |     a_float: number
12 |     lazy: OperationNameResultLazy
13 | }
14 | 


--------------------------------------------------------------------------------
/tests/codegen/snapshots/typescript/basic.ts:
--------------------------------------------------------------------------------
 1 | type OperationNameResultLazy = {
 2 |     something: boolean
 3 | }
 4 | 
 5 | type OperationNameResult = {
 6 |     id: string
 7 |     integer: number
 8 |     float: number
 9 |     boolean: boolean
10 |     uuid: string
11 |     date: string
12 |     datetime: string
13 |     time: string
14 |     decimal: string
15 |     lazy: OperationNameResultLazy
16 | }
17 | 


--------------------------------------------------------------------------------
/tests/codegen/snapshots/typescript/custom_scalar.ts:
--------------------------------------------------------------------------------
1 | type JSON = string
2 | 
3 | type OperationNameResult = {
4 |     json: JSON
5 | }
6 | 


--------------------------------------------------------------------------------
/tests/codegen/snapshots/typescript/enum.ts:
--------------------------------------------------------------------------------
 1 | enum Color {
 2 |     RED = "RED",
 3 |     GREEN = "GREEN",
 4 |     BLUE = "BLUE",
 5 | }
 6 | 
 7 | type OperationNameResult = {
 8 |     enum: Color
 9 | }
10 | 


--------------------------------------------------------------------------------
/tests/codegen/snapshots/typescript/fragment.ts:
--------------------------------------------------------------------------------
1 | type PersonName = {
2 |     name: string
3 | }
4 | 
5 | type OperationNameResult = {
6 |     person: PersonName
7 | }
8 | 


--------------------------------------------------------------------------------
/tests/codegen/snapshots/typescript/generic_types.ts:
--------------------------------------------------------------------------------
 1 | type ListLifeGenericResultListLifeItems1 = {
 2 |     name: string
 3 |     age: number
 4 | }
 5 | 
 6 | type ListLifeGenericResultListLifeItems2 = {
 7 |     name: string
 8 |     age: number
 9 | }
10 | 
11 | type ListLifeGenericResultListLife = {
12 |     items1: ListLifeGenericResultListLifeItems1[]
13 |     items2: ListLifeGenericResultListLifeItems2[]
14 | }
15 | 
16 | type ListLifeGenericResult = {
17 |     list_life: ListLifeGenericResultListLife
18 | }
19 | 


--------------------------------------------------------------------------------
/tests/codegen/snapshots/typescript/interface.ts:
--------------------------------------------------------------------------------
1 | type OperationNameResultInterface = {
2 |     id: string
3 | }
4 | 
5 | type OperationNameResult = {
6 |     interface: OperationNameResultInterface
7 | }
8 | 


--------------------------------------------------------------------------------
/tests/codegen/snapshots/typescript/interface_fragments.ts:
--------------------------------------------------------------------------------
 1 | type OperationNameResultInterfaceBlogPost = {
 2 |     id: string
 3 |     title: string
 4 | }
 5 | 
 6 | type OperationNameResultInterfaceImage = {
 7 |     id: string
 8 |     url: string
 9 | }
10 | 
11 | type OperationNameResultInterface = OperationNameResultInterfaceBlogPost | OperationNameResultInterfaceImage
12 | 
13 | type OperationNameResult = {
14 |     interface: OperationNameResultInterface
15 | }
16 | 


--------------------------------------------------------------------------------
/tests/codegen/snapshots/typescript/interface_fragments_with_spread.ts:
--------------------------------------------------------------------------------
 1 | type PartialBlogPost = {
 2 |     title: string
 3 | }
 4 | 
 5 | type OperationNameResultInterfaceBlogPost = {
 6 |     id: string
 7 |     title: string
 8 | }
 9 | 
10 | type OperationNameResultInterfaceImage = {
11 |     id: string
12 |     url: string
13 | }
14 | 
15 | type OperationNameResultInterface = OperationNameResultInterfaceBlogPost | OperationNameResultInterfaceImage
16 | 
17 | type OperationNameResult = {
18 |     interface: OperationNameResultInterface
19 | }
20 | 


--------------------------------------------------------------------------------
/tests/codegen/snapshots/typescript/interface_single_fragment.ts:
--------------------------------------------------------------------------------
1 | type OperationNameResultInterfaceBlogPost = {
2 |     id: string
3 |     title: string
4 | }
5 | 
6 | type OperationNameResult = {
7 |     interface: OperationNameResultInterfaceBlogPost
8 | }
9 | 


--------------------------------------------------------------------------------
/tests/codegen/snapshots/typescript/multiple_types.ts:
--------------------------------------------------------------------------------
 1 | type OperationNameResultPerson = {
 2 |     name: string
 3 | }
 4 | 
 5 | type OperationNameResultListOfPeople = {
 6 |     name: string
 7 | }
 8 | 
 9 | type OperationNameResult = {
10 |     person: OperationNameResultPerson
11 |     list_of_people: OperationNameResultListOfPeople[]
12 | }
13 | 


--------------------------------------------------------------------------------
/tests/codegen/snapshots/typescript/multiple_types_optional.ts:
--------------------------------------------------------------------------------
1 | type OperationNameResultOptionalPerson = {
2 |     name: string
3 | }
4 | 
5 | type OperationNameResult = {
6 |     optional_person: OperationNameResultOptionalPerson | undefined
7 | }
8 | 


--------------------------------------------------------------------------------
/tests/codegen/snapshots/typescript/mutation-fragment.ts:
--------------------------------------------------------------------------------
 1 | type IdFragment = {
 2 |     id: string
 3 | }
 4 | 
 5 | type addBookResult = {
 6 |     add_book: IdFragment
 7 | }
 8 | 
 9 | type addBookVariables = {
10 |     input: string
11 | }
12 | 


--------------------------------------------------------------------------------
/tests/codegen/snapshots/typescript/mutation.ts:
--------------------------------------------------------------------------------
 1 | type addBookResultAddBook = {
 2 |     id: string
 3 | }
 4 | 
 5 | type addBookResult = {
 6 |     add_book: addBookResultAddBook
 7 | }
 8 | 
 9 | type addBookVariables = {
10 |     input: string
11 | }
12 | 


--------------------------------------------------------------------------------
/tests/codegen/snapshots/typescript/mutation_with_object.ts:
--------------------------------------------------------------------------------
 1 | type AddBlogPostsResultAddBlogPostsPosts = {
 2 |     title: string
 3 | }
 4 | 
 5 | type AddBlogPostsResultAddBlogPosts = {
 6 |     posts: AddBlogPostsResultAddBlogPostsPosts[]
 7 | }
 8 | 
 9 | type AddBlogPostsResult = {
10 |     add_blog_posts: AddBlogPostsResultAddBlogPosts
11 | }
12 | 
13 | enum Color {
14 |     RED = "RED",
15 |     GREEN = "GREEN",
16 |     BLUE = "BLUE",
17 | }
18 | 
19 | type BlogPostInput = {
20 |     title: string
21 |     color: Color
22 |     pi: number
23 |     a_bool: boolean
24 |     an_int: number
25 |     an_optional_int: number | undefined
26 | }
27 | 
28 | type AddBlogPostsVariables = {
29 |     input: BlogPostInput[]
30 | }
31 | 


--------------------------------------------------------------------------------
/tests/codegen/snapshots/typescript/nullable_list_of_non_scalars.ts:
--------------------------------------------------------------------------------
1 | type OperationNameResultOptionalListOfPeople = {
2 |     name: string
3 |     age: number
4 | }
5 | 
6 | type OperationNameResult = {
7 |     optional_list_of_people: OperationNameResultOptionalListOfPeople[] | undefined
8 | }
9 | 


--------------------------------------------------------------------------------
/tests/codegen/snapshots/typescript/optional_and_lists.ts:
--------------------------------------------------------------------------------
1 | type OperationNameResult = {
2 |     optional_int: number | undefined
3 |     list_of_int: number[]
4 |     list_of_optional_int: (number | undefined)[]
5 |     optional_list_of_optional_int: (number | undefined)[] | undefined
6 | }
7 | 


--------------------------------------------------------------------------------
/tests/codegen/snapshots/typescript/union.ts:
--------------------------------------------------------------------------------
 1 | type OperationNameResultUnionAnimal = {
 2 |     age: number
 3 | }
 4 | 
 5 | type OperationNameResultUnionPerson = {
 6 |     name: string
 7 | }
 8 | 
 9 | type OperationNameResultUnion = OperationNameResultUnionAnimal | OperationNameResultUnionPerson
10 | 
11 | type OperationNameResultOptionalUnionAnimal = {
12 |     age: number
13 | }
14 | 
15 | type OperationNameResultOptionalUnionPerson = {
16 |     name: string
17 | }
18 | 
19 | type OperationNameResultOptionalUnion = OperationNameResultOptionalUnionAnimal | OperationNameResultOptionalUnionPerson
20 | 
21 | type OperationNameResult = {
22 |     union: OperationNameResultUnion
23 |     optional_union: OperationNameResultOptionalUnion | undefined
24 | }
25 | 


--------------------------------------------------------------------------------
/tests/codegen/snapshots/typescript/union_return.ts:
--------------------------------------------------------------------------------
1 | type OperationNameResultGetPersonOrAnimalPerson = {
2 |     name: string
3 |     age: number
4 | }
5 | 
6 | type OperationNameResult = {
7 |     get_person_or_animal: OperationNameResultGetPersonOrAnimalPerson
8 | }
9 | 


--------------------------------------------------------------------------------
/tests/codegen/snapshots/typescript/union_with_one_type.ts:
--------------------------------------------------------------------------------
1 | type OperationNameResultUnionAnimal = {
2 |     age: number
3 |     name: string
4 | }
5 | 
6 | type OperationNameResult = {
7 |     union: OperationNameResultUnionAnimal
8 | }
9 | 


--------------------------------------------------------------------------------
/tests/codegen/snapshots/typescript/union_with_typename.ts:
--------------------------------------------------------------------------------
 1 | type OperationNameResultUnionAnimal = {
 2 |     age: number
 3 | }
 4 | 
 5 | type OperationNameResultUnionPerson = {
 6 |     name: string
 7 | }
 8 | 
 9 | type OperationNameResultUnion = OperationNameResultUnionAnimal | OperationNameResultUnionPerson
10 | 
11 | type OperationNameResultOptionalUnionAnimal = {
12 |     age: number
13 | }
14 | 
15 | type OperationNameResultOptionalUnionPerson = {
16 |     name: string
17 | }
18 | 
19 | type OperationNameResultOptionalUnion = OperationNameResultOptionalUnionAnimal | OperationNameResultOptionalUnionPerson
20 | 
21 | type OperationNameResult = {
22 |     __typename: string
23 |     union: OperationNameResultUnion
24 |     optional_union: OperationNameResultOptionalUnion | undefined
25 | }
26 | 


--------------------------------------------------------------------------------
/tests/codegen/snapshots/typescript/union_with_typename_and_fragment.ts:
--------------------------------------------------------------------------------
 1 | type AnimalProjection = {
 2 |     age: number
 3 | }
 4 | 
 5 | type OperationNameResultUnionPerson = {
 6 |     name: string
 7 | }
 8 | 
 9 | type OperationNameResultUnion = AnimalProjection | OperationNameResultUnionPerson
10 | 
11 | type OperationNameResultOptionalUnionPerson = {
12 |     name: string
13 | }
14 | 
15 | type OperationNameResultOptionalUnion = AnimalProjection | OperationNameResultOptionalUnionPerson
16 | 
17 | type OperationNameResult = {
18 |     __typename: string
19 |     union: OperationNameResultUnion
20 |     optional_union: OperationNameResultOptionalUnion | undefined
21 | }
22 | 


--------------------------------------------------------------------------------
/tests/codegen/snapshots/typescript/variables.ts:
--------------------------------------------------------------------------------
 1 | type OperationNameResult = {
 2 |     with_inputs: boolean
 3 | }
 4 | 
 5 | type PersonInput = {
 6 |     name: string
 7 |     age: number | undefined
 8 | }
 9 | 
10 | type ExampleInput = {
11 |     id: string
12 |     name: string
13 |     age: number
14 |     person: PersonInput | undefined
15 |     people: PersonInput[]
16 |     optional_people: PersonInput[] | undefined
17 | }
18 | 
19 | type OperationNameVariables = {
20 |     id: string | undefined
21 |     input: ExampleInput
22 |     ids: string[]
23 |     ids2: (string | undefined)[] | undefined
24 |     ids3: ((string | undefined)[] | undefined)[] | undefined
25 | }
26 | 


--------------------------------------------------------------------------------
/tests/codegen/snapshots/typescript/with_directives.ts:
--------------------------------------------------------------------------------
1 | type OperationNameResultPerson = {
2 |     name: string
3 | }
4 | 
5 | type OperationNameResult = {
6 |     person: OperationNameResultPerson
7 | }
8 | 


--------------------------------------------------------------------------------
/tests/codegen/test_print_operation.py:
--------------------------------------------------------------------------------
 1 | from pathlib import Path
 2 | 
 3 | import pytest
 4 | 
 5 | from strawberry.codegen import QueryCodegen
 6 | from strawberry.codegen.plugins.print_operation import PrintOperationPlugin
 7 | 
 8 | HERE = Path(__file__).parent
 9 | QUERIES = list(HERE.glob("queries/*.graphql"))
10 | 
11 | 
12 | @pytest.mark.parametrize("query", QUERIES, ids=[x.name for x in QUERIES])
13 | def test_codegen(
14 |     query: Path,
15 |     schema,
16 | ):
17 |     generator = QueryCodegen(schema, plugins=[PrintOperationPlugin(query)])
18 |     query_content = query.read_text()
19 | 
20 |     result = generator.run(query_content)
21 | 
22 |     assert result.to_string() == query_content
23 | 


--------------------------------------------------------------------------------
/tests/codemods/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/tests/codemods/__init__.py


--------------------------------------------------------------------------------
/tests/d.py:
--------------------------------------------------------------------------------
 1 | from __future__ import annotations
 2 | 
 3 | from typing import TYPE_CHECKING, Annotated
 4 | 
 5 | import strawberry
 6 | 
 7 | if TYPE_CHECKING:
 8 |     from tests.c import C
 9 | 
10 | 
11 | @strawberry.type
12 | class D:
13 |     id: strawberry.ID
14 | 
15 |     @strawberry.field
16 |     async def c_list(
17 |         self,
18 |     ) -> list[Annotated[C, strawberry.lazy("tests.c")]]:  # pragma: no cover
19 |         from tests.c import C
20 | 
21 |         return [C(id=self.id)]
22 | 


--------------------------------------------------------------------------------
/tests/django/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/tests/django/__init__.py


--------------------------------------------------------------------------------
/tests/django/app/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/tests/django/app/__init__.py


--------------------------------------------------------------------------------
/tests/django/app/models.py:
--------------------------------------------------------------------------------
1 | from django.db import models
2 | 
3 | 
4 | class Example(models.Model):  # noqa: DJ008
5 |     name = models.CharField(max_length=100)
6 | 


--------------------------------------------------------------------------------
/tests/django/app/urls.py:
--------------------------------------------------------------------------------
 1 | from django.urls import path
 2 | 
 3 | from strawberry.django.views import GraphQLView as BaseGraphQLView
 4 | from tests.views.schema import Query, schema
 5 | 
 6 | 
 7 | class GraphQLView(BaseGraphQLView):
 8 |     def get_root_value(self, request) -> Query:
 9 |         return Query()
10 | 
11 | 
12 | urlpatterns = [
13 |     path("graphql/", GraphQLView.as_view(schema=schema)),
14 | ]
15 | 


--------------------------------------------------------------------------------
/tests/django/conftest.py:
--------------------------------------------------------------------------------
 1 | from __future__ import annotations
 2 | 
 3 | from typing import TYPE_CHECKING
 4 | 
 5 | import pytest
 6 | 
 7 | if TYPE_CHECKING:
 8 |     from strawberry.django.test import GraphQLTestClient
 9 | 
10 | 
11 | @pytest.fixture
12 | def graphql_client() -> GraphQLTestClient:
13 |     from django.test.client import Client
14 | 
15 |     from strawberry.django.test import GraphQLTestClient
16 | 
17 |     return GraphQLTestClient(Client())
18 | 


--------------------------------------------------------------------------------
/tests/django/django_settings.py:
--------------------------------------------------------------------------------
 1 | SECRET_KEY = 1
 2 | 
 3 | INSTALLED_APPS = ["tests.django.app"]
 4 | ROOT_URLCONF = "tests.django.app.urls"
 5 | 
 6 | TEMPLATES = [
 7 |     {
 8 |         "BACKEND": "django.template.backends.django.DjangoTemplates",
 9 |         "DIRS": [],
10 |         "APP_DIRS": True,
11 |     }
12 | ]
13 | 
14 | DATABASES = {"default": {"ENGINE": "django.db.backends.sqlite3", "NAME": ":memory:"}}
15 | 
16 | # This is for channels integration, but only one django settings can be used
17 | # per pytest_django settings
18 | CHANNEL_LAYERS = {"default": {"BACKEND": "channels.layers.InMemoryChannelLayer"}}
19 | 


--------------------------------------------------------------------------------
/tests/django/test_extensions.py:
--------------------------------------------------------------------------------
1 | def test_extensions(graphql_client):
2 |     query = "{ hello }"
3 | 
4 |     response = graphql_client.query(query)
5 | 
6 |     assert response.extensions["example"] == "example"
7 | 


--------------------------------------------------------------------------------
/tests/enums/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/tests/enums/__init__.py


--------------------------------------------------------------------------------
/tests/exceptions/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/tests/exceptions/__init__.py


--------------------------------------------------------------------------------
/tests/exceptions/classes/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/tests/exceptions/classes/__init__.py


--------------------------------------------------------------------------------
/tests/exceptions/test_exception_source.py:
--------------------------------------------------------------------------------
 1 | import sys
 2 | from pathlib import Path
 3 | 
 4 | import pytest
 5 | 
 6 | from strawberry.exceptions.exception_source import ExceptionSource
 7 | 
 8 | pytestmark = pytest.mark.skipif(
 9 |     sys.platform == "win32", reason="Test is meant to run on Unix systems"
10 | )
11 | 
12 | 
13 | def test_returns_relative_path(mocker):
14 |     mocker.patch.object(Path, "cwd", return_value="/home/user/project/")
15 | 
16 |     source = ExceptionSource(
17 |         path=Path("/home/user/project/src/main.py"),
18 |         code="",
19 |         start_line=1,
20 |         end_line=1,
21 |         error_line=1,
22 |         error_column=1,
23 |         error_column_end=1,
24 |     )
25 | 
26 |     assert source.path_relative_to_cwd == Path("src/main.py")
27 | 
28 | 
29 | def test_returns_relative_path_when_is_already_relative():
30 |     source = ExceptionSource(
31 |         path=Path("src/main.py"),
32 |         code="",
33 |         start_line=1,
34 |         end_line=1,
35 |         error_line=1,
36 |         error_column=1,
37 |         error_column_end=1,
38 |     )
39 | 
40 |     assert source.path_relative_to_cwd == Path("src/main.py")
41 | 


--------------------------------------------------------------------------------
/tests/experimental/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/tests/experimental/__init__.py


--------------------------------------------------------------------------------
/tests/experimental/pydantic/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/tests/experimental/pydantic/__init__.py


--------------------------------------------------------------------------------
/tests/experimental/pydantic/schema/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/tests/experimental/pydantic/schema/__init__.py


--------------------------------------------------------------------------------
/tests/experimental/pydantic/schema/test_forward_reference.py:
--------------------------------------------------------------------------------
 1 | from __future__ import annotations
 2 | 
 3 | import textwrap
 4 | from typing import Optional
 5 | 
 6 | import pydantic
 7 | 
 8 | import strawberry
 9 | 
10 | 
11 | def test_auto_fields():
12 |     global User
13 | 
14 |     class UserModel(pydantic.BaseModel):
15 |         age: int
16 |         password: Optional[str]
17 |         other: float
18 | 
19 |     @strawberry.experimental.pydantic.type(UserModel)
20 |     class User:
21 |         age: strawberry.auto
22 |         password: strawberry.auto
23 | 
24 |     @strawberry.type
25 |     class Query:
26 |         @strawberry.field
27 |         def user(self) -> User:
28 |             return User(age=1, password="ABC")
29 | 
30 |     schema = strawberry.Schema(query=Query)
31 | 
32 |     expected_schema = """
33 |     type Query {
34 |       user: User!
35 |     }
36 | 
37 |     type User {
38 |       age: Int!
39 |       password: String
40 |     }
41 |     """
42 | 
43 |     assert str(schema) == textwrap.dedent(expected_schema).strip()
44 | 
45 |     query = "{ user { age } }"
46 | 
47 |     result = schema.execute_sync(query)
48 | 
49 |     assert not result.errors
50 |     assert result.data["user"]["age"] == 1
51 | 


--------------------------------------------------------------------------------
/tests/experimental/pydantic/utils.py:
--------------------------------------------------------------------------------
1 | import pytest
2 | 
3 | from strawberry.experimental.pydantic._compat import IS_PYDANTIC_V2
4 | 
5 | needs_pydantic_v2 = pytest.mark.skipif(
6 |     not IS_PYDANTIC_V2, reason="requires Pydantic v2"
7 | )
8 | needs_pydantic_v1 = pytest.mark.skipif(IS_PYDANTIC_V2, reason="requires Pydantic v1")
9 | 


--------------------------------------------------------------------------------
/tests/extensions/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/tests/extensions/__init__.py


--------------------------------------------------------------------------------
/tests/extensions/tracing/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/tests/extensions/tracing/__init__.py


--------------------------------------------------------------------------------
/tests/fastapi/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/tests/fastapi/__init__.py


--------------------------------------------------------------------------------
/tests/fastapi/app.py:
--------------------------------------------------------------------------------
 1 | from typing import Any, Union
 2 | 
 3 | from fastapi import BackgroundTasks, Depends, FastAPI, Request, WebSocket
 4 | from strawberry.fastapi import GraphQLRouter
 5 | from tests.views.schema import schema
 6 | 
 7 | 
 8 | def custom_context_dependency() -> str:
 9 |     return "Hi!"
10 | 
11 | 
12 | async def get_context(
13 |     background_tasks: BackgroundTasks,
14 |     request: Request = None,
15 |     ws: WebSocket = None,
16 |     custom_value=Depends(custom_context_dependency),
17 | ) -> dict[str, Any]:
18 |     return {
19 |         "custom_value": custom_value,
20 |         "request": request or ws,
21 |         "background_tasks": background_tasks,
22 |     }
23 | 
24 | 
25 | async def get_root_value(
26 |     request: Request = None, ws: WebSocket = None
27 | ) -> Union[Request, WebSocket]:
28 |     return request or ws
29 | 
30 | 
31 | def create_app(schema=schema, **kwargs: Any) -> FastAPI:
32 |     app = FastAPI()
33 | 
34 |     graphql_app = GraphQLRouter(
35 |         schema, context_getter=get_context, root_value_getter=get_root_value, **kwargs
36 |     )
37 |     app.include_router(graphql_app, prefix="/graphql")
38 | 
39 |     return app
40 | 


--------------------------------------------------------------------------------
/tests/fastapi/test_async.py:
--------------------------------------------------------------------------------
 1 | from __future__ import annotations
 2 | 
 3 | from typing import TYPE_CHECKING, Optional
 4 | 
 5 | import pytest
 6 | 
 7 | import strawberry
 8 | 
 9 | if TYPE_CHECKING:
10 |     from starlette.testclient import TestClient
11 | 
12 | 
13 | @pytest.fixture
14 | def test_client() -> TestClient:
15 |     from starlette.testclient import TestClient
16 | 
17 |     from tests.fastapi.app import create_app
18 | 
19 |     @strawberry.type
20 |     class Query:
21 |         @strawberry.field
22 |         async def hello(self, name: Optional[str] = None) -> str:
23 |             return f"Hello {name or 'world'}"
24 | 
25 |     async_schema = strawberry.Schema(Query)
26 |     app = create_app(schema=async_schema)
27 |     return TestClient(app)
28 | 
29 | 
30 | def test_simple_query(test_client: TestClient):
31 |     response = test_client.post("/graphql", json={"query": "{ hello }"})
32 | 
33 |     assert response.json() == {"data": {"hello": "Hello world"}}
34 | 


--------------------------------------------------------------------------------
/tests/federation/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/tests/federation/__init__.py


--------------------------------------------------------------------------------
/tests/federation/printer/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/tests/federation/printer/__init__.py


--------------------------------------------------------------------------------
/tests/federation/printer/test_interface_object.py:
--------------------------------------------------------------------------------
 1 | import textwrap
 2 | 
 3 | import strawberry
 4 | 
 5 | 
 6 | def test_interface_object():
 7 |     @strawberry.federation.interface_object(keys=["id"])
 8 |     class SomeInterface:
 9 |         id: strawberry.ID
10 | 
11 |     schema = strawberry.federation.Schema(
12 |         types=[SomeInterface], enable_federation_2=True
13 |     )
14 | 
15 |     expected = """
16 |         schema @link(url: "https://specs.apollo.dev/federation/v2.7", import: ["@interfaceObject", "@key"]) {
17 |           query: Query
18 |         }
19 | 
20 |         type Query {
21 |           _entities(representations: [_Any!]!): [_Entity]!
22 |           _service: _Service!
23 |         }
24 | 
25 |         type SomeInterface @key(fields: "id") @interfaceObject {
26 |           id: ID!
27 |         }
28 | 
29 |         scalar _Any
30 | 
31 |         union _Entity = SomeInterface
32 | 
33 |         type _Service {
34 |           sdl: String!
35 |         }
36 |     """
37 | 
38 |     assert schema.as_str() == textwrap.dedent(expected).strip()
39 | 


--------------------------------------------------------------------------------
/tests/federation/printer/test_one_of.py:
--------------------------------------------------------------------------------
 1 | import textwrap
 2 | from typing import Optional
 3 | 
 4 | import strawberry
 5 | 
 6 | 
 7 | def test_prints_one_of_directive():
 8 |     @strawberry.federation.input(one_of=True, tags=["myTag", "anotherTag"])
 9 |     class Input:
10 |         a: Optional[str] = strawberry.UNSET
11 |         b: Optional[int] = strawberry.UNSET
12 | 
13 |     @strawberry.federation.type
14 |     class Query:
15 |         hello: str
16 | 
17 |     schema = strawberry.federation.Schema(
18 |         query=Query, types=[Input], enable_federation_2=True
19 |     )
20 | 
21 |     expected = """
22 |         directive @oneOf on INPUT_OBJECT
23 | 
24 |         schema @link(url: "https://specs.apollo.dev/federation/v2.7", import: ["@tag"]) {
25 |           query: Query
26 |         }
27 | 
28 |         input Input @tag(name: "myTag") @tag(name: "anotherTag") @oneOf {
29 |           a: String
30 |           b: Int
31 |         }
32 | 
33 |         type Query {
34 |           _service: _Service!
35 |           hello: String!
36 |         }
37 | 
38 |         scalar _Any
39 | 
40 |         type _Service {
41 |           sdl: String!
42 |         }
43 |     """
44 | 
45 |     assert schema.as_str() == textwrap.dedent(expected).strip()
46 | 


--------------------------------------------------------------------------------
/tests/federation/test_types.py:
--------------------------------------------------------------------------------
 1 | import strawberry
 2 | 
 3 | 
 4 | def test_type():
 5 |     @strawberry.federation.type(keys=["id"])
 6 |     class Location:
 7 |         id: strawberry.ID
 8 | 
 9 |     assert Location(id=strawberry.ID("1")).id == "1"
10 | 
11 | 
12 | def test_type_and_override():
13 |     @strawberry.federation.type(keys=["id"])
14 |     class Location:
15 |         id: strawberry.ID
16 |         address: str = strawberry.federation.field(override="start")
17 | 
18 |     location = Location(id=strawberry.ID("1"), address="ABC")
19 | 
20 |     assert location.id == "1"
21 |     assert location.address == "ABC"
22 | 
23 | 
24 | def test_type_and_override_with_resolver():
25 |     @strawberry.federation.type(keys=["id"])
26 |     class Location:
27 |         id: strawberry.ID
28 |         address: str = strawberry.federation.field(
29 |             override="start", resolver=lambda: "ABC"
30 |         )
31 | 
32 |     location = Location(id=strawberry.ID("1"))
33 | 
34 |     assert location.id == "1"
35 | 


--------------------------------------------------------------------------------
/tests/fields/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/tests/fields/__init__.py


--------------------------------------------------------------------------------
/tests/fields/test_field_basics.py:
--------------------------------------------------------------------------------
 1 | import strawberry
 2 | 
 3 | 
 4 | def test_type_add_type_definition_with_fields():
 5 |     @strawberry.type
 6 |     class Query:
 7 |         name: str
 8 |         age: int
 9 | 
10 |     definition = Query.__strawberry_definition__
11 | 
12 |     assert definition.name == "Query"
13 |     assert len(definition.fields) == 2
14 | 
15 |     assert definition.fields[0].python_name == "name"
16 |     assert definition.fields[0].type is str
17 | 
18 |     assert definition.fields[1].python_name == "age"
19 |     assert definition.fields[1].type is int
20 | 
21 | 
22 | def test_passing_nothing_to_fields():
23 |     @strawberry.type
24 |     class Query:
25 |         name: str = strawberry.field()
26 |         age: int = strawberry.field()
27 | 
28 |     definition = Query.__strawberry_definition__
29 | 
30 |     assert definition.name == "Query"
31 |     assert len(definition.fields) == 2
32 | 
33 |     assert definition.fields[0].python_name == "name"
34 |     assert definition.fields[0].type is str
35 | 
36 |     assert definition.fields[1].python_name == "age"
37 |     assert definition.fields[1].type is int
38 | 


--------------------------------------------------------------------------------
/tests/fields/test_field_descriptions.py:
--------------------------------------------------------------------------------
 1 | import strawberry
 2 | 
 3 | 
 4 | def test_field_descriptions():
 5 |     description = "this description is super cool"
 6 | 
 7 |     field = strawberry.field(description=description)
 8 | 
 9 |     assert field.description == description
10 | 


--------------------------------------------------------------------------------
/tests/fields/test_field_names.py:
--------------------------------------------------------------------------------
 1 | import strawberry
 2 | 
 3 | 
 4 | def test_field_name_standard():
 5 |     standard_field = strawberry.field()
 6 | 
 7 |     assert standard_field.python_name is None
 8 |     assert standard_field.graphql_name is None
 9 | 
10 | 
11 | def test_field_name_standard_on_schema():
12 |     @strawberry.type()
13 |     class Query:
14 |         normal_field: int
15 | 
16 |     [field] = Query.__strawberry_definition__.fields
17 | 
18 |     assert field.python_name == "normal_field"
19 |     assert field.graphql_name is None
20 | 
21 | 
22 | def test_field_name_override():
23 |     field_name = "override"
24 | 
25 |     standard_field = strawberry.field(name=field_name)
26 | 
27 |     assert standard_field.python_name is None  # Set once field is added to a Schema
28 |     assert standard_field.graphql_name == field_name
29 | 
30 | 
31 | def test_field_name_override_with_schema():
32 |     field_name = "override_name"
33 | 
34 |     @strawberry.type()
35 |     class Query:
36 |         override_field: bool = strawberry.field(name=field_name)
37 | 
38 |     [field] = Query.__strawberry_definition__.fields
39 | 
40 |     assert field.python_name == "override_field"
41 |     assert field.graphql_name == field_name
42 | 


--------------------------------------------------------------------------------
/tests/file_uploads/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/tests/file_uploads/__init__.py


--------------------------------------------------------------------------------
/tests/fixtures/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/tests/fixtures/__init__.py


--------------------------------------------------------------------------------
/tests/fixtures/sample_package/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/tests/fixtures/sample_package/__init__.py


--------------------------------------------------------------------------------
/tests/http/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/tests/http/__init__.py


--------------------------------------------------------------------------------
/tests/http/clients/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/tests/http/clients/__init__.py


--------------------------------------------------------------------------------
/tests/http/context.py:
--------------------------------------------------------------------------------
1 | def get_context(context: object) -> dict[str, object]:
2 |     assert isinstance(context, dict)
3 | 
4 |     return {**context, "custom_value": "a value from context"}
5 | 


--------------------------------------------------------------------------------
/tests/http/test_http.py:
--------------------------------------------------------------------------------
 1 | from typing import Literal
 2 | 
 3 | import pytest
 4 | 
 5 | from strawberry.http.base import BaseView
 6 | 
 7 | from .clients.base import HttpClient
 8 | 
 9 | 
10 | @pytest.mark.parametrize("method", ["delete", "head", "put", "patch"])
11 | async def test_does_only_allow_get_and_post(
12 |     method: Literal["delete", "head", "put", "patch"],
13 |     http_client: HttpClient,
14 | ):
15 |     response = await http_client.request(url="/graphql", method=method)
16 | 
17 |     assert response.status_code == 405
18 | 
19 | 
20 | async def test_the_http_handler_uses_the_views_decode_json_method(
21 |     http_client: HttpClient, mocker
22 | ):
23 |     spy = mocker.spy(BaseView, "decode_json")
24 | 
25 |     response = await http_client.query(query="{ hello }")
26 |     assert response.status_code == 200
27 | 
28 |     data = response.json["data"]
29 |     assert isinstance(data, dict)
30 |     assert data["hello"] == "Hello world"
31 | 
32 |     assert spy.call_count == 1
33 | 


--------------------------------------------------------------------------------
/tests/http/test_mutation.py:
--------------------------------------------------------------------------------
 1 | from .clients.base import HttpClient
 2 | 
 3 | 
 4 | async def test_mutation(http_client: HttpClient):
 5 |     response = await http_client.query(
 6 |         query="mutation { hello }",
 7 |         headers={
 8 |             "Content-Type": "application/json",
 9 |         },
10 |     )
11 |     data = response.json["data"]
12 | 
13 |     assert response.status_code == 200
14 |     assert isinstance(data, dict)
15 |     assert data["hello"] == "strawberry"
16 | 


--------------------------------------------------------------------------------
/tests/http/test_process_result.py:
--------------------------------------------------------------------------------
 1 | from __future__ import annotations
 2 | 
 3 | from typing_extensions import Literal
 4 | 
 5 | import pytest
 6 | 
 7 | from strawberry.http import GraphQLHTTPResponse
 8 | from strawberry.types import ExecutionResult
 9 | 
10 | from .clients.base import HttpClient
11 | 
12 | 
13 | def process_result(result: ExecutionResult) -> GraphQLHTTPResponse:
14 |     if result.data:
15 |         return {
16 |             "data": {key.upper(): result for key, result in result.data.items()},
17 |         }
18 | 
19 |     return {}
20 | 
21 | 
22 | @pytest.fixture
23 | def http_client(http_client_class) -> HttpClient:
24 |     return http_client_class(result_override=process_result)
25 | 
26 | 
27 | @pytest.mark.parametrize("method", ["get", "post"])
28 | async def test_custom_process_result(
29 |     method: Literal["get", "post"], http_client: HttpClient
30 | ):
31 |     response = await http_client.query(
32 |         method=method,
33 |         query="{ hello }",
34 |     )
35 |     assert response.json["data"] == {"HELLO": "Hello world"}
36 | 


--------------------------------------------------------------------------------
/tests/litestar/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/tests/litestar/__init__.py


--------------------------------------------------------------------------------
/tests/litestar/app.py:
--------------------------------------------------------------------------------
 1 | from typing import Any
 2 | 
 3 | from litestar import Litestar, Request
 4 | from litestar.di import Provide
 5 | from strawberry.litestar import make_graphql_controller
 6 | from tests.views.schema import schema
 7 | 
 8 | 
 9 | def custom_context_dependency() -> str:
10 |     return "Hi!"
11 | 
12 | 
13 | async def get_root_value(request: Request = None):
14 |     return request
15 | 
16 | 
17 | async def get_context(app_dependency: str, request: Request = None):
18 |     return {"custom_value": app_dependency, "request": request}
19 | 
20 | 
21 | def create_app(schema=schema, **kwargs: Any):
22 |     GraphQLController = make_graphql_controller(
23 |         schema,
24 |         path="/graphql",
25 |         context_getter=get_context,
26 |         root_value_getter=get_root_value,
27 |         **kwargs,
28 |     )
29 | 
30 |     return Litestar(
31 |         route_handlers=[GraphQLController],
32 |         dependencies={
33 |             "app_dependency": Provide(custom_context_dependency, sync_to_thread=True)
34 |         },
35 |     )
36 | 


--------------------------------------------------------------------------------
/tests/litestar/conftest.py:
--------------------------------------------------------------------------------
 1 | import pytest
 2 | 
 3 | 
 4 | @pytest.fixture
 5 | def test_client():
 6 |     from litestar.testing import TestClient
 7 |     from tests.litestar.app import create_app
 8 | 
 9 |     app = create_app()
10 |     return TestClient(app)
11 | 
12 | 
13 | @pytest.fixture
14 | def test_client_keep_alive():
15 |     from litestar.testing import TestClient
16 |     from tests.litestar.app import create_app
17 | 
18 |     app = create_app(keep_alive=True, keep_alive_interval=0.1)
19 |     return TestClient(app)
20 | 


--------------------------------------------------------------------------------
/tests/objects/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/tests/objects/__init__.py


--------------------------------------------------------------------------------
/tests/objects/generics/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/tests/objects/generics/__init__.py


--------------------------------------------------------------------------------
/tests/objects/test_inheritance.py:
--------------------------------------------------------------------------------
 1 | from typing import Optional
 2 | 
 3 | import strawberry
 4 | 
 5 | 
 6 | def test_inherited_fields():
 7 |     @strawberry.type
 8 |     class A:
 9 |         a: str = strawberry.field(default="")
10 | 
11 |     @strawberry.type
12 |     class B(A):
13 |         b: Optional[str] = strawberry.field(default=None)
14 | 
15 |     assert strawberry.Schema(query=B)
16 | 


--------------------------------------------------------------------------------
/tests/objects/test_object_instantiation.py:
--------------------------------------------------------------------------------
 1 | import strawberry
 2 | 
 3 | 
 4 | def test_can_instantiate_types_directly():
 5 |     @strawberry.type
 6 |     class User:
 7 |         username: str
 8 | 
 9 |         @strawberry.field
10 |         def email(self) -> str:
11 |             return self.username + "@somesite.com"
12 | 
13 |     user = User(username="abc")
14 |     assert user.username == "abc"
15 |     assert user.email() == "abc@somesite.com"
16 | 


--------------------------------------------------------------------------------
/tests/plugins/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/tests/plugins/__init__.py


--------------------------------------------------------------------------------
/tests/python_312/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/tests/python_312/__init__.py


--------------------------------------------------------------------------------
/tests/relay/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/tests/relay/__init__.py


--------------------------------------------------------------------------------
/tests/sanic/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/tests/sanic/__init__.py


--------------------------------------------------------------------------------
/tests/schema/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/tests/schema/__init__.py


--------------------------------------------------------------------------------
/tests/schema/extensions/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/tests/schema/extensions/__init__.py


--------------------------------------------------------------------------------
/tests/schema/extensions/schema_extensions/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/tests/schema/extensions/schema_extensions/__init__.py


--------------------------------------------------------------------------------
/tests/schema/extensions/test_imports.py:
--------------------------------------------------------------------------------
 1 | import pytest
 2 | 
 3 | 
 4 | def test_can_import(mocker):
 5 |     # mocking sys.modules.ddtrace so we don't get an ImportError
 6 |     mocker.patch.dict("sys.modules", ddtrace=mocker.MagicMock())
 7 | 
 8 | 
 9 | def test_fails_if_import_is_not_found():
10 |     with pytest.raises(ImportError):
11 |         from strawberry.extensions.tracing import Blueberry  # noqa: F401
12 | 


--------------------------------------------------------------------------------
/tests/schema/extensions/test_input_mutation_future.py:
--------------------------------------------------------------------------------
 1 | from __future__ import annotations
 2 | 
 3 | import textwrap
 4 | from uuid import UUID
 5 | 
 6 | import strawberry
 7 | from strawberry.field_extensions import InputMutationExtension
 8 | 
 9 | 
10 | @strawberry.type
11 | class Query:
12 |     @strawberry.field
13 |     async def hello(self) -> str:
14 |         return "hi"
15 | 
16 | 
17 | @strawberry.type
18 | class Mutation:
19 |     @strawberry.mutation(extensions=[InputMutationExtension()])
20 |     async def buggy(self, some_id: UUID) -> None:
21 |         del some_id
22 | 
23 | 
24 | def test_schema():
25 |     schema = strawberry.Schema(query=Query, mutation=Mutation)
26 | 
27 |     expected_schema = '''
28 |     input BuggyInput {
29 |       someId: UUID!
30 |     }
31 | 
32 |     type Mutation {
33 |       buggy(
34 |         """Input data for `buggy` mutation"""
35 |         input: BuggyInput!
36 |       ): Void
37 |     }
38 | 
39 |     type Query {
40 |       hello: String!
41 |     }
42 | 
43 |     scalar UUID
44 | 
45 |     """Represents NULL values"""
46 |     scalar Void
47 |     '''
48 | 
49 |     assert textwrap.dedent(expected_schema).strip() == str(schema).strip()
50 | 


--------------------------------------------------------------------------------
/tests/schema/test_annotated/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/tests/schema/test_annotated/__init__.py


--------------------------------------------------------------------------------
/tests/schema/test_annotated/type_a.py:
--------------------------------------------------------------------------------
 1 | from __future__ import annotations
 2 | 
 3 | from typing import Annotated, Optional
 4 | from uuid import UUID
 5 | 
 6 | import strawberry
 7 | 
 8 | 
 9 | @strawberry.type
10 | class Query:
11 |     @strawberry.field
12 |     def get_testing(
13 |         self,
14 |         info: strawberry.Info,
15 |         id_: Annotated[UUID, strawberry.argument(name="id")],
16 |     ) -> Optional[str]: ...
17 | 


--------------------------------------------------------------------------------
/tests/schema/test_annotated/type_b.py:
--------------------------------------------------------------------------------
 1 | from __future__ import annotations
 2 | 
 3 | from typing import Annotated, Optional
 4 | from uuid import UUID
 5 | 
 6 | import strawberry
 7 | 
 8 | 
 9 | @strawberry.type
10 | class Query:
11 |     @strawberry.field
12 |     def get_testing(
13 |         self,
14 |         id_: Annotated[UUID, strawberry.argument(name="id")],
15 |         info: strawberry.Info,
16 |     ) -> Optional[str]: ...
17 | 


--------------------------------------------------------------------------------
/tests/schema/test_config.py:
--------------------------------------------------------------------------------
 1 | import pytest
 2 | 
 3 | from strawberry.schema.config import StrawberryConfig
 4 | from strawberry.types.info import Info
 5 | 
 6 | 
 7 | def test_config_post_init_auto_camel_case():
 8 |     config = StrawberryConfig(auto_camel_case=True)
 9 | 
10 |     assert config.name_converter.auto_camel_case is True
11 | 
12 | 
13 | def test_config_post_init_no_auto_camel_case():
14 |     config = StrawberryConfig(auto_camel_case=False)
15 | 
16 |     assert config.name_converter.auto_camel_case is False
17 | 
18 | 
19 | def test_config_post_init_info_class():
20 |     class CustomInfo(Info):
21 |         test: str = "foo"
22 | 
23 |     config = StrawberryConfig(info_class=CustomInfo)
24 | 
25 |     assert config.info_class is CustomInfo
26 |     assert config.info_class.test == "foo"
27 | 
28 | 
29 | def test_config_post_init_info_class_is_default():
30 |     config = StrawberryConfig()
31 | 
32 |     assert config.info_class is Info
33 | 
34 | 
35 | def test_config_post_init_info_class_is_not_subclass():
36 |     with pytest.raises(TypeError) as exc_info:
37 |         StrawberryConfig(info_class=object)
38 | 
39 |     assert str(exc_info.value) == "`info_class` must be a subclass of strawberry.Info"
40 | 


--------------------------------------------------------------------------------
/tests/schema/test_dataloaders.py:
--------------------------------------------------------------------------------
 1 | from dataclasses import dataclass
 2 | 
 3 | import pytest
 4 | 
 5 | import strawberry
 6 | from strawberry.dataloader import DataLoader
 7 | 
 8 | 
 9 | @pytest.mark.asyncio
10 | async def test_can_use_dataloaders(mocker):
11 |     @dataclass
12 |     class User:
13 |         id: str
14 | 
15 |     async def idx(keys) -> list[User]:
16 |         return [User(key) for key in keys]
17 | 
18 |     mock_loader = mocker.Mock(side_effect=idx)
19 | 
20 |     loader = DataLoader(load_fn=mock_loader)
21 | 
22 |     @strawberry.type
23 |     class Query:
24 |         @strawberry.field
25 |         async def get_user(self, id: strawberry.ID) -> str:
26 |             user = await loader.load(id)
27 | 
28 |             return user.id
29 | 
30 |     schema = strawberry.Schema(query=Query)
31 | 
32 |     query = """{
33 |         a: getUser(id: "1")
34 |         b: getUser(id: "2")
35 |     }"""
36 | 
37 |     result = await schema.execute(query)
38 | 
39 |     assert not result.errors
40 |     assert result.data == {
41 |         "a": "1",
42 |         "b": "2",
43 |     }
44 | 
45 |     mock_loader.assert_called_once_with(["1", "2"])
46 | 


--------------------------------------------------------------------------------
/tests/schema/test_lazy/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/tests/schema/test_lazy/__init__.py


--------------------------------------------------------------------------------
/tests/schema/test_lazy/schema.py:
--------------------------------------------------------------------------------
1 | import strawberry
2 | from tests.schema.test_lazy.type_c import Query
3 | 
4 | schema = strawberry.Schema(query=Query)
5 | 


--------------------------------------------------------------------------------
/tests/schema/test_lazy/test_lazy.py:
--------------------------------------------------------------------------------
 1 | import textwrap
 2 | 
 3 | import strawberry
 4 | from strawberry.printer import print_schema
 5 | 
 6 | 
 7 | def test_cyclic_import():
 8 |     from .type_a import TypeA
 9 |     from .type_b import TypeB
10 | 
11 |     @strawberry.type
12 |     class Query:
13 |         a: TypeA
14 |         b: TypeB
15 | 
16 |     expected = """
17 |     type Query {
18 |       a: TypeA!
19 |       b: TypeB!
20 |     }
21 | 
22 |     type TypeA {
23 |       listOfB: [TypeB!]
24 |       typeB: TypeB!
25 |     }
26 | 
27 |     type TypeB {
28 |       typeA: TypeA!
29 |       typeAList: [TypeA!]!
30 |       typeCList: [TypeC!]!
31 |     }
32 | 
33 |     type TypeC {
34 |       name: String!
35 |     }
36 |     """
37 | 
38 |     schema = strawberry.Schema(Query)
39 | 
40 |     assert print_schema(schema) == textwrap.dedent(expected).strip()
41 | 


--------------------------------------------------------------------------------
/tests/schema/test_lazy/type_a.py:
--------------------------------------------------------------------------------
 1 | from typing import TYPE_CHECKING, Annotated, Optional
 2 | 
 3 | import strawberry
 4 | 
 5 | if TYPE_CHECKING:
 6 |     from .type_b import TypeB
 7 | 
 8 | 
 9 | @strawberry.type
10 | class TypeA:
11 |     list_of_b: Optional[
12 |         list[Annotated["TypeB", strawberry.lazy("tests.schema.test_lazy.type_b")]]
13 |     ] = None
14 | 
15 |     @strawberry.field
16 |     def type_b(self) -> Annotated["TypeB", strawberry.lazy(".type_b")]:
17 |         from .type_b import TypeB
18 | 
19 |         return TypeB()
20 | 


--------------------------------------------------------------------------------
/tests/schema/test_lazy/type_b.py:
--------------------------------------------------------------------------------
 1 | from typing import TYPE_CHECKING, Annotated
 2 | 
 3 | import strawberry
 4 | 
 5 | if TYPE_CHECKING:
 6 |     from .type_a import TypeA
 7 |     from .type_c import TypeC
 8 | 
 9 |     ListTypeA = list[TypeA]
10 |     ListTypeC = list[TypeC]
11 | else:
12 |     TypeA = Annotated["TypeA", strawberry.lazy("tests.schema.test_lazy.type_a")]
13 |     ListTypeA = list[
14 |         Annotated["TypeA", strawberry.lazy("tests.schema.test_lazy.type_a")]
15 |     ]
16 |     ListTypeC = list[
17 |         Annotated["TypeC", strawberry.lazy("tests.schema.test_lazy.type_c")]
18 |     ]
19 | 
20 | 
21 | @strawberry.type
22 | class TypeB:
23 |     @strawberry.field()
24 |     def type_a(
25 |         self,
26 |     ) -> TypeA:
27 |         from .type_a import TypeA
28 | 
29 |         return TypeA()
30 | 
31 |     @strawberry.field()
32 |     def type_a_list(
33 |         self,
34 |     ) -> ListTypeA:  # pragma: no cover
35 |         from .type_a import TypeA
36 | 
37 |         return [TypeA()]
38 | 
39 |     @strawberry.field()
40 |     def type_c_list(
41 |         self,
42 |     ) -> ListTypeC:  # pragma: no cover
43 |         from .type_c import TypeC
44 | 
45 |         return [TypeC()]
46 | 


--------------------------------------------------------------------------------
/tests/schema/test_lazy/type_c.py:
--------------------------------------------------------------------------------
 1 | import sys
 2 | from typing import Annotated, Generic, TypeVar
 3 | 
 4 | import strawberry
 5 | 
 6 | T = TypeVar("T")
 7 | 
 8 | 
 9 | @strawberry.type
10 | class TypeC:
11 |     name: str
12 | 
13 | 
14 | @strawberry.type
15 | class Edge(Generic[T]):
16 |     @strawberry.field
17 |     def node(self) -> T:  # type: ignore
18 |         ...
19 | 
20 | 
21 | @strawberry.type
22 | class Query:
23 |     type_a: Edge[TypeC]
24 |     type_b: Edge[Annotated["TypeC", strawberry.lazy("tests.schema.test_lazy.type_c")]]
25 | 
26 | 
27 | if __name__ == "__main__":
28 |     schema = strawberry.Schema(query=Query)
29 |     sys.stdout.write(f"{schema.as_str()}\n")
30 | 


--------------------------------------------------------------------------------
/tests/schema/test_lazy/type_d.py:
--------------------------------------------------------------------------------
 1 | import sys
 2 | from typing import Annotated, Generic, TypeVar
 3 | 
 4 | import strawberry
 5 | 
 6 | T = TypeVar("T")
 7 | 
 8 | 
 9 | class Mixin(Generic[T]):
10 |     node: T
11 | 
12 | 
13 | @strawberry.type
14 | class TypeD(Mixin[int]):
15 |     name: str
16 | 
17 | 
18 | @strawberry.type
19 | class Query:
20 |     type_d_1: TypeD
21 |     type_d: Annotated["TypeD", strawberry.lazy("tests.schema.test_lazy.type_d")]
22 | 
23 | 
24 | if __name__ == "__main__":
25 |     schema = strawberry.Schema(query=Query)
26 |     sys.stdout.write(f"{schema.as_str()}\n")
27 | 


--------------------------------------------------------------------------------
/tests/schema/test_lazy/type_e.py:
--------------------------------------------------------------------------------
 1 | from enum import Enum
 2 | from typing import Generic, TypeVar
 3 | 
 4 | import strawberry
 5 | 
 6 | T = TypeVar("T")
 7 | 
 8 | 
 9 | @strawberry.enum
10 | class MyEnum(Enum):
11 |     ONE = "ONE"
12 | 
13 | 
14 | @strawberry.type
15 | class ValueContainer(Generic[T]):
16 |     value: T
17 | 
18 | 
19 | UnionValue = strawberry.union(
20 |     "UnionValue",
21 |     types=(
22 |         ValueContainer[int],
23 |         ValueContainer[MyEnum],
24 |     ),
25 | )
26 | 


--------------------------------------------------------------------------------
/tests/schema/test_lazy_types/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/tests/schema/test_lazy_types/__init__.py


--------------------------------------------------------------------------------
/tests/schema/test_lazy_types/test_cyclic.py:
--------------------------------------------------------------------------------
 1 | import textwrap
 2 | 
 3 | import strawberry
 4 | from strawberry.printer import print_schema
 5 | 
 6 | 
 7 | def test_cyclic_import():
 8 |     from .type_a import TypeA
 9 |     from .type_b import TypeB
10 | 
11 |     @strawberry.type
12 |     class Query:
13 |         a: TypeA
14 |         b: TypeB
15 | 
16 |     expected = """
17 |     type Query {
18 |       a: TypeA!
19 |       b: TypeB!
20 |     }
21 | 
22 |     type TypeA {
23 |       listOfB: [TypeB!]
24 |       typeB: TypeB!
25 |     }
26 | 
27 |     type TypeB {
28 |       typeA: TypeA!
29 |     }
30 |     """
31 | 
32 |     schema = strawberry.Schema(Query)
33 | 
34 |     assert print_schema(schema) == textwrap.dedent(expected).strip()
35 | 


--------------------------------------------------------------------------------
/tests/schema/test_lazy_types/test_lazy_enums.py:
--------------------------------------------------------------------------------
 1 | import enum
 2 | import textwrap
 3 | from typing import TYPE_CHECKING
 4 | 
 5 | import pytest
 6 | 
 7 | import strawberry
 8 | from strawberry.printer import print_schema
 9 | 
10 | if TYPE_CHECKING:
11 |     import tests
12 | 
13 | 
14 | @strawberry.enum
15 | class LazyEnum(enum.Enum):
16 |     BREAD = "BREAD"
17 | 
18 | 
19 | def test_lazy_enum():
20 |     with pytest.deprecated_call():
21 | 
22 |         @strawberry.type
23 |         class Query:
24 |             a: strawberry.LazyType[
25 |                 "LazyEnum", "tests.schema.test_lazy_types.test_lazy_enums"
26 |             ]
27 | 
28 |     expected = """
29 |     enum LazyEnum {
30 |       BREAD
31 |     }
32 | 
33 |     type Query {
34 |       a: LazyEnum!
35 |     }
36 |     """
37 | 
38 |     schema = strawberry.Schema(Query)
39 | 
40 |     assert print_schema(schema) == textwrap.dedent(expected).strip()
41 | 


--------------------------------------------------------------------------------
/tests/schema/test_lazy_types/type_a.py:
--------------------------------------------------------------------------------
 1 | from typing import TYPE_CHECKING, Optional
 2 | 
 3 | import strawberry
 4 | 
 5 | if TYPE_CHECKING:
 6 |     import tests.schema.test_lazy_types
 7 | 
 8 |     from .type_b import TypeB
 9 | 
10 | 
11 | @strawberry.type
12 | class TypeA:
13 |     list_of_b: Optional[
14 |         list[strawberry.LazyType["TypeB", "tests.schema.test_lazy_types.type_b"]]
15 |     ] = None
16 | 
17 |     @strawberry.field
18 |     def type_b(self) -> strawberry.LazyType["TypeB", ".type_b"]:  # noqa: F722
19 |         from .type_b import TypeB
20 | 
21 |         return TypeB()
22 | 


--------------------------------------------------------------------------------
/tests/schema/test_lazy_types/type_b.py:
--------------------------------------------------------------------------------
 1 | from typing import TYPE_CHECKING
 2 | 
 3 | import strawberry
 4 | 
 5 | if TYPE_CHECKING:
 6 |     import tests
 7 | 
 8 |     from .type_a import TypeA
 9 | 
10 | 
11 | @strawberry.type
12 | class TypeB:
13 |     @strawberry.field()
14 |     def type_a(
15 |         self,
16 |     ) -> strawberry.LazyType["TypeA", "tests.schema.test_lazy_types.type_a"]:
17 |         from .type_a import TypeA
18 | 
19 |         return TypeA()
20 | 


--------------------------------------------------------------------------------
/tests/schema/test_unresolved_fields.py:
--------------------------------------------------------------------------------
 1 | import pytest
 2 | 
 3 | import strawberry
 4 | from strawberry.exceptions.unresolved_field_type import UnresolvedFieldTypeError
 5 | 
 6 | 
 7 | @pytest.mark.raises_strawberry_exception(
 8 |     UnresolvedFieldTypeError,
 9 |     match=(
10 |         "Could not resolve the type of 'user'. Check that "
11 |         "the class is accessible from the global module scope."
12 |     ),
13 | )
14 | def test_unresolved_field_fails():
15 |     @strawberry.type
16 |     class Query:
17 |         user: "User"  # type: ignore  # noqa: F821
18 | 
19 |     strawberry.Schema(query=Query)
20 | 
21 | 
22 | @pytest.mark.raises_strawberry_exception(
23 |     UnresolvedFieldTypeError,
24 |     match=(
25 |         "Could not resolve the type of 'user'. Check that "
26 |         "the class is accessible from the global module scope."
27 |     ),
28 | )
29 | def test_unresolved_field_with_resolver_fails():
30 |     @strawberry.type
31 |     class Query:
32 |         @strawberry.field
33 |         def user(self) -> "User":  # type: ignore  # noqa: F821
34 |             ...
35 | 
36 |     strawberry.Schema(query=Query)
37 | 


--------------------------------------------------------------------------------
/tests/schema/types/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/tests/schema/types/__init__.py


--------------------------------------------------------------------------------
/tests/schema_codegen/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/tests/schema_codegen/__init__.py


--------------------------------------------------------------------------------
/tests/schema_codegen/test_order.py:
--------------------------------------------------------------------------------
 1 | import textwrap
 2 | 
 3 | from strawberry.schema_codegen import codegen
 4 | 
 5 | 
 6 | def test_generates_used_interface_before():
 7 |     schema = """
 8 |     type Human implements Being {
 9 |         id: ID!
10 |         name: String!
11 |         friends: [Human]
12 |     }
13 | 
14 |     type Cat implements Being {
15 |         id: ID!
16 |         name: String!
17 |         livesLeft: Int
18 |     }
19 | 
20 |     interface Being {
21 |         id: ID!
22 |         name: String!
23 |     }
24 |     """
25 | 
26 |     expected = textwrap.dedent(
27 |         """
28 |         import strawberry
29 | 
30 |         @strawberry.interface
31 |         class Being:
32 |             id: strawberry.ID
33 |             name: str
34 | 
35 |         @strawberry.type
36 |         class Human(Being):
37 |             id: strawberry.ID
38 |             name: str
39 |             friends: list[Human | None] | None
40 | 
41 |         @strawberry.type
42 |         class Cat(Being):
43 |             id: strawberry.ID
44 |             name: str
45 |             lives_left: int | None
46 |         """
47 |     ).strip()
48 | 
49 |     assert codegen(schema).strip() == expected
50 | 


--------------------------------------------------------------------------------
/tests/schema_codegen/test_union.py:
--------------------------------------------------------------------------------
 1 | import textwrap
 2 | 
 3 | from strawberry.schema_codegen import codegen
 4 | 
 5 | 
 6 | def test_union():
 7 |     schema = """
 8 |     union User = Admin | Client
 9 | 
10 |     type Admin {
11 |         name: String!
12 |     }
13 | 
14 |     type Client {
15 |         name: String!
16 |     }
17 |     """
18 | 
19 |     expected = textwrap.dedent(
20 |         """
21 |         import strawberry
22 |         from typing import Annotated
23 | 
24 |         User = Annotated[Admin | Client, strawberry.union(name="User")]
25 | 
26 |         @strawberry.type
27 |         class Admin:
28 |             name: str
29 | 
30 |         @strawberry.type
31 |         class Client:
32 |             name: str
33 |         """
34 |     ).strip()
35 | 
36 |     assert codegen(schema).strip() == expected
37 | 


--------------------------------------------------------------------------------
/tests/test/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/tests/test/__init__.py


--------------------------------------------------------------------------------
/tests/test_deprecations.py:
--------------------------------------------------------------------------------
 1 | import pytest
 2 | 
 3 | import strawberry
 4 | from strawberry.utils.deprecations import DEPRECATION_MESSAGES
 5 | 
 6 | 
 7 | @strawberry.type
 8 | class A:
 9 |     a: int
10 | 
11 | 
12 | def test_type_definition_is_aliased():
13 |     with pytest.warns(
14 |         match="_type_definition is deprecated, use __strawberry_definition__ instead"
15 |     ):
16 |         assert A.__strawberry_definition__ is A._type_definition
17 | 
18 | 
19 | def test_get_warns():
20 |     with pytest.warns(match=DEPRECATION_MESSAGES._TYPE_DEFINITION):
21 |         assert A._type_definition.fields[0]
22 | 
23 | 
24 | def test_can_import_type_definition():
25 |     from strawberry.types.base import TypeDefinition
26 | 
27 |     assert TypeDefinition
28 | 


--------------------------------------------------------------------------------
/tests/test_info.py:
--------------------------------------------------------------------------------
 1 | from typing import Any
 2 | 
 3 | import pytest
 4 | 
 5 | import strawberry
 6 | 
 7 | 
 8 | def test_can_use_info_with_two_arguments():
 9 |     CustomInfo = strawberry.Info[int, str]
10 | 
11 |     assert CustomInfo.__args__ == (int, str)
12 | 
13 | 
14 | def test_can_use_info_with_one_argument():
15 |     CustomInfo = strawberry.Info[int]
16 | 
17 |     assert CustomInfo.__args__ == (int, Any)
18 | 
19 | 
20 | def test_cannot_use_info_with_more_than_two_arguments():
21 |     with pytest.raises(
22 |         TypeError,
23 |         match="Too many (arguments|parameters) for <class '.*.Info'>; actual 3, expected 2",
24 |     ):
25 |         strawberry.Info[int, str, int]  # type: ignore
26 | 


--------------------------------------------------------------------------------
/tests/test_inspect.py:
--------------------------------------------------------------------------------
 1 | from strawberry.utils.inspect import in_async_context
 2 | 
 3 | 
 4 | def test_in_async_context_sync():
 5 |     assert not in_async_context()
 6 | 
 7 | 
 8 | async def test_in_async_context_async():
 9 |     assert in_async_context()
10 | 
11 | 
12 | async def test_in_async_context_async_with_inner_sync_function():
13 |     def inner_sync_function():
14 |         assert in_async_context()
15 | 
16 |     inner_sync_function()
17 | 


--------------------------------------------------------------------------------
/tests/test_printer/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/tests/test_printer/__init__.py


--------------------------------------------------------------------------------
/tests/test_printer/test_one_of.py:
--------------------------------------------------------------------------------
 1 | from __future__ import annotations
 2 | 
 3 | import textwrap
 4 | 
 5 | import strawberry
 6 | from strawberry.schema_directives import OneOf
 7 | 
 8 | 
 9 | @strawberry.input(directives=[OneOf()])
10 | class ExampleInputTagged:
11 |     a: str | None
12 |     b: int | None
13 | 
14 | 
15 | @strawberry.type
16 | class ExampleResult:
17 |     a: str | None
18 |     b: int | None
19 | 
20 | 
21 | @strawberry.type
22 | class Query:
23 |     @strawberry.field
24 |     def test(self, input: ExampleInputTagged) -> ExampleResult:  # pragma: no cover
25 |         return input  # type: ignore
26 | 
27 | 
28 | schema = strawberry.Schema(query=Query)
29 | 
30 | 
31 | def test_prints_one_of_directive():
32 |     expected_type = """
33 |     directive @oneOf on INPUT_OBJECT
34 | 
35 |     input ExampleInputTagged @oneOf {
36 |       a: String
37 |       b: Int
38 |     }
39 | 
40 |     type ExampleResult {
41 |       a: String
42 |       b: Int
43 |     }
44 | 
45 |     type Query {
46 |       test(input: ExampleInputTagged!): ExampleResult!
47 |     }
48 |     """
49 | 
50 |     assert str(schema) == textwrap.dedent(expected_type).strip()
51 | 


--------------------------------------------------------------------------------
/tests/test_repr.py:
--------------------------------------------------------------------------------
 1 | from enum import Enum
 2 | 
 3 | import strawberry
 4 | 
 5 | 
 6 | def test_repr_type():
 7 |     @strawberry.type
 8 |     class MyType:
 9 |         s: str
10 |         i: int
11 |         b: bool
12 |         f: float
13 |         id: strawberry.ID
14 | 
15 |     assert (
16 |         repr(MyType(s="a", i=1, b=True, f=3.2, id="123"))
17 |         == "test_repr_type.<locals>.MyType(s='a', i=1, b=True, f=3.2, id='123')"
18 |     )
19 | 
20 | 
21 | def test_repr_enum():
22 |     @strawberry.enum()
23 |     class Test(Enum):
24 |         A = 1
25 |         B = 2
26 |         C = 3
27 | 
28 |     assert repr(Test(1)) == "<Test.A: 1>"
29 | 


--------------------------------------------------------------------------------
/tests/tools/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/tests/tools/__init__.py


--------------------------------------------------------------------------------
/tests/typecheckers/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/tests/typecheckers/__init__.py


--------------------------------------------------------------------------------
/tests/typecheckers/utils/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/tests/typecheckers/utils/__init__.py


--------------------------------------------------------------------------------
/tests/typecheckers/utils/marks.py:
--------------------------------------------------------------------------------
 1 | import shutil
 2 | import sys
 3 | 
 4 | import pytest
 5 | 
 6 | 
 7 | def pyright_exist() -> bool:
 8 |     return shutil.which("pyright") is not None
 9 | 
10 | 
11 | def mypy_exists() -> bool:
12 |     return shutil.which("mypy") is not None
13 | 
14 | 
15 | skip_on_windows = pytest.mark.skipif(
16 |     sys.platform == "win32",
17 |     reason="Do not run pyright on windows due to path issues",
18 | )
19 | 
20 | requires_pyright = pytest.mark.skipif(
21 |     not pyright_exist(),
22 |     reason="These tests require pyright",
23 | )
24 | 
25 | requires_mypy = pytest.mark.skipif(
26 |     not mypy_exists(),
27 |     reason="These tests require mypy",
28 | )
29 | 


--------------------------------------------------------------------------------
/tests/typecheckers/utils/result.py:
--------------------------------------------------------------------------------
 1 | from dataclasses import dataclass
 2 | from typing import Literal
 3 | 
 4 | ResultType = Literal[
 5 |     "error",
 6 |     "information",
 7 |     "note",
 8 | ]
 9 | 
10 | 
11 | @dataclass
12 | class Result:
13 |     type: ResultType
14 |     message: str
15 |     line: int
16 |     column: int
17 | 


--------------------------------------------------------------------------------
/tests/typecheckers/utils/typecheck.py:
--------------------------------------------------------------------------------
 1 | from __future__ import annotations
 2 | 
 3 | import concurrent.futures
 4 | from dataclasses import dataclass
 5 | 
 6 | from .mypy import run_mypy
 7 | from .pyright import run_pyright
 8 | from .result import Result
 9 | 
10 | 
11 | @dataclass
12 | class TypecheckResult:
13 |     pyright: list[Result]
14 |     mypy: list[Result]
15 | 
16 | 
17 | def typecheck(code: str, strict: bool = True) -> TypecheckResult:
18 |     with concurrent.futures.ThreadPoolExecutor() as executor:
19 |         pyright_future = executor.submit(run_pyright, code, strict=strict)
20 |         mypy_future = executor.submit(run_mypy, code, strict=strict)
21 | 
22 |         pyright_results = pyright_future.result()
23 |         mypy_results = mypy_future.result()
24 | 
25 |     return TypecheckResult(pyright=pyright_results, mypy=mypy_results)
26 | 


--------------------------------------------------------------------------------
/tests/types/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/tests/types/__init__.py


--------------------------------------------------------------------------------
/tests/types/cross_module_resolvers/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/tests/types/cross_module_resolvers/__init__.py


--------------------------------------------------------------------------------
/tests/types/cross_module_resolvers/a_mod.py:
--------------------------------------------------------------------------------
 1 | import strawberry
 2 | 
 3 | 
 4 | def a_resolver() -> list["AObject"]:
 5 |     return []
 6 | 
 7 | 
 8 | @strawberry.type
 9 | class ABase:
10 |     a_name: str
11 | 
12 | 
13 | @strawberry.type
14 | class AObject(ABase):
15 |     a_age: int
16 | 
17 |     @strawberry.field
18 |     def a_is_of_full_age(self) -> bool:
19 |         return self.a_age >= 18
20 | 


--------------------------------------------------------------------------------
/tests/types/cross_module_resolvers/b_mod.py:
--------------------------------------------------------------------------------
 1 | import strawberry
 2 | 
 3 | 
 4 | def b_resolver() -> list["BObject"]:
 5 |     return []
 6 | 
 7 | 
 8 | @strawberry.type
 9 | class BBase:
10 |     b_name: str = strawberry.field()
11 | 
12 | 
13 | @strawberry.type
14 | class BObject(BBase):
15 |     b_age: int = strawberry.field()
16 | 
17 |     @strawberry.field
18 |     def b_is_of_full_age(self) -> bool:
19 |         return self.b_age >= 18
20 | 


--------------------------------------------------------------------------------
/tests/types/cross_module_resolvers/x_mod.py:
--------------------------------------------------------------------------------
1 | def typeless_resolver() -> list:  # pragma: no cover
2 |     return []
3 | 


--------------------------------------------------------------------------------
/tests/types/resolving/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/tests/types/resolving/__init__.py


--------------------------------------------------------------------------------
/tests/types/resolving/test_enums.py:
--------------------------------------------------------------------------------
 1 | from enum import Enum
 2 | 
 3 | import strawberry
 4 | from strawberry.annotation import StrawberryAnnotation
 5 | 
 6 | 
 7 | def test_basic():
 8 |     @strawberry.enum
 9 |     class NumaNuma(Enum):
10 |         MA = "ma"
11 |         I = "i"  # noqa: E741
12 |         A = "a"
13 |         HI = "hi"
14 | 
15 |     annotation = StrawberryAnnotation(NumaNuma)
16 |     resolved = annotation.resolve()
17 | 
18 |     # TODO: Remove reference to .enum_definition with StrawberryEnum
19 |     assert resolved is NumaNuma._enum_definition
20 | 


--------------------------------------------------------------------------------
/tests/types/resolving/test_forward_references.py:
--------------------------------------------------------------------------------
 1 | import pytest
 2 | 
 3 | import strawberry
 4 | from strawberry.annotation import StrawberryAnnotation
 5 | 
 6 | 
 7 | def test_forward_reference():
 8 |     global ForwardClass
 9 | 
10 |     annotation = StrawberryAnnotation("ForwardClass", namespace=globals())
11 | 
12 |     @strawberry.type
13 |     class ForwardClass:
14 |         backward: bool
15 | 
16 |     resolved = annotation.resolve()
17 | 
18 |     assert resolved is ForwardClass
19 | 
20 |     del ForwardClass
21 | 
22 | 
23 | @pytest.mark.xfail(reason="Combining locals() and globals() strangely makes this fail")
24 | def test_forward_reference_locals_and_globals():
25 |     global BackwardClass
26 | 
27 |     namespace = {**locals(), **globals()}
28 | 
29 |     annotation = StrawberryAnnotation("BackwardClass", namespace=namespace)
30 | 
31 |     @strawberry.type
32 |     class BackwardClass:
33 |         backward: bool
34 | 
35 |     resolved = annotation.resolve()
36 | 
37 |     assert resolved is BackwardClass
38 | 
39 |     del BackwardClass
40 | 


--------------------------------------------------------------------------------
/tests/types/resolving/test_literals.py:
--------------------------------------------------------------------------------
 1 | from typing import Optional, Union
 2 | 
 3 | from strawberry.annotation import StrawberryAnnotation
 4 | 
 5 | 
 6 | def test_bool():
 7 |     annotation = StrawberryAnnotation(bool)
 8 |     resolved = annotation.resolve()
 9 | 
10 |     assert resolved is bool
11 | 
12 | 
13 | def test_float():
14 |     annotation = StrawberryAnnotation(float)
15 |     resolved = annotation.resolve()
16 | 
17 |     assert resolved is float
18 | 
19 | 
20 | def test_int():
21 |     annotation = StrawberryAnnotation(int)
22 |     resolved = annotation.resolve()
23 | 
24 |     assert resolved is int
25 | 
26 | 
27 | def test_str():
28 |     annotation = StrawberryAnnotation(str)
29 |     resolved = annotation.resolve()
30 | 
31 |     assert resolved is str
32 | 
33 | 
34 | def test_none():
35 |     annotation = StrawberryAnnotation(None)
36 |     annotation.resolve()
37 | 
38 |     annotation = StrawberryAnnotation(type(None))
39 |     annotation.resolve()
40 | 
41 |     annotation = StrawberryAnnotation(Optional[int])
42 |     annotation.resolve()
43 | 
44 |     annotation = StrawberryAnnotation(Union[None, int])
45 |     annotation.resolve()
46 | 


--------------------------------------------------------------------------------
/tests/types/test_cast.py:
--------------------------------------------------------------------------------
 1 | import strawberry
 2 | from strawberry.types.cast import get_strawberry_type_cast
 3 | 
 4 | 
 5 | def test_cast():
 6 |     @strawberry.type
 7 |     class SomeType: ...
 8 | 
 9 |     class OtherType: ...
10 | 
11 |     obj = OtherType
12 |     assert get_strawberry_type_cast(obj) is None
13 | 
14 |     cast_obj = strawberry.cast(SomeType, obj)
15 |     assert cast_obj is obj
16 |     assert get_strawberry_type_cast(cast_obj) is SomeType
17 | 
18 | 
19 | def test_cast_none_obj():
20 |     @strawberry.type
21 |     class SomeType: ...
22 | 
23 |     obj = None
24 |     assert get_strawberry_type_cast(obj) is None
25 | 
26 |     cast_obj = strawberry.cast(SomeType, obj)
27 |     assert cast_obj is None
28 |     assert get_strawberry_type_cast(obj) is None
29 | 


--------------------------------------------------------------------------------
/tests/types/test_deferred_annotations.py:
--------------------------------------------------------------------------------
 1 | from sys import modules
 2 | from types import ModuleType
 3 | 
 4 | import strawberry
 5 | 
 6 | deferred_module_source = """
 7 | from __future__ import annotations
 8 | 
 9 | import strawberry
10 | 
11 | @strawberry.type
12 | class User:
13 |     username: str
14 |     email: str
15 | 
16 | @strawberry.interface
17 | class UserContent:
18 |     created_by: User
19 | """
20 | 
21 | 
22 | def test_deferred_other_module():
23 |     mod = ModuleType("tests.deferred_module")
24 |     modules[mod.__name__] = mod
25 | 
26 |     try:
27 |         exec(deferred_module_source, mod.__dict__)  # noqa: S102
28 | 
29 |         @strawberry.type
30 |         class Post(mod.UserContent):
31 |             title: str
32 |             body: str
33 | 
34 |         definition = Post.__strawberry_definition__
35 |         assert definition.fields[0].type == mod.User
36 |     finally:
37 |         del modules[mod.__name__]
38 | 


--------------------------------------------------------------------------------
/tests/utils/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/tests/utils/__init__.py


--------------------------------------------------------------------------------
/tests/utils/test_get_first_operation.py:
--------------------------------------------------------------------------------
 1 | from graphql import OperationType, parse
 2 | 
 3 | from strawberry.utils.operation import get_first_operation
 4 | 
 5 | 
 6 | def test_document_without_operation_definition_nodes():
 7 |     document = parse(
 8 |         """
 9 |         fragment Test on Query {
10 |             hello
11 |         }
12 |         """
13 |     )
14 |     assert get_first_operation(document) is None
15 | 
16 | 
17 | def test_single_operation_definition_node():
18 |     document = parse(
19 |         """
20 |         query Operation1 {
21 |             hello
22 |         }
23 |         """
24 |     )
25 |     node = get_first_operation(document)
26 |     assert node is not None
27 |     assert node.operation == OperationType.QUERY
28 | 
29 | 
30 | def test_multiple_operation_definition_nodes():
31 |     document = parse(
32 |         """
33 |         mutation Operation1 {
34 |             hello
35 |         }
36 |         query Operation2 {
37 |             hello
38 |         }
39 |         """
40 |     )
41 |     node = get_first_operation(document)
42 |     assert node is not None
43 |     assert node.operation == OperationType.MUTATION
44 | 


--------------------------------------------------------------------------------
/tests/utils/test_logging.py:
--------------------------------------------------------------------------------
 1 | import logging
 2 | 
 3 | from graphql.error import GraphQLError
 4 | 
 5 | from strawberry.utils.logging import StrawberryLogger
 6 | 
 7 | 
 8 | def test_strawberry_logger_error(caplog):
 9 |     caplog.set_level(logging.ERROR, logger="strawberry.execution")
10 | 
11 |     exc = GraphQLError("test exception")
12 |     StrawberryLogger.error(exc)
13 | 
14 |     assert caplog.record_tuples == [
15 |         ("strawberry.execution", logging.ERROR, "test exception")
16 |     ]
17 | 


--------------------------------------------------------------------------------
/tests/utils/test_pretty_print.py:
--------------------------------------------------------------------------------
 1 | from decimal import Decimal
 2 | 
 3 | from strawberry.utils.debug import pretty_print_graphql_operation
 4 | 
 5 | 
 6 | def test_pretty_print(mocker):
 7 |     mock = mocker.patch("builtins.print")
 8 | 
 9 |     pretty_print_graphql_operation("Example", "{ query }", variables={})
10 | 
11 |     mock.assert_called_with("{ \x1b[38;5;125mquery\x1b[39m }\n")
12 | 
13 | 
14 | def test_pretty_print_variables(mocker):
15 |     mock = mocker.patch("builtins.print")
16 | 
17 |     pretty_print_graphql_operation("Example", "{ query }", variables={"example": 1})
18 | 
19 |     mock.assert_called_with(
20 |         "{\n\x1b[38;5;250m    "
21 |         '\x1b[39m\x1b[38;5;28;01m"example"\x1b[39;00m:\x1b[38;5;250m '
22 |         "\x1b[39m\x1b[38;5;241m1\x1b[39m\n}\n"
23 |     )
24 | 
25 | 
26 | def test_pretty_print_variables_object(mocker):
27 |     mock = mocker.patch("builtins.print")
28 | 
29 |     pretty_print_graphql_operation(
30 |         "Example", "{ query }", variables={"example": Decimal(1)}
31 |     )
32 | 
33 |     mock.assert_called_with(
34 |         "{\n\x1b[38;5;250m    "
35 |         '\x1b[39m\x1b[38;5;28;01m"example"\x1b[39;00m:\x1b[38;5;250m '
36 |         "\x1b[39m\x1b[38;5;124m\"Decimal('1')\"\x1b[39m\n}\n"
37 |     )
38 | 


--------------------------------------------------------------------------------
/tests/views/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/tests/views/__init__.py


--------------------------------------------------------------------------------
/tests/websockets/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strawberry-graphql/strawberry/dc4388067ab5fb3775b9c869d2018b4ee10c7757/tests/websockets/__init__.py


--------------------------------------------------------------------------------