Skip to content

Commit d0cbcc4

Browse files
committed
Merge branch 'master' into feat/span-first
2 parents 7066f69 + 8596f89 commit d0cbcc4

36 files changed

+2710
-300
lines changed

.github/workflows/test-integrations-ai.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,10 @@ jobs:
8686
run: |
8787
set -x # print commands that are executed
8888
./scripts/runtox.sh "py${{ matrix.python-version }}-mcp"
89+
- name: Test fastmcp
90+
run: |
91+
set -x # print commands that are executed
92+
./scripts/runtox.sh "py${{ matrix.python-version }}-fastmcp"
8993
- name: Test openai-base
9094
run: |
9195
set -x # print commands that are executed

CHANGELOG.md

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

3+
## 2.45.0
4+
5+
### Various fixes & improvements
6+
7+
- OTLPIntegration (#4877) by @sl0thentr0py
8+
9+
Enable the new OTLP integration with the code snippet below, and your OpenTelemetry instrumentation will be automatically sent to Sentry's OTLP ingestion endpoint.
10+
11+
```python
12+
import sentry_sdk
13+
from sentry_sdk.integrations.otlp import OTLPIntegration
14+
15+
sentry_sdk.init(
16+
dsn="<your-dsn>",
17+
# Add data like inputs and responses;
18+
# see https://docs.sentry.io/platforms/python/data-management/data-collected/ for more info
19+
send_default_pii=True,
20+
integrations=[
21+
OTLPIntegration(),
22+
],
23+
)
24+
```
25+
26+
Under the hood, this will setup:
27+
- A `SpanExporter` that will automatically set up the OTLP ingestion endpoint from your DSN
28+
- A `Propagator` that ensures Distributed Tracing works
29+
- Trace/Span linking for all other Sentry events such as Errors, Logs, Crons and Metrics
30+
31+
If you were using the `SentrySpanProcessor` before, we recommend migrating over to `OTLPIntegration` since it's a much simpler setup.
32+
33+
- feat(integrations): implement context management for invoke_agent spans (#5089) by @constantinius
34+
- feat(loguru): Capture extra (#5096) by @sentrivana
35+
- feat: Attach `server.address` to metrics (#5113) by @alexander-alderman-webb
36+
- fix: Cast message and detail attributes before appending exception notes (#5114) by @alexander-alderman-webb
37+
- fix(integrations): ensure that GEN_AI_AGENT_NAME is properly set for GEN_AI spans under an invoke_agent span (#5030) by @constantinius
38+
- fix(logs): Update `sentry.origin` (#5112) by @sentrivana
39+
- chore: Deprecate description truncation option for Redis spans (#5073) by @alexander-alderman-webb
40+
- chore: Deprecate `max_spans` LangChain parameter (#5074) by @alexander-alderman-webb
41+
- chore(toxgen): Check availability of pip and add detail to exceptions (#5076) by @alexander-alderman-webb
42+
- chore: add MCP SDK Pydantic AI and OpenAI Agents to the list of auto enabled integrations (#5111) by @constantinius
43+
- test: add tests for either FastMCP implementation (#5075) by @constantinius
44+
- fix(ci): Re-enable skipped tests (#5104) by @sentrivana
45+
- ci: 🤖 Update test matrix with new releases (11/17) (#5110) by @github-actions
46+
- ci: Force coverage core ctrace for 3.14 (#5108) by @sl0thentr0py
47+
348
## 2.44.0
449

550
### Various fixes & improvements

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.44.0"
34+
release = "2.45.0"
3535
version = ".".join(release.split(".")[:2]) # The short X.Y version.
3636

3737

scripts/populate_tox/README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,20 @@ sure we support everything we claim to.
77
This `populate_tox.py` script is responsible for picking reasonable versions to
88
test automatically and generating parts of `tox.ini` to capture this.
99

10+
## Running the script
11+
12+
You require a free-threaded interpreter with pip installed to run the script. With
13+
a recent version of `uv` you can directly run the script with the following
14+
command:
15+
16+
```
17+
uv run --python 3.14t \
18+
--with pip \
19+
--with-requirements scripts/populate_tox/requirements.txt \
20+
--with-editable . \
21+
python scripts/populate_tox/populate_tox.py
22+
```
23+
1024
## How it works
1125

1226
There is a template in this directory called `tox.jinja` which contains a

scripts/populate_tox/config.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@
200200
"package": "langchain",
201201
"integration_name": "langchain",
202202
"deps": {
203-
"*": ["openai", "tiktoken", "langchain-openai"],
203+
"*": ["pytest-asyncio", "openai", "tiktoken", "langchain-openai"],
204204
"<=0.1": ["httpx<0.28.0"],
205205
">=0.3": ["langchain-community"],
206206
">=1.0": ["langchain-classic"],
@@ -213,7 +213,7 @@
213213
"package": "langchain",
214214
"integration_name": "langchain",
215215
"deps": {
216-
"*": ["openai", "langchain-openai"],
216+
"*": ["pytest-asyncio", "openai", "langchain-openai"],
217217
"<=0.1": ["httpx<0.28.0"],
218218
">=0.3": ["langchain-community"],
219219
">=1.0": ["langchain-classic"],
@@ -249,6 +249,12 @@
249249
"*": ["pytest-asyncio"],
250250
},
251251
},
252+
"fastmcp": {
253+
"package": "fastmcp",
254+
"deps": {
255+
"*": ["pytest-asyncio"],
256+
},
257+
},
252258
"openai-base": {
253259
"package": "openai",
254260
"integration_name": "openai",

scripts/populate_tox/package_dependencies.jsonl

Lines changed: 13 additions & 8 deletions
Large diffs are not rendered by default.

scripts/populate_tox/populate_tox.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -891,7 +891,31 @@ def _normalize_package_dependencies(package_dependencies: list[dict]) -> list[di
891891

892892
def _exit_if_not_free_threaded_interpreter():
893893
if "free-threading build" not in sys.version:
894-
raise Exception("Running with a free-threaded interpreter is required.")
894+
exc = Exception("Running with a free-threaded interpreter is required.")
895+
exc.add_note(
896+
"A dry run of pip is used to determine free-threading support of packages."
897+
)
898+
raise exc
899+
900+
901+
def _exit_if_pip_unavailable():
902+
pip_help_return_code = subprocess.run(
903+
[
904+
sys.executable,
905+
"-m",
906+
"pip",
907+
"--help",
908+
],
909+
stdout=subprocess.DEVNULL,
910+
stderr=subprocess.DEVNULL,
911+
).returncode
912+
913+
if pip_help_return_code != 0:
914+
exc = Exception("pip must be available.")
915+
exc.add_note(
916+
"A dry run of pip is used to determine free-threading support of packages."
917+
)
918+
raise exc
895919

896920

897921
def main() -> dict[str, list]:
@@ -901,6 +925,7 @@ def main() -> dict[str, list]:
901925
global MIN_PYTHON_VERSION, MAX_PYTHON_VERSION
902926

903927
_exit_if_not_free_threaded_interpreter()
928+
_exit_if_pip_unavailable()
904929

905930
meta = _fetch_sdk_metadata()
906931
sdk_python_versions = _parse_python_versions_from_classifiers(

scripts/populate_tox/releases.jsonl

Lines changed: 25 additions & 20 deletions
Large diffs are not rendered by default.

scripts/split_tox_gh_actions/split_tox_gh_actions.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@
7979
"langgraph",
8080
"litellm",
8181
"mcp",
82+
"fastmcp",
8283
"openai-base",
8384
"openai-notiktoken",
8485
"openai_agents",

sentry_sdk/client.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,6 +1015,13 @@ def _capture_metric(self, metric):
10151015
metric["attributes"]["sentry.sdk.name"] = SDK_INFO["name"]
10161016
metric["attributes"]["sentry.sdk.version"] = SDK_INFO["version"]
10171017

1018+
server_name = self.options.get("server_name")
1019+
if (
1020+
server_name is not None
1021+
and SPANDATA.SERVER_ADDRESS not in metric["attributes"]
1022+
):
1023+
metric["attributes"][SPANDATA.SERVER_ADDRESS] = server_name
1024+
10181025
environment = self.options.get("environment")
10191026
if environment is not None and "sentry.environment" not in metric["attributes"]:
10201027
metric["attributes"]["sentry.environment"] = environment

0 commit comments

Comments
 (0)