sentry-sdk 2.34.1__py2.py3-none-any.whl → 2.35.0__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.

sentry_sdk/__init__.py CHANGED
@@ -50,6 +50,7 @@ __all__ = [ # noqa
50
50
  "start_session",
51
51
  "end_session",
52
52
  "set_transaction_name",
53
+ "update_current_span",
53
54
  ]
54
55
 
55
56
  # Initialize the debug support after everything is loaded
sentry_sdk/ai/utils.py CHANGED
@@ -7,8 +7,8 @@ from sentry_sdk.tracing import Span
7
7
  from sentry_sdk.utils import logger
8
8
 
9
9
 
10
- def _normalize_data(data):
11
- # type: (Any) -> Any
10
+ def _normalize_data(data, unpack=True):
11
+ # type: (Any, bool) -> Any
12
12
 
13
13
  # convert pydantic data (e.g. OpenAI v1+) to json compatible format
14
14
  if hasattr(data, "model_dump"):
@@ -18,18 +18,18 @@ def _normalize_data(data):
18
18
  logger.warning("Could not convert pydantic data to JSON: %s", e)
19
19
  return data
20
20
  if isinstance(data, list):
21
- if len(data) == 1:
22
- return _normalize_data(data[0]) # remove empty dimensions
23
- return list(_normalize_data(x) for x in data)
21
+ if unpack and len(data) == 1:
22
+ return _normalize_data(data[0], unpack=unpack) # remove empty dimensions
23
+ return list(_normalize_data(x, unpack=unpack) for x in data)
24
24
  if isinstance(data, dict):
25
- return {k: _normalize_data(v) for (k, v) in data.items()}
25
+ return {k: _normalize_data(v, unpack=unpack) for (k, v) in data.items()}
26
26
 
27
27
  return data
28
28
 
29
29
 
30
- def set_data_normalized(span, key, value):
31
- # type: (Span, str, Any) -> None
32
- normalized = _normalize_data(value)
30
+ def set_data_normalized(span, key, value, unpack=True):
31
+ # type: (Span, str, Any, bool) -> None
32
+ normalized = _normalize_data(value, unpack=unpack)
33
33
  if isinstance(normalized, (int, float, bool, str)):
34
34
  span.set_data(key, normalized)
35
35
  else:
sentry_sdk/api.py CHANGED
@@ -85,6 +85,7 @@ __all__ = [
85
85
  "start_session",
86
86
  "end_session",
87
87
  "set_transaction_name",
88
+ "update_current_span",
88
89
  ]
89
90
 
90
91
 
@@ -473,3 +474,82 @@ def end_session():
473
474
  def set_transaction_name(name, source=None):
474
475
  # type: (str, Optional[str]) -> None
475
476
  return get_current_scope().set_transaction_name(name, source)
477
+
478
+
479
+ def update_current_span(op=None, name=None, attributes=None, data=None):
480
+ # type: (Optional[str], Optional[str], Optional[dict[str, Union[str, int, float, bool]]], Optional[dict[str, Any]]) -> None
481
+ """
482
+ Update the current active span with the provided parameters.
483
+
484
+ This function allows you to modify properties of the currently active span.
485
+ If no span is currently active, this function will do nothing.
486
+
487
+ :param op: The operation name for the span. This is a high-level description
488
+ of what the span represents (e.g., "http.client", "db.query").
489
+ You can use predefined constants from :py:class:`sentry_sdk.consts.OP`
490
+ or provide your own string. If not provided, the span's operation will
491
+ remain unchanged.
492
+ :type op: str or None
493
+
494
+ :param name: The human-readable name/description for the span. This provides
495
+ more specific details about what the span represents (e.g., "GET /api/users",
496
+ "SELECT * FROM users"). If not provided, the span's name will remain unchanged.
497
+ :type name: str or None
498
+
499
+ :param data: A dictionary of key-value pairs to add as data to the span. This
500
+ data will be merged with any existing span data. If not provided,
501
+ no data will be added.
502
+
503
+ .. deprecated:: 2.35.0
504
+ Use ``attributes`` instead. The ``data`` parameter will be removed
505
+ in a future version.
506
+ :type data: dict[str, Union[str, int, float, bool]] or None
507
+
508
+ :param attributes: A dictionary of key-value pairs to add as attributes to the span.
509
+ Attribute values must be strings, integers, floats, or booleans. These
510
+ attributes will be merged with any existing span data. If not provided,
511
+ no attributes will be added.
512
+ :type attributes: dict[str, Union[str, int, float, bool]] or None
513
+
514
+ :returns: None
515
+
516
+ .. versionadded:: 2.35.0
517
+
518
+ Example::
519
+
520
+ import sentry_sdk
521
+ from sentry_sdk.consts import OP
522
+
523
+ sentry_sdk.update_current_span(
524
+ op=OP.FUNCTION,
525
+ name="process_user_data",
526
+ attributes={"user_id": 123, "batch_size": 50}
527
+ )
528
+ """
529
+ current_span = get_current_span()
530
+
531
+ if current_span is None:
532
+ return
533
+
534
+ if op is not None:
535
+ current_span.op = op
536
+
537
+ if name is not None:
538
+ # internally it is still description
539
+ current_span.description = name
540
+
541
+ if data is not None and attributes is not None:
542
+ raise ValueError(
543
+ "Cannot provide both `data` and `attributes`. Please use only `attributes`."
544
+ )
545
+
546
+ if data is not None:
547
+ warnings.warn(
548
+ "The `data` parameter is deprecated. Please use `attributes` instead.",
549
+ DeprecationWarning,
550
+ stacklevel=2,
551
+ )
552
+ attributes = data
553
+
554
+ if attributes is not None:
555
+ current_span.update_data(attributes)
sentry_sdk/client.py CHANGED
@@ -23,6 +23,8 @@ from sentry_sdk.utils import (
23
23
  handle_in_app,
24
24
  is_gevent,
25
25
  logger,
26
+ get_before_send_log,
27
+ has_logs_enabled,
26
28
  )
27
29
  from sentry_sdk.serializer import serialize
28
30
  from sentry_sdk.tracing import trace
@@ -382,7 +384,8 @@ class _Client(BaseClient):
382
384
  )
383
385
 
384
386
  self.log_batcher = None
385
- if experiments.get("enable_logs", False):
387
+
388
+ if has_logs_enabled(self.options):
386
389
  from sentry_sdk._log_batcher import LogBatcher
387
390
 
388
391
  self.log_batcher = LogBatcher(capture_func=_capture_envelope)
@@ -898,9 +901,8 @@ class _Client(BaseClient):
898
901
  return return_value
899
902
 
900
903
  def _capture_experimental_log(self, log):
901
- # type: (Log) -> None
902
- logs_enabled = self.options["_experiments"].get("enable_logs", False)
903
- if not logs_enabled:
904
+ # type: (Optional[Log]) -> None
905
+ if not has_logs_enabled(self.options) or log is None:
904
906
  return
905
907
 
906
908
  current_scope = sentry_sdk.get_current_scope()
@@ -955,9 +957,10 @@ class _Client(BaseClient):
955
957
  f'[Sentry Logs] [{log.get("severity_text")}] {log.get("body")}'
956
958
  )
957
959
 
958
- before_send_log = self.options["_experiments"].get("before_send_log")
960
+ before_send_log = get_before_send_log(self.options)
959
961
  if before_send_log is not None:
960
962
  log = before_send_log(log, {})
963
+
961
964
  if log is None:
962
965
  return
963
966
 
sentry_sdk/consts.py CHANGED
@@ -100,6 +100,17 @@ FALSE_VALUES = [
100
100
  ]
101
101
 
102
102
 
103
+ class SPANTEMPLATE(str, Enum):
104
+ DEFAULT = "default"
105
+ AI_AGENT = "ai_agent"
106
+ AI_TOOL = "ai_tool"
107
+ AI_CHAT = "ai_chat"
108
+
109
+ def __str__(self):
110
+ # type: () -> str
111
+ return self.value
112
+
113
+
103
114
  class INSTRUMENTER:
104
115
  SENTRY = "sentry"
105
116
  OTEL = "otel"
@@ -113,71 +124,106 @@ class SPANDATA:
113
124
 
114
125
  AI_CITATIONS = "ai.citations"
115
126
  """
127
+ .. deprecated::
128
+ This attribute is deprecated. Use GEN_AI_* attributes instead.
129
+
116
130
  References or sources cited by the AI model in its response.
117
131
  Example: ["Smith et al. 2020", "Jones 2019"]
118
132
  """
119
133
 
120
134
  AI_DOCUMENTS = "ai.documents"
121
135
  """
136
+ .. deprecated::
137
+ This attribute is deprecated. Use GEN_AI_* attributes instead.
138
+
122
139
  Documents or content chunks used as context for the AI model.
123
140
  Example: ["doc1.txt", "doc2.pdf"]
124
141
  """
125
142
 
126
143
  AI_FINISH_REASON = "ai.finish_reason"
127
144
  """
145
+ .. deprecated::
146
+ This attribute is deprecated. Use GEN_AI_RESPONSE_FINISH_REASONS instead.
147
+
128
148
  The reason why the model stopped generating.
129
149
  Example: "length"
130
150
  """
131
151
 
132
152
  AI_FREQUENCY_PENALTY = "ai.frequency_penalty"
133
153
  """
154
+ .. deprecated::
155
+ This attribute is deprecated. Use GEN_AI_REQUEST_FREQUENCY_PENALTY instead.
156
+
134
157
  Used to reduce repetitiveness of generated tokens.
135
158
  Example: 0.5
136
159
  """
137
160
 
138
161
  AI_FUNCTION_CALL = "ai.function_call"
139
162
  """
163
+ .. deprecated::
164
+ This attribute is deprecated. Use GEN_AI_RESPONSE_TOOL_CALLS instead.
165
+
140
166
  For an AI model call, the function that was called. This is deprecated for OpenAI, and replaced by tool_calls
141
167
  """
142
168
 
143
169
  AI_GENERATION_ID = "ai.generation_id"
144
170
  """
171
+ .. deprecated::
172
+ This attribute is deprecated. Use GEN_AI_RESPONSE_ID instead.
173
+
145
174
  Unique identifier for the completion.
146
175
  Example: "gen_123abc"
147
176
  """
148
177
 
149
178
  AI_INPUT_MESSAGES = "ai.input_messages"
150
179
  """
180
+ .. deprecated::
181
+ This attribute is deprecated. Use GEN_AI_REQUEST_MESSAGES instead.
182
+
151
183
  The input messages to an LLM call.
152
184
  Example: [{"role": "user", "message": "hello"}]
153
185
  """
154
186
 
155
187
  AI_LOGIT_BIAS = "ai.logit_bias"
156
188
  """
189
+ .. deprecated::
190
+ This attribute is deprecated. Use GEN_AI_* attributes instead.
191
+
157
192
  For an AI model call, the logit bias
158
193
  """
159
194
 
160
195
  AI_METADATA = "ai.metadata"
161
196
  """
197
+ .. deprecated::
198
+ This attribute is deprecated. Use GEN_AI_* attributes instead.
199
+
162
200
  Extra metadata passed to an AI pipeline step.
163
201
  Example: {"executed_function": "add_integers"}
164
202
  """
165
203
 
166
204
  AI_MODEL_ID = "ai.model_id"
167
205
  """
168
- The unique descriptor of the model being execugted
206
+ .. deprecated::
207
+ This attribute is deprecated. Use GEN_AI_REQUEST_MODEL or GEN_AI_RESPONSE_MODEL instead.
208
+
209
+ The unique descriptor of the model being executed.
169
210
  Example: gpt-4
170
211
  """
171
212
 
172
213
  AI_PIPELINE_NAME = "ai.pipeline.name"
173
214
  """
215
+ .. deprecated::
216
+ This attribute is deprecated. Use GEN_AI_PIPELINE_NAME instead.
217
+
174
218
  Name of the AI pipeline or chain being executed.
175
- DEPRECATED: Use GEN_AI_PIPELINE_NAME instead.
176
219
  Example: "qa-pipeline"
177
220
  """
178
221
 
179
222
  AI_PREAMBLE = "ai.preamble"
180
223
  """
224
+ .. deprecated::
225
+ This attribute is deprecated. Use GEN_AI_* attributes instead.
226
+
181
227
  For an AI model call, the preamble parameter.
182
228
  Preambles are a part of the prompt used to adjust the model's overall behavior and conversation style.
183
229
  Example: "You are now a clown."
@@ -185,100 +231,150 @@ class SPANDATA:
185
231
 
186
232
  AI_PRESENCE_PENALTY = "ai.presence_penalty"
187
233
  """
234
+ .. deprecated::
235
+ This attribute is deprecated. Use GEN_AI_REQUEST_PRESENCE_PENALTY instead.
236
+
188
237
  Used to reduce repetitiveness of generated tokens.
189
238
  Example: 0.5
190
239
  """
191
240
 
192
241
  AI_RAW_PROMPTING = "ai.raw_prompting"
193
242
  """
243
+ .. deprecated::
244
+ This attribute is deprecated. Use GEN_AI_* attributes instead.
245
+
194
246
  Minimize pre-processing done to the prompt sent to the LLM.
195
247
  Example: true
196
248
  """
197
249
 
198
250
  AI_RESPONSE_FORMAT = "ai.response_format"
199
251
  """
252
+ .. deprecated::
253
+ This attribute is deprecated. Use GEN_AI_* attributes instead.
254
+
200
255
  For an AI model call, the format of the response
201
256
  """
202
257
 
203
258
  AI_RESPONSES = "ai.responses"
204
259
  """
260
+ .. deprecated::
261
+ This attribute is deprecated. Use GEN_AI_RESPONSE_TEXT instead.
262
+
205
263
  The responses to an AI model call. Always as a list.
206
264
  Example: ["hello", "world"]
207
265
  """
208
266
 
209
267
  AI_SEARCH_QUERIES = "ai.search_queries"
210
268
  """
269
+ .. deprecated::
270
+ This attribute is deprecated. Use GEN_AI_* attributes instead.
271
+
211
272
  Queries used to search for relevant context or documents.
212
273
  Example: ["climate change effects", "renewable energy"]
213
274
  """
214
275
 
215
276
  AI_SEARCH_REQUIRED = "ai.is_search_required"
216
277
  """
278
+ .. deprecated::
279
+ This attribute is deprecated. Use GEN_AI_* attributes instead.
280
+
217
281
  Boolean indicating if the model needs to perform a search.
218
282
  Example: true
219
283
  """
220
284
 
221
285
  AI_SEARCH_RESULTS = "ai.search_results"
222
286
  """
287
+ .. deprecated::
288
+ This attribute is deprecated. Use GEN_AI_* attributes instead.
289
+
223
290
  Results returned from search queries for context.
224
291
  Example: ["Result 1", "Result 2"]
225
292
  """
226
293
 
227
294
  AI_SEED = "ai.seed"
228
295
  """
296
+ .. deprecated::
297
+ This attribute is deprecated. Use GEN_AI_REQUEST_SEED instead.
298
+
229
299
  The seed, ideally models given the same seed and same other parameters will produce the exact same output.
230
300
  Example: 123.45
231
301
  """
232
302
 
233
303
  AI_STREAMING = "ai.streaming"
234
304
  """
305
+ .. deprecated::
306
+ This attribute is deprecated. Use GEN_AI_RESPONSE_STREAMING instead.
307
+
235
308
  Whether or not the AI model call's response was streamed back asynchronously
236
- DEPRECATED: Use GEN_AI_RESPONSE_STREAMING instead.
237
309
  Example: true
238
310
  """
239
311
 
240
312
  AI_TAGS = "ai.tags"
241
313
  """
314
+ .. deprecated::
315
+ This attribute is deprecated. Use GEN_AI_* attributes instead.
316
+
242
317
  Tags that describe an AI pipeline step.
243
318
  Example: {"executed_function": "add_integers"}
244
319
  """
245
320
 
246
321
  AI_TEMPERATURE = "ai.temperature"
247
322
  """
323
+ .. deprecated::
324
+ This attribute is deprecated. Use GEN_AI_REQUEST_TEMPERATURE instead.
325
+
248
326
  For an AI model call, the temperature parameter. Temperature essentially means how random the output will be.
249
327
  Example: 0.5
250
328
  """
251
329
 
252
330
  AI_TEXTS = "ai.texts"
253
331
  """
332
+ .. deprecated::
333
+ This attribute is deprecated. Use GEN_AI_* attributes instead.
334
+
254
335
  Raw text inputs provided to the model.
255
336
  Example: ["What is machine learning?"]
256
337
  """
257
338
 
258
339
  AI_TOP_K = "ai.top_k"
259
340
  """
341
+ .. deprecated::
342
+ This attribute is deprecated. Use GEN_AI_REQUEST_TOP_K instead.
343
+
260
344
  For an AI model call, the top_k parameter. Top_k essentially controls how random the output will be.
261
345
  Example: 35
262
346
  """
263
347
 
264
348
  AI_TOP_P = "ai.top_p"
265
349
  """
350
+ .. deprecated::
351
+ This attribute is deprecated. Use GEN_AI_REQUEST_TOP_P instead.
352
+
266
353
  For an AI model call, the top_p parameter. Top_p essentially controls how random the output will be.
267
354
  Example: 0.5
268
355
  """
269
356
 
270
357
  AI_TOOL_CALLS = "ai.tool_calls"
271
358
  """
359
+ .. deprecated::
360
+ This attribute is deprecated. Use GEN_AI_RESPONSE_TOOL_CALLS instead.
361
+
272
362
  For an AI model call, the function that was called. This is deprecated for OpenAI, and replaced by tool_calls
273
363
  """
274
364
 
275
365
  AI_TOOLS = "ai.tools"
276
366
  """
367
+ .. deprecated::
368
+ This attribute is deprecated. Use GEN_AI_REQUEST_AVAILABLE_TOOLS instead.
369
+
277
370
  For an AI model call, the functions that are available
278
371
  """
279
372
 
280
373
  AI_WARNINGS = "ai.warnings"
281
374
  """
375
+ .. deprecated::
376
+ This attribute is deprecated. Use GEN_AI_* attributes instead.
377
+
282
378
  Warning messages generated during model execution.
283
379
  Example: ["Token limit exceeded"]
284
380
  """
@@ -383,6 +479,18 @@ class SPANDATA:
383
479
  Example: "qa-pipeline"
384
480
  """
385
481
 
482
+ GEN_AI_RESPONSE_FINISH_REASONS = "gen_ai.response.finish_reasons"
483
+ """
484
+ The reason why the model stopped generating.
485
+ Example: "COMPLETE"
486
+ """
487
+
488
+ GEN_AI_RESPONSE_ID = "gen_ai.response.id"
489
+ """
490
+ Unique identifier for the completion.
491
+ Example: "gen_123abc"
492
+ """
493
+
386
494
  GEN_AI_RESPONSE_MODEL = "gen_ai.response.model"
387
495
  """
388
496
  Exact model identifier used to generate the response
@@ -443,12 +551,24 @@ class SPANDATA:
443
551
  Example: 0.1
444
552
  """
445
553
 
554
+ GEN_AI_REQUEST_SEED = "gen_ai.request.seed"
555
+ """
556
+ The seed, ideally models given the same seed and same other parameters will produce the exact same output.
557
+ Example: "1234567890"
558
+ """
559
+
446
560
  GEN_AI_REQUEST_TEMPERATURE = "gen_ai.request.temperature"
447
561
  """
448
562
  The temperature parameter used to control randomness in the output.
449
563
  Example: 0.7
450
564
  """
451
565
 
566
+ GEN_AI_REQUEST_TOP_K = "gen_ai.request.top_k"
567
+ """
568
+ Limits the model to only consider the K most likely next tokens, where K is an integer (e.g., top_k=20 means only the 20 highest probability tokens are considered).
569
+ Example: 35
570
+ """
571
+
452
572
  GEN_AI_REQUEST_TOP_P = "gen_ai.request.top_p"
453
573
  """
454
574
  The top_p parameter used to control diversity via nucleus sampling.
@@ -675,6 +795,7 @@ class OP:
675
795
  GEN_AI_EMBEDDINGS = "gen_ai.embeddings"
676
796
  GEN_AI_EXECUTE_TOOL = "gen_ai.execute_tool"
677
797
  GEN_AI_HANDOFF = "gen_ai.handoff"
798
+ GEN_AI_PIPELINE = "gen_ai.pipeline"
678
799
  GEN_AI_INVOKE_AGENT = "gen_ai.invoke_agent"
679
800
  GEN_AI_RESPONSES = "gen_ai.responses"
680
801
  GRAPHQL_EXECUTE = "graphql.execute"
@@ -702,11 +823,6 @@ class OP:
702
823
  HUGGINGFACE_HUB_CHAT_COMPLETIONS_CREATE = (
703
824
  "ai.chat_completions.create.huggingface_hub"
704
825
  )
705
- LANGCHAIN_PIPELINE = "ai.pipeline.langchain"
706
- LANGCHAIN_RUN = "ai.run.langchain"
707
- LANGCHAIN_TOOL = "ai.tool.langchain"
708
- LANGCHAIN_AGENT = "ai.agent.langchain"
709
- LANGCHAIN_CHAT_COMPLETIONS_CREATE = "ai.chat_completions.create.langchain"
710
826
  QUEUE_PROCESS = "queue.process"
711
827
  QUEUE_PUBLISH = "queue.publish"
712
828
  QUEUE_SUBMIT_ARQ = "queue.submit.arq"
@@ -798,6 +914,8 @@ class ClientConstructor:
798
914
  custom_repr=None, # type: Optional[Callable[..., Optional[str]]]
799
915
  add_full_stack=DEFAULT_ADD_FULL_STACK, # type: bool
800
916
  max_stack_frames=DEFAULT_MAX_STACK_FRAMES, # type: Optional[int]
917
+ enable_logs=False, # type: bool
918
+ before_send_log=None, # type: Optional[Callable[[Log, Hint], Optional[Log]]]
801
919
  ):
802
920
  # type: (...) -> None
803
921
  """Initialize the Sentry SDK with the given parameters. All parameters described here can be used in a call to `sentry_sdk.init()`.
@@ -1168,7 +1286,6 @@ class ClientConstructor:
1168
1286
 
1169
1287
  :param profile_session_sample_rate:
1170
1288
 
1171
-
1172
1289
  :param enable_tracing:
1173
1290
 
1174
1291
  :param propagate_traces:
@@ -1179,6 +1296,14 @@ class ClientConstructor:
1179
1296
 
1180
1297
  :param instrumenter:
1181
1298
 
1299
+ :param enable_logs: Set `enable_logs` to True to enable the SDK to emit
1300
+ Sentry logs. Defaults to False.
1301
+
1302
+ :param before_send_log: An optional function to modify or filter out logs
1303
+ before they're sent to Sentry. Any modifications to the log in this
1304
+ function will be retained. If the function returns None, the log will
1305
+ not be sent to Sentry.
1306
+
1182
1307
  :param _experiments:
1183
1308
  """
1184
1309
  pass
@@ -1204,4 +1329,4 @@ DEFAULT_OPTIONS = _get_default_options()
1204
1329
  del _get_default_options
1205
1330
 
1206
1331
 
1207
- VERSION = "2.34.1"
1332
+ VERSION = "2.35.0"
sentry_sdk/crons/api.py CHANGED
@@ -1,6 +1,7 @@
1
1
  import uuid
2
2
 
3
3
  import sentry_sdk
4
+ from sentry_sdk.utils import logger
4
5
 
5
6
  from typing import TYPE_CHECKING
6
7
 
@@ -54,4 +55,8 @@ def capture_checkin(
54
55
 
55
56
  sentry_sdk.capture_event(check_in_event)
56
57
 
58
+ logger.debug(
59
+ f"[Crons] Captured check-in ({check_in_event.get('check_in_id')}): {check_in_event.get('monitor_slug')} -> {check_in_event.get('status')}"
60
+ )
61
+
57
62
  return check_in_event["check_in_id"]