Skip to content

Commit 0eba849

Browse files
cvxluoclaude
andauthored
ref(api): tighten event serializer response types (#119351)
Add some slightly more accurate types to docs + dict fields Co-authored-by: Claude <noreply@anthropic.com>
1 parent 41884f8 commit 0eba849

5 files changed

Lines changed: 44 additions & 17 deletions

File tree

src/sentry/api/serializers/models/event.py

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from collections import defaultdict
55
from collections.abc import Sequence
66
from datetime import datetime, timezone
7-
from typing import Any, TypedDict
7+
from typing import Any, NotRequired, TypedDict
88

99
import sentry_sdk
1010
import sqlparse
@@ -18,10 +18,11 @@
1818
from sentry.api.serializers.types import GroupEventReleaseSerializerResponse
1919
from sentry.eventtypes import EventTypeStr
2020
from sentry.grouping.api import GroupingConfig
21+
from sentry.interfaces.sdk import EventSdkApiContext
2122
from sentry.interfaces.user import EventUserApiContext
2223
from sentry.issues.issue_occurrence import IssueOccurrenceResponse
2324
from sentry.models.eventattachment import EventAttachment
24-
from sentry.models.eventerror import EventError
25+
from sentry.models.eventerror import EventError, EventErrorApiContext
2526
from sentry.models.release import Release
2627
from sentry.models.userreport import UserReport
2728
from sentry.sdk_updates import SdkSetupState, get_suggested_updates
@@ -54,6 +55,11 @@ class EventTag(EventTagOptional):
5455
value: str
5556

5657

58+
class MeasurementValue(TypedDict):
59+
value: float
60+
unit: NotRequired[str | None]
61+
62+
5763
def get_crash_files(events):
5864
event_ids = [x.event_id for x in events if x.platform == "native"]
5965
if event_ids:
@@ -161,12 +167,12 @@ class BaseEventSerializerResponse(TypedDict):
161167
size: int | None
162168
entries: list[Any]
163169
dist: str | None
164-
sdk: dict[str, str]
170+
sdk: EventSdkApiContext | None
165171
context: dict[str, Any] | None
166172
packages: dict[str, Any]
167173
type: EventTypeStr
168-
metadata: Any
169-
errors: list[Any]
174+
metadata: dict[str, Any]
175+
errors: list[EventErrorApiContext]
170176
occurrence: IssueOccurrenceResponse | None
171177
_meta: dict[str, Any]
172178

@@ -180,10 +186,10 @@ class ErrorEventFields(TypedDict, total=False):
180186

181187

182188
class TransactionEventFields(TypedDict, total=False):
183-
startTimestamp: datetime
184-
endTimestamp: datetime
185-
measurements: Any
186-
breakdowns: Any
189+
startTimestamp: float
190+
endTimestamp: float
191+
measurements: dict[str, MeasurementValue] | None
192+
breakdowns: dict[str, dict[str, MeasurementValue]] | None
187193

188194

189195
class EventSerializerResponse(
@@ -600,7 +606,7 @@ def serialize(self, obj, attrs, user, **kwargs):
600606
"platform": str | None,
601607
"dateCreated": datetime,
602608
"crashFile": str | None,
603-
"metadata": dict[str, Any] | None,
609+
"metadata": dict[str, Any],
604610
},
605611
)
606612

src/sentry/apidocs/examples/event_examples.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,13 @@
22

33
from drf_spectacular.utils import OpenApiExample
44

5-
from sentry.api.serializers.models.event import EventSerializerResponse, GroupEventDetailsResponse
5+
from sentry.api.serializers.models.event import (
6+
EventSerializerResponse,
7+
GroupEventDetailsResponse,
8+
SimpleEventSerializerResponse,
9+
)
610

7-
SIMPLE_EVENT = {
11+
SIMPLE_EVENT: SimpleEventSerializerResponse = {
812
"eventID": "9fac2ceed9344f2bbfdd1fdacb0ed9b1",
913
"tags": [
1014
{"key": "browser", "value": "Chrome 60.0"},
@@ -16,7 +20,7 @@
1620
{"key": "release", "value": "17642328ead24b51867165985996d04b29310337"},
1721
{"key": "server_name", "value": "web1.example.com"},
1822
],
19-
"dateCreated": "2020-09-11T17:46:36Z",
23+
"dateCreated": datetime.fromisoformat("2020-09-11T17:46:36Z"),
2024
"user": None,
2125
"message": "",
2226
"title": "This is an example Python exception",
@@ -28,7 +32,10 @@
2832
"location": "example.py:123",
2933
"culprit": "/books/new/",
3034
"projectID": "49271",
31-
"metadata": None,
35+
"metadata": {
36+
"type": "ExampleException",
37+
"value": "This is an example Python exception",
38+
},
3239
}
3340

3441
GROUP_EVENT: GroupEventDetailsResponse = {

src/sentry/apidocs/examples/organization_examples.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -956,7 +956,7 @@ class OrganizationExamples:
956956
"packages": {"my.package": "1.0.0"},
957957
"platform": "python",
958958
"projectID": "1",
959-
"sdk": {},
959+
"sdk": {"name": "sentry.python", "version": "2.0.0"},
960960
"size": 7055,
961961
"tags": [
962962
{"key": "browser", "value": "Chrome 28.0"},

src/sentry/interfaces/sdk.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
11
__all__ = ("Sdk",)
22

3+
from typing import TypedDict
4+
35
from sentry.interfaces.base import Interface
46
from sentry.utils.json import prune_empty_keys
57

68

9+
class EventSdkApiContext(TypedDict):
10+
name: str | None
11+
version: str | None
12+
13+
714
class Sdk(Interface):
815
"""
916
The SDK used to transmit this event.
@@ -38,7 +45,7 @@ def to_json(self):
3845
}
3946
)
4047

41-
def get_api_context(self, is_public=False, platform=None):
48+
def get_api_context(self, is_public=False, platform=None) -> EventSdkApiContext:
4249
return {"name": self.name, "version": self.version}
4350

4451
def get_api_meta(self, meta, is_public=False, platform=None):

src/sentry/models/eventerror.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from __future__ import annotations
22

33
import enum
4+
from typing import Any, TypedDict
45

56

67
class EventErrorType(enum.StrEnum):
@@ -60,6 +61,12 @@ class EventErrorType(enum.StrEnum):
6061
PROGUARD_MISSING_LINENO = "proguard_missing_lineno"
6162

6263

64+
class EventErrorApiContext(TypedDict):
65+
type: str
66+
message: str
67+
data: dict[str, Any]
68+
69+
6370
class EventError:
6471
_messages: dict[str, str] = {
6572
EventErrorType.UNKNOWN_ERROR: "Unknown error",
@@ -125,5 +132,5 @@ def data(self):
125132
def message(self):
126133
return self._messages.get(self._data["type"], self._messages["unknown_error"])
127134

128-
def get_api_context(self):
135+
def get_api_context(self) -> EventErrorApiContext:
129136
return {"type": self.type, "message": self.message, "data": self.data}

0 commit comments

Comments
 (0)