Skip to content

Commit 818c8f9

Browse files
authored
feat(profiling): Add release to profile payload (#41282)
In order to support the `Open in ...` feature, we need to return some metadata for the release. Make sure we add that onto the payload.
1 parent 0458c67 commit 818c8f9

File tree

3 files changed

+50
-17
lines changed

3 files changed

+50
-17
lines changed

src/sentry/api/endpoints/organization_profiling_profiles.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from typing import Any, Dict
22

3-
from django.http import StreamingHttpResponse
3+
from django.http import HttpResponse
44
from rest_framework.exceptions import ParseError
55
from rest_framework.request import Request
66
from rest_framework.response import Response
@@ -31,7 +31,7 @@ def get_profiling_params(self, request: Request, organization: Organization) ->
3131

3232
@region_silo_endpoint
3333
class OrganizationProfilingFiltersEndpoint(OrganizationProfilingBaseEndpoint):
34-
def get(self, request: Request, organization: Organization) -> StreamingHttpResponse:
34+
def get(self, request: Request, organization: Organization) -> HttpResponse:
3535
if not features.has("organizations:profiling", organization, actor=request.user):
3636
return Response(status=404)
3737

src/sentry/api/endpoints/project_profiling_profile.py

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from abc import ABC, abstractmethod
22
from typing import Any, Dict
33

4-
from django.http import StreamingHttpResponse
4+
from django.http import HttpResponse
55
from rest_framework.exceptions import ParseError
66
from rest_framework.request import Request
77
from rest_framework.response import Response
@@ -10,8 +10,10 @@
1010
from sentry.api.base import region_silo_endpoint
1111
from sentry.api.bases.project import ProjectEndpoint
1212
from sentry.api.paginator import GenericOffsetPaginator
13+
from sentry.api.serializers import serialize
1314
from sentry.exceptions import InvalidSearchQuery
14-
from sentry.models import Project
15+
from sentry.models.project import Project
16+
from sentry.models.release import Release
1517
from sentry.profiles.utils import (
1618
get_from_profiling_service,
1719
parse_profile_filters,
@@ -64,7 +66,7 @@ def get(self, request: Request, project: Project) -> Response:
6466

6567
@region_silo_endpoint
6668
class ProjectProfilingTransactionIDProfileIDEndpoint(ProjectProfilingBaseEndpoint):
67-
def get(self, request: Request, project: Project, transaction_id: str) -> StreamingHttpResponse:
69+
def get(self, request: Request, project: Project, transaction_id: str) -> HttpResponse:
6870
if not features.has("organizations:profiling", project.organization, actor=request.user):
6971
return Response(status=404)
7072
kwargs: Dict[str, Any] = {
@@ -76,19 +78,50 @@ def get(self, request: Request, project: Project, transaction_id: str) -> Stream
7678

7779
@region_silo_endpoint
7880
class ProjectProfilingProfileEndpoint(ProjectProfilingBaseEndpoint):
79-
def get(self, request: Request, project: Project, profile_id: str) -> StreamingHttpResponse:
81+
def get(self, request: Request, project: Project, profile_id: str) -> HttpResponse:
8082
if not features.has("organizations:profiling", project.organization, actor=request.user):
8183
return Response(status=404)
82-
kwargs: Dict[str, Any] = {
83-
"method": "GET",
84-
"path": f"/organizations/{project.organization.id}/projects/{project.id}/profiles/{profile_id}",
85-
}
86-
return proxy_profiling_service(**kwargs)
84+
85+
response = get_from_profiling_service(
86+
"GET",
87+
f"/organizations/{project.organization.id}/projects/{project.id}/profiles/{profile_id}",
88+
)
89+
90+
if response.status == 200:
91+
profile = json.loads(response.data)
92+
93+
# make sure to remove the version from the metadata
94+
# we're going to replace it with the release here
95+
version = profile.get("metadata", {}).pop("version")
96+
profile["metadata"]["release"] = get_release(project, version)
97+
98+
return Response(profile)
99+
100+
return HttpResponse(
101+
content=response.data,
102+
status=response.status,
103+
content_type=response.headers.get("Content-Type", "application/json"),
104+
)
105+
106+
107+
def get_release(project: Project, version: str) -> Any:
108+
if not version:
109+
return None
110+
111+
try:
112+
release = Release.objects.get(
113+
projects=project,
114+
organization_id=project.organization_id,
115+
version=version,
116+
)
117+
return serialize(release)
118+
except Release.DoesNotExist:
119+
return {"version": version}
87120

88121

89122
@region_silo_endpoint
90123
class ProjectProfilingRawProfileEndpoint(ProjectProfilingBaseEndpoint):
91-
def get(self, request: Request, project: Project, profile_id: str) -> StreamingHttpResponse:
124+
def get(self, request: Request, project: Project, profile_id: str) -> HttpResponse:
92125
if not features.has("organizations:profiling", project.organization, actor=request.user):
93126
return Response(status=404)
94127
kwargs: Dict[str, Any] = {

src/sentry/profiles/utils.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
import brotli
66
import urllib3
77
from django.conf import settings
8-
from django.http import HttpResponse
8+
from django.http import HttpResponse as SentryResponse
99
from parsimonious.exceptions import ParseError
10-
from urllib3.response import HTTPResponse
10+
from urllib3.response import HTTPResponse as VroomResponse
1111

1212
from sentry.api.event_search import SearchFilter, parse_search_query
1313
from sentry.exceptions import InvalidSearchQuery
@@ -78,7 +78,7 @@ def get_from_profiling_service(
7878
params: Optional[Dict[Any, Any]] = None,
7979
headers: Optional[Dict[Any, Any]] = None,
8080
json_data: Any = None,
81-
) -> HTTPResponse:
81+
) -> VroomResponse:
8282
kwargs: Dict[str, Any] = {"headers": {}}
8383
if params:
8484
params = {
@@ -113,9 +113,9 @@ def proxy_profiling_service(
113113
path: str,
114114
params: Optional[Dict[str, Any]] = None,
115115
headers: Optional[Dict[str, str]] = None,
116-
) -> HttpResponse:
116+
) -> SentryResponse:
117117
profiling_response = get_from_profiling_service(method, path, params=params, headers=headers)
118-
return HttpResponse(
118+
return SentryResponse(
119119
content=profiling_response.data,
120120
status=profiling_response.status,
121121
content_type=profiling_response.headers.get("Content-Type", "application/json"),

0 commit comments

Comments
 (0)