Skip to content

Django urlconf callback #1302

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

Closed
wants to merge 11 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
15 changes: 12 additions & 3 deletions sentry_sdk/integrations/django/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@

from sentry_sdk.integrations.wsgi import _ScopedResponse
from sentry_sdk._types import Event, Hint, EventProcessor, NotImplementedType
from sentry_sdk.integrations.django._types import CustomUrlconf


if DJANGO_VERSION < (1, 10):
Expand All @@ -85,15 +86,21 @@ class DjangoIntegration(Integration):
transaction_style = None
middleware_spans = None

def __init__(self, transaction_style="url", middleware_spans=True):
# type: (str, bool) -> None
# a custom urlconf can be a string pointing to a module
# or a callback returning a string pointing to a module
# or a list of url_patterns themselves
urlconf = None

def __init__(self, transaction_style="url", middleware_spans=True, urlconf=None):
# type: (str, bool, Optional[CustomUrlconf]) -> None
if transaction_style not in TRANSACTION_STYLE_VALUES:
raise ValueError(
"Invalid value for transaction_style: %s (must be in %s)"
% (transaction_style, TRANSACTION_STYLE_VALUES)
)
self.transaction_style = transaction_style
self.middleware_spans = middleware_spans
self.urlconf = urlconf

@staticmethod
def setup_once():
Expand Down Expand Up @@ -337,7 +344,9 @@ def _before_get_response(request):
getattr(fn, "view_class", fn)
)
elif integration.transaction_style == "url":
scope.transaction = LEGACY_RESOLVER.resolve(request.path_info)
scope.transaction = LEGACY_RESOLVER.resolve(
request.path_info, integration.urlconf
)
except Exception:
pass

Expand Down
12 changes: 12 additions & 0 deletions sentry_sdk/integrations/django/_types.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from sentry_sdk._types import MYPY

if MYPY:
from typing import Callable, Union, Tuple
from django.urls.resolvers import URLPattern, URLResolver

CustomUrlconf = Union[
str,
Callable[[], str],
Tuple[URLPattern, URLPattern, URLResolver],
Tuple[URLPattern],
]
7 changes: 4 additions & 3 deletions sentry_sdk/integrations/django/transactions.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
from typing import List
from typing import Optional
from django.urls.resolvers import URLPattern
from typing import Tuple
from typing import Union
from re import Pattern
from sentry_sdk.integrations.django._types import CustomUrlconf

try:
from django.urls import get_resolver
Expand Down Expand Up @@ -125,10 +125,11 @@ def _resolve(self, resolver, path, parents=None):
def resolve(
self,
path, # type: str
urlconf=None, # type: Union[None, Tuple[URLPattern, URLPattern, URLResolver], Tuple[URLPattern]]
urlconf=None, # type: Optional[CustomUrlconf]
):
# type: (...) -> str
resolver = get_resolver(urlconf)
resolver_urlconf = urlconf() if callable(urlconf) else urlconf
resolver = get_resolver(resolver_urlconf)
match = self._resolve(resolver, path)
return match or path

Expand Down
15 changes: 15 additions & 0 deletions tests/integrations/django/myapp/custom_urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from __future__ import absolute_import

import django

if django.VERSION >= (2, 0):
# TODO: once we stop supporting django < 2, use the real name of this
# function (re_path)
from django.urls import re_path as url
else:
from django.conf.urls import url


urlpatterns = [
url(r"^foo/bar/baz/(?P<param>[\d]+)", lambda x: ""),
]
16 changes: 16 additions & 0 deletions tests/integrations/django/test_transactions.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,19 @@ def test_legacy_resolver_newstyle_django20_urlconf():
resolver = RavenResolver()
result = resolver.resolve("/api/v2/1234/store/", url_conf)
assert result == "/api/v2/{project_id}/store/"


def test_legacy_resolver_custom_urlconf_module_name():
resolver = RavenResolver()
custom_urlconf_module = "tests.integrations.django.myapp.custom_urls"
result = resolver.resolve("/foo/bar/baz/1234", custom_urlconf_module)
assert result == "/foo/bar/baz/{param}"


def test_legacy_resolver_custom_urlconf_callback():
def custom_urlconf_callback():
return "tests.integrations.django.myapp.custom_urls"

resolver = RavenResolver()
result = resolver.resolve("/foo/bar/baz/1234", custom_urlconf_callback)
assert result == "/foo/bar/baz/{param}"