diff --git a/RELEASE.md b/RELEASE.md
new file mode 100644
index 0000000000..7aef45f4d0
--- /dev/null
+++ b/RELEASE.md
@@ -0,0 +1,8 @@
+Release type: minor
+
+After a year-long deprecation period, the `SentryTracingExtension` has been
+removed in favor of the official Sentry SDK integration.
+
+To migrate, remove the `SentryTracingExtension` from your Strawberry schema and
+then follow the
+[official Sentry SDK integration guide](https://docs.sentry.io/platforms/python/integrations/strawberry/).
diff --git a/TWEET.md b/TWEET.md
new file mode 100644
index 0000000000..284e1c2ba1
--- /dev/null
+++ b/TWEET.md
@@ -0,0 +1,8 @@
+After a year-long deprecation period, the SentryTracingExtension has
+been removed in favor of the official Sentry SDK integration.
+
+Checkout out our migration guides if you have not migrated yet.
+
+Thanks to $contributor for the PR 👏
+
+$release_url
diff --git a/docs/breaking-changes.md b/docs/breaking-changes.md
index 3df11e2b23..c87fabd804 100644
--- a/docs/breaking-changes.md
+++ b/docs/breaking-changes.md
@@ -4,6 +4,7 @@ title: List of breaking changes and deprecations
# List of breaking changes and deprecations
+- [Version 0.249.0 - 18 November 2024](./breaking-changes/0.249.0.md)
- [Version 0.243.0 - 25 September 2024](./breaking-changes/0.243.0.md)
- [Version 0.240.0 - 10 September 2024](./breaking-changes/0.240.0.md)
- [Version 0.236.0 - 17 July 2024](./breaking-changes/0.236.0.md)
diff --git a/docs/breaking-changes/0.249.0.md b/docs/breaking-changes/0.249.0.md
new file mode 100644
index 0000000000..7d0a8f8951
--- /dev/null
+++ b/docs/breaking-changes/0.249.0.md
@@ -0,0 +1,13 @@
+---
+title: 0.249.0 Breaking Changes
+slug: breaking-changes/0.249.0
+---
+
+# v0.249.0 Breaking Changes
+
+After a year-long deprecation period, the `SentryTracingExtension` has been
+removed in favor of the official Sentry SDK integration.
+
+To migrate, remove the `SentryTracingExtension` from your Strawberry schema and
+then follow the
+[official Sentry SDK integration guide](https://docs.sentry.io/platforms/python/integrations/strawberry/).
diff --git a/docs/extensions/sentry-tracing.md b/docs/extensions/sentry-tracing.md
index 52b70d3582..e62359783d 100644
--- a/docs/extensions/sentry-tracing.md
+++ b/docs/extensions/sentry-tracing.md
@@ -4,68 +4,16 @@ summary: Add Sentry tracing to your GraphQL server.
tags: tracing
---
-
-
-As of Sentry 1.32.0, Strawberry is now supported by default. This extension is
-no longer necessary. For more details, please refer to the
-[release notes](https://github.com/getsentry/sentry-python/releases/tag/1.32.0).
-
-Below is the revised usage example:
-
-```python
-import sentry_sdk
-from sentry_sdk.integrations.strawberry import StrawberryIntegration
-
-sentry_sdk.init(
- dsn="___PUBLIC_DSN___",
- integrations=[
- # make sure to set async_execution to False if you're executing
- # GraphQL queries synchronously
- StrawberryIntegration(async_execution=True),
- ],
- traces_sample_rate=1.0,
-)
-```
-
-
-
# `SentryTracingExtension`
-This extension adds support for tracing with Sentry.
-
-## Usage example:
-
-```python
-import strawberry
-from strawberry.extensions.tracing import SentryTracingExtension
-
-schema = strawberry.Schema(
- Query,
- extensions=[
- SentryTracingExtension,
- ],
-)
-```
-
-
-
-If you are not running in an Async context then you'll need to use the sync
-version:
-
-```python
-import strawberry
-from strawberry.extensions.tracing import SentryTracingExtensionSync
-
-schema = strawberry.Schema(
- Query,
- extensions=[
- SentryTracingExtensionSync,
- ],
-)
-```
+
-
+As of Sentry 1.32.0, Strawberry is officially supported by the Sentry SDK.
+Therefore, Strawberry's `SentryTracingExtension` has been deprecated in version
+0.210.0 and finally removed with Strawberry 0.249.0 in favor of the official
+Sentry SDK integration.
-## API reference:
+For more details, please refer to the
+[documentation for the official Sentry Strawberry integration](https://docs.sentry.io/platforms/python/integrations/strawberry/).
-_No arguments_
+
diff --git a/poetry.lock b/poetry.lock
index 898f856ef7..b02f9c6899 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -3474,53 +3474,6 @@ files = [
cryptography = ">=2.0"
jeepney = ">=0.6"
-[[package]]
-name = "sentry-sdk"
-version = "1.45.1"
-description = "Python client for Sentry (https://sentry.io)"
-optional = false
-python-versions = "*"
-files = [
- {file = "sentry_sdk-1.45.1-py2.py3-none-any.whl", hash = "sha256:608887855ccfe39032bfd03936e3a1c4f4fc99b3a4ac49ced54a4220de61c9c1"},
- {file = "sentry_sdk-1.45.1.tar.gz", hash = "sha256:a16c997c0f4e3df63c0fc5e4207ccb1ab37900433e0f72fef88315d317829a26"},
-]
-
-[package.dependencies]
-certifi = "*"
-urllib3 = {version = ">=1.26.11", markers = "python_version >= \"3.6\""}
-
-[package.extras]
-aiohttp = ["aiohttp (>=3.5)"]
-arq = ["arq (>=0.23)"]
-asyncpg = ["asyncpg (>=0.23)"]
-beam = ["apache-beam (>=2.12)"]
-bottle = ["bottle (>=0.12.13)"]
-celery = ["celery (>=3)"]
-celery-redbeat = ["celery-redbeat (>=2)"]
-chalice = ["chalice (>=1.16.0)"]
-clickhouse-driver = ["clickhouse-driver (>=0.2.0)"]
-django = ["django (>=1.8)"]
-falcon = ["falcon (>=1.4)"]
-fastapi = ["fastapi (>=0.79.0)"]
-flask = ["blinker (>=1.1)", "flask (>=0.11)", "markupsafe"]
-grpcio = ["grpcio (>=1.21.1)"]
-httpx = ["httpx (>=0.16.0)"]
-huey = ["huey (>=2)"]
-loguru = ["loguru (>=0.5)"]
-openai = ["openai (>=1.0.0)", "tiktoken (>=0.3.0)"]
-opentelemetry = ["opentelemetry-distro (>=0.35b0)"]
-opentelemetry-experimental = ["opentelemetry-distro (>=0.40b0,<1.0)", "opentelemetry-instrumentation-aiohttp-client (>=0.40b0,<1.0)", "opentelemetry-instrumentation-django (>=0.40b0,<1.0)", "opentelemetry-instrumentation-fastapi (>=0.40b0,<1.0)", "opentelemetry-instrumentation-flask (>=0.40b0,<1.0)", "opentelemetry-instrumentation-requests (>=0.40b0,<1.0)", "opentelemetry-instrumentation-sqlite3 (>=0.40b0,<1.0)", "opentelemetry-instrumentation-urllib (>=0.40b0,<1.0)"]
-pure-eval = ["asttokens", "executing", "pure-eval"]
-pymongo = ["pymongo (>=3.1)"]
-pyspark = ["pyspark (>=2.4.4)"]
-quart = ["blinker (>=1.1)", "quart (>=0.16.1)"]
-rq = ["rq (>=0.6)"]
-sanic = ["sanic (>=0.8)"]
-sqlalchemy = ["sqlalchemy (>=1.2)"]
-starlette = ["starlette (>=0.19.1)"]
-starlite = ["starlite (>=1.48)"]
-tornado = ["tornado (>=5)"]
-
[[package]]
name = "service-identity"
version = "24.1.0"
@@ -4595,4 +4548,4 @@ sanic = ["sanic"]
[metadata]
lock-version = "2.0"
python-versions = "^3.8"
-content-hash = "ed925030eb8c2f2baa836c6f64990e2f4eabfb2b1c177294623671d1e6760081"
+content-hash = "5b4688f203c3b744c228b13f33c6ed30515e00bf259a4c5ddd83d270293cda08"
diff --git a/pyproject.toml b/pyproject.toml
index 44b70dc1ed..06ef141d92 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -85,7 +85,6 @@ pytest-xdist = {extras = ["psutil"], version = "^3.1.0"}
python-multipart = ">=0.0.7"
rich = {version = ">=12.5.1", optional = false}
sanic-testing = ">=22.9,<24.0"
-sentry-sdk = "^1.39.2"
typer = {version = ">=0.7.0", optional = false}
types-aiofiles = ">=22.1"
types-certifi = "^2021.10.8"
diff --git a/strawberry/extensions/tracing/__init__.py b/strawberry/extensions/tracing/__init__.py
index 772b18dbf0..593ed0b2ea 100644
--- a/strawberry/extensions/tracing/__init__.py
+++ b/strawberry/extensions/tracing/__init__.py
@@ -8,7 +8,6 @@
OpenTelemetryExtension,
OpenTelemetryExtensionSync,
)
- from .sentry import SentryTracingExtension, SentryTracingExtensionSync
__all__ = [
"ApolloTracingExtension",
@@ -17,8 +16,6 @@
"DatadogTracingExtensionSync",
"OpenTelemetryExtension",
"OpenTelemetryExtensionSync",
- "SentryTracingExtension",
- "SentryTracingExtensionSync",
]
@@ -32,7 +29,4 @@ def __getattr__(name: str) -> Any:
if name in {"OpenTelemetryExtension", "OpenTelemetryExtensionSync"}:
return getattr(importlib.import_module(".opentelemetry", __name__), name)
- if name in {"SentryTracingExtension", "SentryTracingExtensionSync"}:
- return getattr(importlib.import_module(".sentry", __name__), name)
-
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
diff --git a/strawberry/extensions/tracing/sentry.py b/strawberry/extensions/tracing/sentry.py
deleted file mode 100644
index 7a0c6188b4..0000000000
--- a/strawberry/extensions/tracing/sentry.py
+++ /dev/null
@@ -1,161 +0,0 @@
-from __future__ import annotations
-
-import hashlib
-import warnings
-from functools import cached_property
-from inspect import isawaitable
-from typing import TYPE_CHECKING, Any, Callable, Generator, Optional
-
-from sentry_sdk import configure_scope, start_span
-
-from strawberry.extensions import SchemaExtension
-from strawberry.extensions.tracing.utils import should_skip_tracing
-
-if TYPE_CHECKING:
- from graphql import GraphQLResolveInfo
-
- from strawberry.types.execution import ExecutionContext
-
-
-class SentryTracingExtension(SchemaExtension):
- def __init__(
- self,
- *,
- execution_context: Optional[ExecutionContext] = None,
- ) -> None:
- warnings.warn(
- "The Sentry tracing extension is deprecated, please update to sentry-sdk>=1.32.0",
- DeprecationWarning,
- stacklevel=2,
- )
-
- if execution_context:
- self.execution_context = execution_context
-
- @cached_property
- def _resource_name(self) -> str:
- assert self.execution_context.query
-
- query_hash = self.hash_query(self.execution_context.query)
-
- if self.execution_context.operation_name:
- return f"{self.execution_context.operation_name}:{query_hash}"
-
- return query_hash
-
- def hash_query(self, query: str) -> str:
- return hashlib.md5(query.encode("utf-8")).hexdigest()
-
- def on_operation(self) -> Generator[None, None, None]:
- self._operation_name = self.execution_context.operation_name
- name = f"{self._operation_name}" if self._operation_name else "Anonymous Query"
-
- with configure_scope() as scope:
- if scope.span:
- self.gql_span = scope.span.start_child(
- op="gql",
- description=name,
- )
- else:
- self.gql_span = start_span(
- op="gql",
- )
-
- operation_type = "query"
-
- assert self.execution_context.query
-
- if self.execution_context.query.strip().startswith("mutation"):
- operation_type = "mutation"
- if self.execution_context.query.strip().startswith("subscription"):
- operation_type = "subscription"
-
- self.gql_span.set_tag("graphql.operation_type", operation_type)
- self.gql_span.set_tag("graphql.resource_name", self._resource_name)
- self.gql_span.set_data("graphql.query", self.execution_context.query)
-
- yield
-
- self.gql_span.finish()
-
- def on_validate(self) -> Generator[None, None, None]:
- self.validation_span = self.gql_span.start_child(
- op="validation", description="Validation"
- )
-
- yield
-
- self.validation_span.finish()
-
- def on_parse(self) -> Generator[None, None, None]:
- self.parsing_span = self.gql_span.start_child(
- op="parsing", description="Parsing"
- )
-
- yield
-
- self.parsing_span.finish()
-
- def should_skip_tracing(self, _next: Callable, info: GraphQLResolveInfo) -> bool:
- return should_skip_tracing(_next, info)
-
- async def resolve(
- self,
- _next: Callable,
- root: Any,
- info: GraphQLResolveInfo,
- *args: str,
- **kwargs: Any,
- ) -> Any:
- if self.should_skip_tracing(_next, info):
- result = _next(root, info, *args, **kwargs)
-
- if isawaitable(result): # pragma: no cover
- result = await result
-
- return result
-
- field_path = f"{info.parent_type}.{info.field_name}"
-
- with self.gql_span.start_child(
- op="resolve", description=f"Resolving: {field_path}"
- ) as span:
- span.set_tag("graphql.field_name", info.field_name)
- span.set_tag("graphql.parent_type", info.parent_type.name)
- span.set_tag("graphql.field_path", field_path)
- span.set_tag("graphql.path", ".".join(map(str, info.path.as_list())))
-
- result = _next(root, info, *args, **kwargs)
-
- if isawaitable(result):
- result = await result
-
- return result
-
-
-class SentryTracingExtensionSync(SentryTracingExtension):
- def resolve(
- self,
- _next: Callable,
- root: Any,
- info: GraphQLResolveInfo,
- *args: str,
- **kwargs: Any,
- ) -> Any:
- if self.should_skip_tracing(_next, info):
- return _next(root, info, *args, **kwargs)
-
- field_path = f"{info.parent_type}.{info.field_name}"
-
- with self.gql_span.start_child(
- op="resolve", description=f"Resolving: {field_path}"
- ) as span:
- span.set_tag("graphql.field_name", info.field_name)
- span.set_tag("graphql.parent_type", info.parent_type.name)
- span.set_tag("graphql.field_path", field_path)
- span.set_tag("graphql.path", ".".join(map(str, info.path.as_list())))
-
- return _next(root, info, *args, **kwargs)
-
-
-__all__ = ["SentryTracingExtension", "SentryTracingExtensionSync"]
diff --git a/tests/schema/extensions/test_sentry.py b/tests/schema/extensions/test_sentry.py
deleted file mode 100644
index 696818999d..0000000000
--- a/tests/schema/extensions/test_sentry.py
+++ /dev/null
@@ -1,368 +0,0 @@
-from __future__ import annotations
-
-from typing import TYPE_CHECKING, AsyncGenerator, Tuple, Type
-from unittest.mock import MagicMock
-
-import pytest
-from pytest_mock import MockerFixture
-
-import strawberry
-
-if TYPE_CHECKING:
- from strawberry.extensions.tracing.sentry import (
- SentryTracingExtension,
- SentryTracingExtensionSync,
- )
-
-
-@pytest.fixture
-def sentry_extension(
- mocker: MockerFixture,
-) -> Tuple[Type[SentryTracingExtension], MagicMock]:
- sentry_mock = mocker.MagicMock()
-
- mocker.patch.dict("sys.modules", sentry_sdk=sentry_mock)
-
- from strawberry.extensions.tracing.sentry import SentryTracingExtension
-
- return SentryTracingExtension, sentry_mock
-
-
-@pytest.fixture
-def sentry_extension_sync(
- mocker: MockerFixture,
-) -> Tuple[Type[SentryTracingExtension], MagicMock]:
- sentry_mock = mocker.MagicMock()
-
- mocker.patch.dict("sys.modules", sentry_sdk=sentry_mock)
-
- from strawberry.extensions.tracing.sentry import SentryTracingExtensionSync
-
- return SentryTracingExtensionSync, sentry_mock
-
-
-@strawberry.type
-class Person:
- name: str = "Jack"
-
-
-@strawberry.type
-class Query:
- @strawberry.field
- def person(self) -> Person:
- return Person()
-
- @strawberry.field
- async def person_async(self) -> Person:
- return Person()
-
-
-@strawberry.type
-class Mutation:
- @strawberry.mutation
- def say_hi(self) -> str:
- return "hello"
-
-
-@strawberry.type
-class Subscription:
- @strawberry.field
- async def on_hi(self) -> AsyncGenerator[str, None]:
- yield "Hello"
-
-
-@pytest.mark.asyncio
-async def test_sentry_tracer(
- sentry_extension: Tuple[SentryTracingExtension, MagicMock], mocker: MockerFixture
-):
- extension, mock = sentry_extension
-
- schema = strawberry.Schema(
- query=Query,
- mutation=Mutation,
- extensions=[extension],
- )
-
- query = """
- query {
- personAsync {
- name
- }
- }
- """
-
- with pytest.warns(
- DeprecationWarning, match="The Sentry tracing extension is deprecated"
- ):
- await schema.execute(query)
-
- assert mock.configure_scope.mock_calls == [
- mocker.call(),
- mocker.call().__enter__(),
- mocker.call().__enter__().span.__bool__(),
- mocker.call()
- .__enter__()
- .span.start_child(op="gql", description="Anonymous Query"),
- mocker.call().__exit__(None, None, None),
- mocker.call()
- .__enter__()
- .span.start_child()
- .set_tag("graphql.operation_type", "query"),
- mocker.call()
- .__enter__()
- .span.start_child()
- .set_tag("graphql.resource_name", "63a280256ca4e8514e06cf90b30c8c3a"),
- mocker.call().__enter__().span.start_child().set_data("graphql.query", query),
- mocker.call()
- .__enter__()
- .span.start_child()
- .start_child(op="parsing", description="Parsing"),
- mocker.call().__enter__().span.start_child().start_child().finish(),
- mocker.call()
- .__enter__()
- .span.start_child()
- .start_child(op="validation", description="Validation"),
- mocker.call().__enter__().span.start_child().start_child().finish(),
- mocker.call()
- .__enter__()
- .span.start_child()
- .start_child(op="resolve", description="Resolving: Query.personAsync"),
- mocker.call().__enter__().span.start_child().start_child().__enter__(),
- mocker.call()
- .__enter__()
- .span.start_child()
- .start_child()
- .__enter__()
- .set_tag("graphql.field_name", "personAsync"),
- mocker.call()
- .__enter__()
- .span.start_child()
- .start_child()
- .__enter__()
- .set_tag("graphql.parent_type", "Query"),
- mocker.call()
- .__enter__()
- .span.start_child()
- .start_child()
- .__enter__()
- .set_tag("graphql.field_path", "Query.personAsync"),
- mocker.call()
- .__enter__()
- .span.start_child()
- .start_child()
- .__enter__()
- .set_tag("graphql.path", "personAsync"),
- mocker.call()
- .__enter__()
- .span.start_child()
- .start_child()
- .__exit__(None, None, None),
- mocker.call().__enter__().span.start_child().finish(),
- ]
-
-
-@pytest.mark.asyncio
-async def test_uses_operation_name(
- sentry_extension: Tuple[SentryTracingExtension, MagicMock],
-):
- extension, mock = sentry_extension
-
- schema = strawberry.Schema(query=Query, mutation=Mutation, extensions=[extension])
-
- query = """
- query MyExampleQuery {
- person {
- name
- }
- }
- """
-
- with pytest.warns(
- DeprecationWarning, match="The Sentry tracing extension is deprecated"
- ):
- await schema.execute(query, operation_name="MyExampleQuery")
-
- mock.configure_scope().__enter__().span.start_child.assert_any_call(
- op="gql", description="MyExampleQuery"
- )
-
-
-@pytest.mark.asyncio
-async def test_uses_operation_type(
- sentry_extension: Tuple[SentryTracingExtension, MagicMock],
-):
- extension, mock = sentry_extension
-
- schema = strawberry.Schema(query=Query, mutation=Mutation, extensions=[extension])
-
- query = """
- mutation MyMutation {
- sayHi
- }
- """
-
- with pytest.warns(
- DeprecationWarning, match="The Sentry tracing extension is deprecated"
- ):
- await schema.execute(query, operation_name="MyMutation")
-
- mock.configure_scope().__enter__().span.start_child().set_tag.assert_any_call(
- "graphql.operation_type", "mutation"
- )
-
-
-@pytest.mark.asyncio
-async def test_uses_operation_subscription(
- sentry_extension: Tuple[SentryTracingExtension, MagicMock],
-):
- extension, mock = sentry_extension
-
- schema = strawberry.Schema(query=Query, mutation=Mutation, extensions=[extension])
-
- query = """
- subscription MySubscription {
- onHi
- }
- """
-
- with pytest.warns(
- DeprecationWarning, match="The Sentry tracing extension is deprecated"
- ):
- await schema.execute(query, operation_name="MySubscription")
-
- mock.configure_scope().__enter__().span.start_child().set_tag.assert_any_call(
- "graphql.operation_type", "subscription"
- )
-
-
-def test_sentry_tracer_sync(
- sentry_extension_sync: Tuple[SentryTracingExtensionSync, MagicMock],
- mocker: MockerFixture,
-):
- extension, mock = sentry_extension_sync
- schema = strawberry.Schema(query=Query, mutation=Mutation, extensions=[extension])
-
- query = """
- query {
- person {
- name
- }
- }
- """
-
- with pytest.warns(
- DeprecationWarning, match="The Sentry tracing extension is deprecated"
- ):
- schema.execute_sync(query)
-
- assert mock.configure_scope.mock_calls == [
- mocker.call(),
- mocker.call().__enter__(),
- mocker.call().__enter__().span.__bool__(),
- mocker.call()
- .__enter__()
- .span.start_child(op="gql", description="Anonymous Query"),
- mocker.call().__exit__(None, None, None),
- mocker.call()
- .__enter__()
- .span.start_child()
- .set_tag("graphql.operation_type", "query"),
- mocker.call()
- .__enter__()
- .span.start_child()
- .set_tag("graphql.resource_name", "659edba9e6ac9c20d03da1b2d0f9a956"),
- mocker.call().__enter__().span.start_child().set_data("graphql.query", query),
- mocker.call()
- .__enter__()
- .span.start_child()
- .start_child(op="parsing", description="Parsing"),
- mocker.call().__enter__().span.start_child().start_child().finish(),
- mocker.call()
- .__enter__()
- .span.start_child()
- .start_child(op="validation", description="Validation"),
- mocker.call().__enter__().span.start_child().start_child().finish(),
- mocker.call()
- .__enter__()
- .span.start_child()
- .start_child(op="resolve", description="Resolving: Query.person"),
- mocker.call().__enter__().span.start_child().start_child().__enter__(),
- mocker.call()
- .__enter__()
- .span.start_child()
- .start_child()
- .__enter__()
- .set_tag("graphql.field_name", "person"),
- mocker.call()
- .__enter__()
- .span.start_child()
- .start_child()
- .__enter__()
- .set_tag("graphql.parent_type", "Query"),
- mocker.call()
- .__enter__()
- .span.start_child()
- .start_child()
- .__enter__()
- .set_tag("graphql.field_path", "Query.person"),
- mocker.call()
- .__enter__()
- .span.start_child()
- .start_child()
- .__enter__()
- .set_tag("graphql.path", "person"),
- mocker.call()
- .__enter__()
- .span.start_child()
- .start_child()
- .__exit__(None, None, None),
- mocker.call().__enter__().span.start_child().finish(),
- ]
-
-
-def test_uses_operation_name_sync(
- sentry_extension_sync: Tuple[SentryTracingExtensionSync, MagicMock],
-):
- extension, mock = sentry_extension_sync
-
- schema = strawberry.Schema(query=Query, mutation=Mutation, extensions=[extension])
-
- query = """
- query MyExampleQuery {
- person {
- name
- }
- }
- """
-
- with pytest.warns(
- DeprecationWarning, match="The Sentry tracing extension is deprecated"
- ):
- schema.execute_sync(query, operation_name="MyExampleQuery")
-
- mock.configure_scope().__enter__().span.start_child.assert_any_call(
- op="gql", description="MyExampleQuery"
- )
-
-
-def test_uses_operation_type_sync(
- sentry_extension_sync: Tuple[SentryTracingExtensionSync, MagicMock],
-):
- extension, mock = sentry_extension_sync
-
- schema = strawberry.Schema(query=Query, mutation=Mutation, extensions=[extension])
-
- query = """
- mutation MyMutation {
- sayHi
- }
- """
-
- with pytest.warns(
- DeprecationWarning, match="The Sentry tracing extension is deprecated"
- ):
- schema.execute_sync(query, operation_name="MyMutation")
-
- mock.configure_scope().__enter__().span.start_child().set_tag.assert_any_call(
- "graphql.operation_type", "mutation"
- )