Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ref: Patched functions decorator for integrations #2454

Merged
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
190923c
Created async and sync decorators
szokeasaurusrex Oct 18, 2023
c8aeadb
Added use of each sentry decorator
szokeasaurusrex Oct 18, 2023
c18a902
Fix circular import
szokeasaurusrex Oct 18, 2023
0fbea43
Merge branch 'sentry-sdk-2.0' into szokeasaurusrex/sentry_patched_dec…
szokeasaurusrex Mar 15, 2024
9f5c279
Revert changes to starlette.py
szokeasaurusrex Mar 15, 2024
45b90ab
Rename method
szokeasaurusrex Mar 15, 2024
69ebafb
Use actual generics, move async implementation to utils
szokeasaurusrex Mar 15, 2024
46cd0e2
Refactor parameters
szokeasaurusrex Mar 15, 2024
7a8196a
Undo changes to _types.py
szokeasaurusrex Mar 15, 2024
d9016db
Use client instead of Hub
szokeasaurusrex Mar 15, 2024
75934d1
Add doc string
szokeasaurusrex Mar 15, 2024
66726d0
Move type comments
szokeasaurusrex Mar 15, 2024
4e48ce3
Merge branch 'sentry-sdk-2.0' into szokeasaurusrex/sentry_patched_dec…
szokeasaurusrex Mar 18, 2024
e8c921c
Fix mypy
szokeasaurusrex Mar 18, 2024
20688fd
Fix circular import
szokeasaurusrex Mar 18, 2024
d93ff92
Added unit tests for decorators
szokeasaurusrex Mar 18, 2024
4b90191
Merge branch 'sentry-sdk-2.0' into szokeasaurusrex/sentry_patched_dec…
szokeasaurusrex Mar 18, 2024
85c1a1f
Revert gql changes
szokeasaurusrex Mar 18, 2024
1bb2f11
Fix typo
szokeasaurusrex Mar 18, 2024
41a6bad
Try forking the flaky test
antonpirker Mar 18, 2024
f05e00c
no
antonpirker Mar 18, 2024
a9aa22d
debug output
antonpirker Mar 18, 2024
25fb0b9
debug output
antonpirker Mar 18, 2024
38d6249
Debug output
antonpirker Mar 19, 2024
099d747
debugging
antonpirker Mar 19, 2024
41b433e
fix?
antonpirker Mar 19, 2024
56e5eeb
Cleanup
antonpirker Mar 19, 2024
940ef7c
typo
antonpirker Mar 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions sentry_sdk/integrations/gql.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
from sentry_sdk.utils import event_from_exception, parse_version
from sentry_sdk.utils import (
event_from_exception,
ensure_integration_enabled,
parse_version,
)
from sentry_sdk.hub import Hub, _should_send_default_pii
from sentry_sdk.integrations import DidNotEnable, Integration

Expand Down Expand Up @@ -85,13 +89,11 @@ def _patch_execute():
# type: () -> None
real_execute = gql.Client.execute

@ensure_integration_enabled(GQLIntegration, real_execute)
def sentry_patched_execute(self, document, *args, **kwargs):
# type: (gql.Client, DocumentNode, Any, Any) -> Any
hub = Hub.current
if hub.get_integration(GQLIntegration) is None:
return real_execute(self, document, *args, **kwargs)

with Hub.current.configure_scope() as scope:
with hub.configure_scope() as scope:
scope.add_event_processor(_make_gql_event_processor(self, document))

try:
Expand Down
79 changes: 78 additions & 1 deletion sentry_sdk/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from copy import copy
from datetime import datetime
from decimal import Decimal
from functools import partial, partialmethod
from functools import partial, partialmethod, wraps
from numbers import Real
from urllib.parse import parse_qs, unquote, urlencode, urlsplit, urlunsplit

Expand All @@ -26,11 +26,14 @@
BaseExceptionGroup = None # type: ignore

import sentry_sdk
import sentry_sdk.hub
from sentry_sdk._compat import PY37
from sentry_sdk._types import TYPE_CHECKING
from sentry_sdk.consts import DEFAULT_MAX_VALUE_LENGTH, EndpointType

if TYPE_CHECKING:
from collections.abc import Awaitable

Check warning on line 35 in sentry_sdk/utils.py

View check run for this annotation

Codecov / codecov/patch

sentry_sdk/utils.py#L35

Added line #L35 was not covered by tests

from types import FrameType, TracebackType
from typing import (
Any,
Expand All @@ -41,14 +44,20 @@
List,
NoReturn,
Optional,
ParamSpec,
Set,
Tuple,
Type,
TypeVar,
Union,
)
from sentry_sdk.integrations import Integration

Check warning on line 54 in sentry_sdk/utils.py

View check run for this annotation

Codecov / codecov/patch

sentry_sdk/utils.py#L54

Added line #L54 was not covered by tests

from sentry_sdk._types import Event, ExcInfo

P = ParamSpec("P")
R = TypeVar("R")

Check warning on line 59 in sentry_sdk/utils.py

View check run for this annotation

Codecov / codecov/patch

sentry_sdk/utils.py#L58-L59

Added lines #L58 - L59 were not covered by tests


epoch = datetime(1970, 1, 1)

Expand Down Expand Up @@ -1622,6 +1631,74 @@
raise value


def ensure_integration_enabled(
integration, # type: type[Integration]
original_function, # type: Callable[P, R]
):
# type: (...) -> Callable[[Callable[P, R]], Callable[P, R]]
"""
Ensures a given integration is enabled prior to calling a Sentry-patched function.

The function takes as its parameters the integration that must be enabled and the original
function that the SDK is patching. The function returns a function that takes the
decorated (Sentry-patched) function as its parameter, and returns a function that, when
called, checks whether the given integration is enabled. If the integration is enabled, the
funciton calls the decorated, Sentry-patched funciton. If the integration is not enabled,
szokeasaurusrex marked this conversation as resolved.
Show resolved Hide resolved
the original function is called.

The function also takes care of preserving the original function's signature and docstring.

Example usage:

```python
@ensure_integration_enabled(MyIntegration, my_function)
def patch_my_function():
with sentry_sdk.start_transaction(...):
return my_function()
```
"""

def patcher(sentry_patched_function):
# type: (Callable[P, R]) -> Callable[P, R]
@wraps(original_function)
def runner(*args: "P.args", **kwargs: "P.kwargs"):
antonpirker marked this conversation as resolved.
Show resolved Hide resolved
# type: (...) -> R
if sentry_sdk.get_client().get_integration(integration) is None:
return original_function(*args, **kwargs)

Check warning on line 1667 in sentry_sdk/utils.py

View check run for this annotation

Codecov / codecov/patch

sentry_sdk/utils.py#L1667

Added line #L1667 was not covered by tests

return sentry_patched_function(*args, **kwargs)

return runner

return patcher


def ensure_integration_enabled_async(
integration, # type: type[Integration]
original_function, # type: Callable[P, Awaitable[R]]
):
# type: (...) -> Callable[[Callable[P, Awaitable[R]]], Callable[P, Awaitable[R]]]
"""
Version of `ensure_integration_enabled` for decorating async functions.

Please refer to the `ensure_integration_enabled` documentation for more information.
"""

def patcher(sentry_patched_function):

Check warning on line 1687 in sentry_sdk/utils.py

View check run for this annotation

Codecov / codecov/patch

sentry_sdk/utils.py#L1687

Added line #L1687 was not covered by tests
# type: (Callable[P, Awaitable[R]]) -> Callable[P, Awaitable[R]]
@wraps(original_function)

Check warning on line 1689 in sentry_sdk/utils.py

View check run for this annotation

Codecov / codecov/patch

sentry_sdk/utils.py#L1689

Added line #L1689 was not covered by tests
async def runner(*args: "P.args", **kwargs: "P.kwargs"):
# type: (...) -> R
if sentry_sdk.get_client().get_integration(integration) is None:
return await original_function(*args, **kwargs)

Check warning on line 1693 in sentry_sdk/utils.py

View check run for this annotation

Codecov / codecov/patch

sentry_sdk/utils.py#L1693

Added line #L1693 was not covered by tests

return await sentry_patched_function(*args, **kwargs)

Check warning on line 1695 in sentry_sdk/utils.py

View check run for this annotation

Codecov / codecov/patch

sentry_sdk/utils.py#L1695

Added line #L1695 was not covered by tests

return runner

Check warning on line 1697 in sentry_sdk/utils.py

View check run for this annotation

Codecov / codecov/patch

sentry_sdk/utils.py#L1697

Added line #L1697 was not covered by tests

return patcher

Check warning on line 1699 in sentry_sdk/utils.py

View check run for this annotation

Codecov / codecov/patch

sentry_sdk/utils.py#L1699

Added line #L1699 was not covered by tests


if PY37:

def nanosecond_time():
Expand Down
Loading