sentry-sdk 3.0.0a3__py2.py3-none-any.whl → 3.0.0a4__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of sentry-sdk might be problematic. Click here for more details.

Files changed (58) hide show
  1. sentry_sdk/__init__.py +2 -0
  2. sentry_sdk/ai/monitoring.py +7 -7
  3. sentry_sdk/ai/utils.py +5 -1
  4. sentry_sdk/api.py +16 -0
  5. sentry_sdk/client.py +10 -7
  6. sentry_sdk/consts.py +38 -7
  7. sentry_sdk/integrations/aiohttp.py +1 -1
  8. sentry_sdk/integrations/anthropic.py +1 -1
  9. sentry_sdk/integrations/arq.py +1 -1
  10. sentry_sdk/integrations/asyncio.py +1 -1
  11. sentry_sdk/integrations/asyncpg.py +1 -1
  12. sentry_sdk/integrations/boto3.py +2 -2
  13. sentry_sdk/integrations/celery/__init__.py +4 -3
  14. sentry_sdk/integrations/clickhouse_driver.py +1 -1
  15. sentry_sdk/integrations/cohere.py +2 -2
  16. sentry_sdk/integrations/django/__init__.py +12 -2
  17. sentry_sdk/integrations/django/asgi.py +1 -1
  18. sentry_sdk/integrations/django/caching.py +1 -1
  19. sentry_sdk/integrations/django/middleware.py +1 -1
  20. sentry_sdk/integrations/django/signals_handlers.py +1 -1
  21. sentry_sdk/integrations/django/templates.py +2 -2
  22. sentry_sdk/integrations/django/views.py +2 -2
  23. sentry_sdk/integrations/gnu_backtrace.py +3 -14
  24. sentry_sdk/integrations/graphene.py +1 -1
  25. sentry_sdk/integrations/grpc/aio/client.py +2 -2
  26. sentry_sdk/integrations/grpc/client.py +2 -2
  27. sentry_sdk/integrations/httpx.py +2 -2
  28. sentry_sdk/integrations/huey.py +1 -1
  29. sentry_sdk/integrations/huggingface_hub.py +1 -1
  30. sentry_sdk/integrations/langchain.py +1 -1
  31. sentry_sdk/integrations/litestar.py +3 -3
  32. sentry_sdk/integrations/logging.py +1 -1
  33. sentry_sdk/integrations/loguru.py +1 -1
  34. sentry_sdk/integrations/openai.py +339 -134
  35. sentry_sdk/integrations/openai_agents/utils.py +1 -49
  36. sentry_sdk/integrations/openfeature.py +4 -5
  37. sentry_sdk/integrations/pymongo.py +1 -1
  38. sentry_sdk/integrations/ray.py +1 -1
  39. sentry_sdk/integrations/redis/_async_common.py +3 -3
  40. sentry_sdk/integrations/redis/_sync_common.py +3 -3
  41. sentry_sdk/integrations/rust_tracing.py +1 -1
  42. sentry_sdk/integrations/socket.py +2 -2
  43. sentry_sdk/integrations/starlette.py +3 -3
  44. sentry_sdk/integrations/starlite.py +3 -3
  45. sentry_sdk/integrations/stdlib.py +4 -4
  46. sentry_sdk/integrations/strawberry.py +1 -1
  47. sentry_sdk/integrations/threading.py +1 -1
  48. sentry_sdk/opentelemetry/scope.py +10 -0
  49. sentry_sdk/serializer.py +8 -11
  50. sentry_sdk/tracing.py +3 -3
  51. sentry_sdk/tracing_utils.py +3 -3
  52. sentry_sdk/utils.py +46 -0
  53. {sentry_sdk-3.0.0a3.dist-info → sentry_sdk-3.0.0a4.dist-info}/METADATA +1 -1
  54. {sentry_sdk-3.0.0a3.dist-info → sentry_sdk-3.0.0a4.dist-info}/RECORD +58 -58
  55. {sentry_sdk-3.0.0a3.dist-info → sentry_sdk-3.0.0a4.dist-info}/WHEEL +0 -0
  56. {sentry_sdk-3.0.0a3.dist-info → sentry_sdk-3.0.0a4.dist-info}/entry_points.txt +0 -0
  57. {sentry_sdk-3.0.0a3.dist-info → sentry_sdk-3.0.0a4.dist-info}/licenses/LICENSE +0 -0
  58. {sentry_sdk-3.0.0a3.dist-info → sentry_sdk-3.0.0a4.dist-info}/top_level.txt +0 -0
@@ -1,17 +1,15 @@
1
1
  from __future__ import annotations
2
2
 
3
- import json
4
3
  import sentry_sdk
5
4
  from sentry_sdk.consts import SPANDATA
6
5
  from sentry_sdk.integrations import DidNotEnable
7
6
  from sentry_sdk.scope import should_send_default_pii
8
- from sentry_sdk.utils import event_from_exception
7
+ from sentry_sdk.utils import event_from_exception, safe_serialize
9
8
 
10
9
  from typing import TYPE_CHECKING
11
10
 
12
11
  if TYPE_CHECKING:
13
12
  from typing import Any
14
- from typing import Union
15
13
  from agents import Usage
16
14
 
17
15
  try:
@@ -153,49 +151,3 @@ def _set_output_data(span: sentry_sdk.tracing.Span, result: Any) -> None:
153
151
  span.set_attribute(
154
152
  SPANDATA.GEN_AI_RESPONSE_TEXT, safe_serialize(output_messages["response"])
155
153
  )
156
-
157
-
158
- def safe_serialize(data: Any) -> str:
159
- """Safely serialize to a readable string."""
160
-
161
- def serialize_item(
162
- item: Any,
163
- ) -> Union[str, dict[Any, Any], list[Any], tuple[Any, ...]]:
164
- if callable(item):
165
- try:
166
- module = getattr(item, "__module__", None)
167
- qualname = getattr(item, "__qualname__", None)
168
- name = getattr(item, "__name__", "anonymous")
169
-
170
- if module and qualname:
171
- full_path = f"{module}.{qualname}"
172
- elif module and name:
173
- full_path = f"{module}.{name}"
174
- else:
175
- full_path = name
176
-
177
- return f"<function {full_path}>"
178
- except Exception:
179
- return f"<callable {type(item).__name__}>"
180
- elif isinstance(item, dict):
181
- return {k: serialize_item(v) for k, v in item.items()}
182
- elif isinstance(item, (list, tuple)):
183
- return [serialize_item(x) for x in item]
184
- elif hasattr(item, "__dict__"):
185
- try:
186
- attrs = {
187
- k: serialize_item(v)
188
- for k, v in vars(item).items()
189
- if not k.startswith("_")
190
- }
191
- return f"<{type(item).__name__} {attrs}>"
192
- except Exception:
193
- return repr(item)
194
- else:
195
- return item
196
-
197
- try:
198
- serialized = serialize_item(data)
199
- return json.dumps(serialized, default=str)
200
- except Exception:
201
- return str(data)
@@ -1,5 +1,5 @@
1
1
  from __future__ import annotations
2
- from typing import TYPE_CHECKING
2
+ from typing import TYPE_CHECKING, Any
3
3
 
4
4
  from sentry_sdk.feature_flags import add_feature_flag
5
5
  from sentry_sdk.integrations import DidNotEnable, Integration
@@ -9,7 +9,6 @@ try:
9
9
  from openfeature.hook import Hook
10
10
 
11
11
  if TYPE_CHECKING:
12
- from openfeature.flag_evaluation import FlagEvaluationDetails
13
12
  from openfeature.hook import HookContext, HookHints
14
13
  except ImportError:
15
14
  raise DidNotEnable("OpenFeature is not installed")
@@ -28,9 +27,9 @@ class OpenFeatureHook(Hook):
28
27
 
29
28
  def after(
30
29
  self,
31
- hook_context: HookContext,
32
- details: FlagEvaluationDetails[bool],
33
- hints: HookHints,
30
+ hook_context: Any,
31
+ details: Any,
32
+ hints: Any,
34
33
  ) -> None:
35
34
  if isinstance(details.value, bool):
36
35
  add_feature_flag(details.flag_key, details.value)
@@ -152,7 +152,7 @@ class CommandTracer(monitoring.CommandListener):
152
152
  op=OP.DB,
153
153
  name=query,
154
154
  origin=PyMongoIntegration.origin,
155
- only_if_parent=True,
155
+ only_as_child_span=True,
156
156
  )
157
157
 
158
158
  with capture_internal_exceptions():
@@ -101,7 +101,7 @@ def _patch_ray_remote() -> None:
101
101
  op=OP.QUEUE_SUBMIT_RAY,
102
102
  name=qualname_from_function(user_f),
103
103
  origin=RayIntegration.origin,
104
- only_if_parent=True,
104
+ only_as_child_span=True,
105
105
  ) as span:
106
106
  tracing = {
107
107
  k: v
@@ -42,7 +42,7 @@ def patch_redis_async_pipeline(
42
42
  op=OP.DB_REDIS,
43
43
  name="redis.pipeline.execute",
44
44
  origin=SPAN_ORIGIN,
45
- only_if_parent=True,
45
+ only_as_child_span=True,
46
46
  ) as span:
47
47
  with capture_internal_exceptions():
48
48
  span_data = get_db_data_fn(self)
@@ -98,7 +98,7 @@ def patch_redis_async_client(
98
98
  op=cache_properties["op"],
99
99
  name=cache_properties["description"],
100
100
  origin=SPAN_ORIGIN,
101
- only_if_parent=True,
101
+ only_as_child_span=True,
102
102
  )
103
103
  cache_span.__enter__()
104
104
 
@@ -108,7 +108,7 @@ def patch_redis_async_client(
108
108
  op=db_properties["op"],
109
109
  name=db_properties["description"],
110
110
  origin=SPAN_ORIGIN,
111
- only_if_parent=True,
111
+ only_as_child_span=True,
112
112
  )
113
113
  db_span.__enter__()
114
114
 
@@ -40,7 +40,7 @@ def patch_redis_pipeline(
40
40
  op=OP.DB_REDIS,
41
41
  name="redis.pipeline.execute",
42
42
  origin=SPAN_ORIGIN,
43
- only_if_parent=True,
43
+ only_as_child_span=True,
44
44
  ) as span:
45
45
  with capture_internal_exceptions():
46
46
  try:
@@ -94,7 +94,7 @@ def patch_redis_client(
94
94
  op=cache_properties["op"],
95
95
  name=cache_properties["description"],
96
96
  origin=SPAN_ORIGIN,
97
- only_if_parent=True,
97
+ only_as_child_span=True,
98
98
  )
99
99
  cache_span.__enter__()
100
100
 
@@ -104,7 +104,7 @@ def patch_redis_client(
104
104
  op=db_properties["op"],
105
105
  name=db_properties["description"],
106
106
  origin=SPAN_ORIGIN,
107
- only_if_parent=True,
107
+ only_as_child_span=True,
108
108
  )
109
109
  db_span.__enter__()
110
110
 
@@ -210,7 +210,7 @@ class RustTracingLayer:
210
210
  op="function",
211
211
  name=sentry_span_name,
212
212
  origin=self.origin,
213
- only_if_parent=True,
213
+ only_as_child_span=True,
214
214
  )
215
215
  span.__enter__()
216
216
 
@@ -60,7 +60,7 @@ def _patch_create_connection() -> None:
60
60
  op=OP.SOCKET_CONNECTION,
61
61
  name=_get_span_description(address[0], address[1]),
62
62
  origin=SocketIntegration.origin,
63
- only_if_parent=True,
63
+ only_as_child_span=True,
64
64
  ) as span:
65
65
  host, port = address
66
66
  span.set_attribute("address.host", host)
@@ -102,7 +102,7 @@ def _patch_getaddrinfo() -> None:
102
102
  op=OP.SOCKET_DNS,
103
103
  name=_get_span_description(host, port),
104
104
  origin=SocketIntegration.origin,
105
- only_if_parent=True,
105
+ only_as_child_span=True,
106
106
  ) as span:
107
107
  span.set_attribute("host", host)
108
108
  span.set_attribute("port", port)
@@ -144,7 +144,7 @@ def _enable_span_for_middleware(middleware_class: Any) -> type:
144
144
  op=OP.MIDDLEWARE_STARLETTE,
145
145
  name=middleware_name,
146
146
  origin=StarletteIntegration.origin,
147
- only_if_parent=True,
147
+ only_as_child_span=True,
148
148
  ) as middleware_span:
149
149
  middleware_span.set_tag("starlette.middleware_name", middleware_name)
150
150
 
@@ -154,7 +154,7 @@ def _enable_span_for_middleware(middleware_class: Any) -> type:
154
154
  op=OP.MIDDLEWARE_STARLETTE_RECEIVE,
155
155
  name=getattr(receive, "__qualname__", str(receive)),
156
156
  origin=StarletteIntegration.origin,
157
- only_if_parent=True,
157
+ only_as_child_span=True,
158
158
  ) as span:
159
159
  span.set_tag("starlette.middleware_name", middleware_name)
160
160
  return await receive(*args, **kwargs)
@@ -169,7 +169,7 @@ def _enable_span_for_middleware(middleware_class: Any) -> type:
169
169
  op=OP.MIDDLEWARE_STARLETTE_SEND,
170
170
  name=getattr(send, "__qualname__", str(send)),
171
171
  origin=StarletteIntegration.origin,
172
- only_if_parent=True,
172
+ only_as_child_span=True,
173
173
  ) as span:
174
174
  span.set_tag("starlette.middleware_name", middleware_name)
175
175
  return await send(*args, **kwargs)
@@ -136,7 +136,7 @@ def enable_span_for_middleware(middleware: Middleware) -> Middleware:
136
136
  op=OP.MIDDLEWARE_STARLITE,
137
137
  name=middleware_name,
138
138
  origin=StarliteIntegration.origin,
139
- only_if_parent=True,
139
+ only_as_child_span=True,
140
140
  ) as middleware_span:
141
141
  middleware_span.set_tag("starlite.middleware_name", middleware_name)
142
142
 
@@ -150,7 +150,7 @@ def enable_span_for_middleware(middleware: Middleware) -> Middleware:
150
150
  op=OP.MIDDLEWARE_STARLITE_RECEIVE,
151
151
  name=getattr(receive, "__qualname__", str(receive)),
152
152
  origin=StarliteIntegration.origin,
153
- only_if_parent=True,
153
+ only_as_child_span=True,
154
154
  ) as span:
155
155
  span.set_tag("starlite.middleware_name", middleware_name)
156
156
  return await receive(*args, **kwargs)
@@ -167,7 +167,7 @@ def enable_span_for_middleware(middleware: Middleware) -> Middleware:
167
167
  op=OP.MIDDLEWARE_STARLITE_SEND,
168
168
  name=getattr(send, "__qualname__", str(send)),
169
169
  origin=StarliteIntegration.origin,
170
- only_if_parent=True,
170
+ only_as_child_span=True,
171
171
  ) as span:
172
172
  span.set_tag("starlite.middleware_name", middleware_name)
173
173
  return await send(message)
@@ -95,7 +95,7 @@ def _install_httplib() -> None:
95
95
  name="%s %s"
96
96
  % (method, parsed_url.url if parsed_url else SENSITIVE_DATA_SUBSTITUTE),
97
97
  origin="auto.http.stdlib.httplib",
98
- only_if_parent=True,
98
+ only_as_child_span=True,
99
99
  )
100
100
  span.__enter__()
101
101
 
@@ -236,7 +236,7 @@ def _install_subprocess() -> None:
236
236
  op=OP.SUBPROCESS,
237
237
  name=description,
238
238
  origin="auto.subprocess.stdlib.subprocess",
239
- only_if_parent=True,
239
+ only_as_child_span=True,
240
240
  ) as span:
241
241
  for k, v in sentry_sdk.get_current_scope().iter_trace_propagation_headers(
242
242
  span=span
@@ -288,7 +288,7 @@ def _install_subprocess() -> None:
288
288
  with sentry_sdk.start_span(
289
289
  op=OP.SUBPROCESS_WAIT,
290
290
  origin="auto.subprocess.stdlib.subprocess",
291
- only_if_parent=True,
291
+ only_as_child_span=True,
292
292
  ) as span:
293
293
  span.set_tag("subprocess.pid", self.pid)
294
294
  return old_popen_wait(self, *a, **kw)
@@ -304,7 +304,7 @@ def _install_subprocess() -> None:
304
304
  with sentry_sdk.start_span(
305
305
  op=OP.SUBPROCESS_COMMUNICATE,
306
306
  origin="auto.subprocess.stdlib.subprocess",
307
- only_if_parent=True,
307
+ only_as_child_span=True,
308
308
  ) as span:
309
309
  span.set_tag("subprocess.pid", self.pid)
310
310
  return old_popen_communicate(self, *a, **kw)
@@ -173,7 +173,7 @@ class SentryAsyncExtension(SchemaExtension):
173
173
  op=op,
174
174
  name=description,
175
175
  origin=StrawberryIntegration.origin,
176
- only_if_parent=True,
176
+ only_as_child_span=True,
177
177
  ) as graphql_span:
178
178
  graphql_span.set_attribute("graphql.operation.type", operation_type)
179
179
  graphql_span.set_attribute("graphql.document", self.execution_context.query)
@@ -106,7 +106,7 @@ def _wrap_run(
106
106
  def _run_old_run_func() -> Any:
107
107
  try:
108
108
  self = current_thread()
109
- return old_run_func(self, *a, **kw)
109
+ return old_run_func(self, *a[1:], **kw)
110
110
  except Exception:
111
111
  reraise(*_capture_exception())
112
112
 
@@ -15,6 +15,7 @@ from opentelemetry.trace import (
15
15
  TraceFlags,
16
16
  TraceState,
17
17
  use_span,
18
+ INVALID_SPAN,
18
19
  )
19
20
 
20
21
  from sentry_sdk.opentelemetry.consts import (
@@ -89,6 +90,15 @@ class PotelScope(Scope):
89
90
  with use_span(NonRecordingSpan(span_context)):
90
91
  yield
91
92
 
93
+ @contextmanager
94
+ def new_trace(self) -> Generator[None, None, None]:
95
+ """
96
+ Force creation of a new trace.
97
+ """
98
+ self.generate_propagation_context()
99
+ with use_span(INVALID_SPAN):
100
+ yield
101
+
92
102
  def _incoming_otel_span_context(self) -> Optional[SpanContext]:
93
103
  if self._propagation_context is None:
94
104
  return None
sentry_sdk/serializer.py CHANGED
@@ -39,16 +39,6 @@ if TYPE_CHECKING:
39
39
  serializable_str_types = (str, bytes, bytearray, memoryview)
40
40
 
41
41
 
42
- # Maximum length of JSON-serialized event payloads that can be safely sent
43
- # before the server may reject the event due to its size. This is not intended
44
- # to reflect actual values defined server-side, but rather only be an upper
45
- # bound for events sent by the SDK.
46
- #
47
- # Can be overwritten if wanting to send more bytes, e.g. with a custom server.
48
- # When changing this, keep in mind that events may be a little bit larger than
49
- # this value due to attached metadata, so keep the number conservative.
50
- MAX_EVENT_BYTES = 10**6
51
-
52
42
  # Maximum depth and breadth of databags. Excess data will be trimmed. If
53
43
  # max_request_body_size is "always", request bodies won't be trimmed.
54
44
  MAX_DATABAG_DEPTH = 5
@@ -63,6 +53,13 @@ def add_global_repr_processor(processor: ReprProcessor) -> None:
63
53
  global_repr_processors.append(processor)
64
54
 
65
55
 
56
+ sequence_types: list[type] = [Sequence, Set]
57
+
58
+
59
+ def add_repr_sequence_type(ty: type) -> None:
60
+ sequence_types.append(ty)
61
+
62
+
66
63
  class Memo:
67
64
  __slots__ = ("_ids", "_objs")
68
65
 
@@ -318,7 +315,7 @@ def serialize(event: Union[Dict[str, Any], Event], **kwargs: Any) -> Dict[str, A
318
315
  return rv_dict
319
316
 
320
317
  elif not isinstance(obj, serializable_str_types) and isinstance(
321
- obj, (Set, Sequence)
318
+ obj, tuple(sequence_types)
322
319
  ):
323
320
  rv_list = []
324
321
 
sentry_sdk/tracing.py CHANGED
@@ -156,7 +156,7 @@ class Span:
156
156
  name: Optional[str] = None,
157
157
  source: str = TransactionSource.CUSTOM,
158
158
  attributes: Optional[dict[str, Any]] = None,
159
- only_if_parent: bool = False,
159
+ only_as_child_span: bool = False,
160
160
  parent_span: Optional[Span] = None,
161
161
  otel_span: Optional[OtelSpan] = None,
162
162
  span: Optional[Span] = None,
@@ -167,7 +167,7 @@ class Span:
167
167
  If span is passed explicitly, use it. The only purpose of this param
168
168
  is backwards compatibility with start_transaction(transaction=...).
169
169
 
170
- If only_if_parent is True, just return an INVALID_SPAN
170
+ If only_as_child_span is True, just return an INVALID_SPAN
171
171
  and avoid instrumentation if there's no active parent span.
172
172
  """
173
173
  if otel_span is not None:
@@ -176,7 +176,7 @@ class Span:
176
176
  self._otel_span = span._otel_span
177
177
  else:
178
178
  skip_span = False
179
- if only_if_parent and parent_span is None:
179
+ if only_as_child_span and parent_span is None:
180
180
  parent_span_context = get_current_span().get_span_context()
181
181
  skip_span = (
182
182
  not parent_span_context.is_valid or parent_span_context.is_remote
@@ -143,7 +143,7 @@ def record_sql_queries(
143
143
  op=OP.DB,
144
144
  name=query,
145
145
  origin=span_origin,
146
- only_if_parent=True,
146
+ only_as_child_span=True,
147
147
  ) as span:
148
148
  for k, v in data.items():
149
149
  span.set_attribute(k, v)
@@ -710,7 +710,7 @@ def start_child_span_decorator(func: Any) -> Any:
710
710
  with sentry_sdk.start_span(
711
711
  op=OP.FUNCTION,
712
712
  name=qualname_from_function(func),
713
- only_if_parent=True,
713
+ only_as_child_span=True,
714
714
  ):
715
715
  return await func(*args, **kwargs)
716
716
 
@@ -739,7 +739,7 @@ def start_child_span_decorator(func: Any) -> Any:
739
739
  with sentry_sdk.start_span(
740
740
  op=OP.FUNCTION,
741
741
  name=qualname_from_function(func),
742
- only_if_parent=True,
742
+ only_as_child_span=True,
743
743
  ):
744
744
  return func(*args, **kwargs)
745
745
 
sentry_sdk/utils.py CHANGED
@@ -1873,3 +1873,49 @@ def set_thread_info_from_span(
1873
1873
  data[SPANDATA.THREAD_ID] = span.get_attribute(SPANDATA.THREAD_ID)
1874
1874
  if span.get_attribute(SPANDATA.THREAD_NAME) is not None:
1875
1875
  data[SPANDATA.THREAD_NAME] = span.get_attribute(SPANDATA.THREAD_NAME)
1876
+
1877
+
1878
+ def safe_serialize(data: Any) -> str:
1879
+ """Safely serialize to a readable string."""
1880
+
1881
+ def serialize_item(
1882
+ item: Any,
1883
+ ) -> Union[str, dict[Any, Any], list[Any], tuple[Any, ...]]:
1884
+ if callable(item):
1885
+ try:
1886
+ module = getattr(item, "__module__", None)
1887
+ qualname = getattr(item, "__qualname__", None)
1888
+ name = getattr(item, "__name__", "anonymous")
1889
+
1890
+ if module and qualname:
1891
+ full_path = f"{module}.{qualname}"
1892
+ elif module and name:
1893
+ full_path = f"{module}.{name}"
1894
+ else:
1895
+ full_path = name
1896
+
1897
+ return f"<function {full_path}>"
1898
+ except Exception:
1899
+ return f"<callable {type(item).__name__}>"
1900
+ elif isinstance(item, dict):
1901
+ return {k: serialize_item(v) for k, v in item.items()}
1902
+ elif isinstance(item, (list, tuple)):
1903
+ return [serialize_item(x) for x in item]
1904
+ elif hasattr(item, "__dict__"):
1905
+ try:
1906
+ attrs = {
1907
+ k: serialize_item(v)
1908
+ for k, v in vars(item).items()
1909
+ if not k.startswith("_")
1910
+ }
1911
+ return f"<{type(item).__name__} {attrs}>"
1912
+ except Exception:
1913
+ return repr(item)
1914
+ else:
1915
+ return item
1916
+
1917
+ try:
1918
+ serialized = serialize_item(data)
1919
+ return json.dumps(serialized, default=str)
1920
+ except Exception:
1921
+ return str(data)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sentry-sdk
3
- Version: 3.0.0a3
3
+ Version: 3.0.0a4
4
4
  Summary: Python client for Sentry (https://sentry.io)
5
5
  Home-page: https://github.com/getsentry/sentry-python
6
6
  Author: Sentry Team and Contributors