Skip to content

Commit 90c70df

Browse files
committed
Merge remote-tracking branch 'origin/master' into ep/django-tests-asgi-params
2 parents 05ce4f0 + 4899d4f commit 90c70df

50 files changed

Lines changed: 8801 additions & 5873 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ jobs:
115115
uv run coverage combine .coverage-sentry-*
116116
uv run coverage xml
117117
- name: Report coverage and test results
118-
uses: getsentry/codecov-action@66554aa51d8656c657e233a9e98bcb18e95f2c9a # main
118+
uses: getsentry/codecov-action@d90e69cdf071dfbb0430159125321dc09c424d4c # main
119119
with:
120120
token: ${{ secrets.GITHUB_TOKEN }}
121121
files: coverage.xml

CHANGELOG.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,40 @@
11
# Changelog
22

3+
## 2.68.1
4+
5+
### `enable_logs`
6+
7+
- (logs) Don't stop sending auto-collected logs when `enable_logs=True` by @sentrivana in [#7237](https://github.com/getsentry/sentry-python/pull/7237)
8+
9+
If you have `enable_logs` set to `True`, our logging integrations for the standard library logging module as well as Loguru will auto-collect logs and send them to Sentry as Sentry logs by default, preserving old behavior. Turning automatic collection off for a specific integration can still be achieved using the `capture_sentry_logs` integration option.
10+
11+
```python
12+
import sentry_sdk
13+
from sentry_sdk.integrations.logging import LoggingIntegration
14+
from sentry_sdk.integrations.loguru import LoguruIntegration
15+
16+
sentry_sdk.init(
17+
enable_logs=True,
18+
integrations=[
19+
LoggingIntegration(capture_sentry_logs=True),
20+
LoguruIntegration(capture_sentry_logs=False),
21+
],
22+
)
23+
```
24+
25+
Please note that the `enable_logs` option is deprecated and will be removed in the next major release. The `sentry_sdk.logger.X` API now works regardless of it, and auto-collection can be opted into via the `capture_sentry_logs` integration-level options, which are `False` by default, unless you have `enable_logs=True`. We've added this compatibility layer to make the transition to a `enable_logs`-free world easier.
26+
27+
### Bug Fixes 🐛
28+
29+
- (django) Add `failed_request_status_codes` by @mgaligniana in [#7140](https://github.com/getsentry/sentry-python/pull/7140)
30+
- (anthropic) Gate `gen_ai.response.tool_calls` on outputs, not inputs by @ericapisani in [#7207](https://github.com/getsentry/sentry-python/pull/7207)
31+
- (google_genai) Gate streaming `gen_ai.response.tool_calls` on outputs, not inputs by @ericapisani in [#7210](https://github.com/getsentry/sentry-python/pull/7210)
32+
- (langchain) Use `gen_ai.tool.definitions` attribute when data collection is enabled by @ericapisani in [#7204](https://github.com/getsentry/sentry-python/pull/7204)
33+
- (langgraph,huggingface_hub) Gate `gen_ai.response.tool_calls` on outputs, not inputs by @ericapisani in [#7208](https://github.com/getsentry/sentry-python/pull/7208)
34+
- (openai) Gate `gen_ai.response.tool_calls` on outputs, not inputs by @ericapisani in [#7205](https://github.com/getsentry/sentry-python/pull/7205)
35+
- (openai_agents) Gate `gen_ai.response.tool_calls` on outputs, not inputs by @ericapisani in [#7209](https://github.com/getsentry/sentry-python/pull/7209)
36+
37+
338
## 2.68.0
439

540
### Important

docs/conf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
copyright = "2019-{}, Sentry Team and Contributors".format(datetime.now().year)
3232
author = "Sentry Team and Contributors"
3333

34-
release = "2.68.0"
34+
release = "2.68.1"
3535
version = ".".join(release.split(".")[:2]) # The short X.Y version.
3636

3737

scripts/populate_tox/config.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
"anthropic": {
2424
"package": "anthropic",
2525
"deps": {
26-
"*": ["pytest-asyncio"],
26+
"*": ["pytest-asyncio", "httpx"],
2727
"<0.50": ["httpx<0.28.0"],
2828
# tokenizers dropped Python 3.8 support, but didn't update package metadata.
2929
# https://github.com/huggingface/tokenizers/commit/f4c9fd7f402fc794df8f1b547a95ee5305f9fe62
@@ -249,7 +249,7 @@
249249
"package": "langchain",
250250
"integration_name": "langchain",
251251
"deps": {
252-
"*": ["pytest-asyncio", "openai", "tiktoken", "langchain-openai"],
252+
"*": ["pytest-asyncio", "openai", "tiktoken", "langchain-openai", "httpx"],
253253
"<=0.1": ["httpx<0.28.0"],
254254
">=0.3": ["langchain-community"],
255255
">=1.0": ["langchain-classic"],
@@ -263,7 +263,7 @@
263263
"package": "langchain",
264264
"integration_name": "langchain",
265265
"deps": {
266-
"*": ["pytest-asyncio", "openai", "langchain-openai"],
266+
"*": ["pytest-asyncio", "openai", "langchain-openai", "httpx"],
267267
"<=0.1": ["httpx<0.28.0"],
268268
">=0.3": ["langchain-community"],
269269
">=1.0": ["langchain-classic"],
@@ -283,7 +283,7 @@
283283
"litellm": {
284284
"package": "litellm",
285285
"deps": {
286-
"*": ["anthropic", "google-genai", "pytest-asyncio"],
286+
"*": ["anthropic", "google-genai", "pytest-asyncio", "httpx"],
287287
},
288288
"include": "<=1.96", # https://github.com/BerriAI/litellm/issues/36384
289289
},
@@ -323,7 +323,7 @@
323323
"package": "openai",
324324
"integration_name": "openai",
325325
"deps": {
326-
"*": ["pytest-asyncio", "tiktoken"],
326+
"*": ["pytest-asyncio", "tiktoken", "httpx"],
327327
"<1.55": ["httpx<0.28"],
328328
},
329329
"python": {
@@ -335,7 +335,7 @@
335335
"package": "openai",
336336
"integration_name": "openai",
337337
"deps": {
338-
"*": ["pytest-asyncio"],
338+
"*": ["pytest-asyncio", "httpx"],
339339
"<1.55": ["httpx<0.28"],
340340
},
341341
"python": {
@@ -346,7 +346,9 @@
346346
"openai_agents": {
347347
"package": "openai-agents",
348348
"deps": {
349-
"*": ["pytest-asyncio"],
349+
"*": ["pytest-asyncio", "httpx"],
350+
# https://github.com/openai/openai-python/commit/f16fbbd2bd25dc1ff150b5f78dbd15ff6bab6d91 makes `cache_write_tokens` required.
351+
"<=0.18.0": ["openai<2.45"],
350352
},
351353
"python": ">=3.10",
352354
},

scripts/populate_tox/package_dependencies.jsonl

Lines changed: 210 additions & 192 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

scripts/populate_tox/releases.jsonl

Lines changed: 231 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

sentry_sdk/client.py

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -648,13 +648,6 @@ def _record_lost_event(
648648

649649
self.session_flusher = SessionFlusher(capture_func=_capture_envelope)
650650

651-
if self.options.get("enable_logs", False) or self.options[
652-
"_experiments"
653-
].get("enable_logs", False):
654-
logger.warning(
655-
"The enable_logs option has no effect and will be removed in the next major."
656-
)
657-
658651
self.log_batcher = LogBatcher(
659652
capture_func=_capture_envelope,
660653
record_lost_func=_record_lost_event,

sentry_sdk/consts.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1840,4 +1840,4 @@ def _get_default_options() -> "dict[str, Any]":
18401840
del _get_default_options
18411841

18421842

1843-
VERSION = "2.68.0"
1843+
VERSION = "2.68.1"

sentry_sdk/integrations/_wsgi_common.py

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -89,38 +89,47 @@ def extract_into_event(self, event: "Event") -> None:
8989
content_length = self.content_length()
9090
request_info = event.get("request", {})
9191

92+
# Prior to data collection being implemented we unconditionally attached
93+
# the request body, which is why we default to True here.
94+
attach_request_body = True
95+
9296
if has_data_collection_enabled(client.options):
9397
cookies = _apply_key_value_collection_filtering(
9498
items=dict(self.cookies()),
9599
behaviour=client.options["data_collection"]["cookies"],
96100
)
97101
if cookies:
98102
request_info["cookies"] = cookies
103+
104+
attach_request_body = (
105+
"incoming_request" in client.options["data_collection"]["http_bodies"]
106+
)
99107
elif should_send_default_pii():
100108
request_info["cookies"] = dict(self.cookies())
101109

102-
if not request_body_within_bounds(client, content_length):
103-
data = AnnotatedValue.removed_because_over_size_limit()
104-
else:
105-
# First read the raw body data
106-
# It is important to read this first because if it is Django
107-
# it will cache the body and then we can read the cached version
108-
# again in parsed_body() (or json() or wherever).
109-
raw_data = None
110-
try:
111-
raw_data = self.raw_data()
112-
except _RAW_DATA_EXCEPTIONS:
113-
# If DjangoRestFramework is used it already read the body for us
114-
# so reading it here will fail. We can ignore this.
115-
pass
116-
117-
parsed_body = self.parsed_body()
118-
if parsed_body is not None:
119-
data = parsed_body
120-
elif raw_data:
121-
data = AnnotatedValue.removed_because_raw_data()
110+
if attach_request_body:
111+
if not request_body_within_bounds(client, content_length):
112+
data = AnnotatedValue.removed_because_over_size_limit()
122113
else:
123-
data = None
114+
# First read the raw body data
115+
# It is important to read this first because if it is Django
116+
# it will cache the body and then we can read the cached version
117+
# again in parsed_body() (or json() or wherever).
118+
raw_data = None
119+
try:
120+
raw_data = self.raw_data()
121+
except _RAW_DATA_EXCEPTIONS:
122+
# If DjangoRestFramework is used it already read the body for us
123+
# so reading it here will fail. We can ignore this.
124+
pass
125+
126+
parsed_body = self.parsed_body()
127+
if parsed_body is not None:
128+
data = parsed_body
129+
elif raw_data:
130+
data = AnnotatedValue.removed_because_raw_data()
131+
else:
132+
data = None
124133

125134
if data is not None:
126135
request_info["data"] = data

sentry_sdk/integrations/anthropic.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -608,16 +608,13 @@ def _set_output_data(
608608
set_on_span(SPANDATA.GEN_AI_RESPONSE_FINISH_REASONS, [finish_reason])
609609

610610
client = sentry_sdk.get_client()
611-
record_inputs = False
612611
record_outputs = False
613612
if has_data_collection_enabled(client.options):
614-
record_inputs = client.options["data_collection"]["gen_ai"]["inputs"]
615613
record_outputs = client.options["data_collection"]["gen_ai"]["outputs"]
616614
elif should_send_default_pii() and integration.include_prompts:
617-
record_inputs = True
618615
record_outputs = True
619616

620-
if record_inputs or record_outputs:
617+
if record_outputs:
621618
output_messages: "dict[str, list[Any]]" = {
622619
"response": [],
623620
"tool": [],
@@ -629,15 +626,15 @@ def _set_output_data(
629626
elif output["type"] == "tool_use":
630627
output_messages["tool"].append(output)
631628

632-
if record_inputs and len(output_messages["tool"]) > 0:
629+
if len(output_messages["tool"]) > 0:
633630
set_data_normalized(
634631
span,
635632
SPANDATA.GEN_AI_RESPONSE_TOOL_CALLS,
636633
output_messages["tool"],
637634
unpack=False,
638635
)
639636

640-
if record_outputs and len(output_messages["response"]) > 0:
637+
if len(output_messages["response"]) > 0:
641638
set_data_normalized(
642639
span, SPANDATA.GEN_AI_RESPONSE_TEXT, output_messages["response"]
643640
)

0 commit comments

Comments
 (0)