Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions sentry_sdk/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"push_scope",
"remove_attribute",
"set_attribute",
"set_attributes",
"set_context",
"set_extra",
"set_level",
Expand Down
16 changes: 14 additions & 2 deletions sentry_sdk/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ def overload(x: "T") -> "T":
"push_scope",
"remove_attribute",
"set_attribute",
"set_attributes",
Comment thread
sentrivana marked this conversation as resolved.
"set_context",
"set_extra",
"set_level",
Expand Down Expand Up @@ -298,12 +299,23 @@ def set_attribute(attribute: str, value: "Any") -> None:
"""
Set an attribute.

Any attributes-based telemetry (logs, metrics) captured in this scope will
include this attribute.
Any attributes-based telemetry (logs, metrics, streamed spans) captured in
this scope will include this attribute.
"""
return get_isolation_scope().set_attribute(attribute, value)


@scopemethod
def set_attributes(attributes: "dict[str, Any]") -> None:
Comment thread
sentrivana marked this conversation as resolved.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The type on set_attribute() is broader then Scope.set_attribute() as well

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yup just mirrored set_attribute here

"""
Set multiple attributes.

Any attributes-based telemetry (logs, metrics, streamed spans) captured in
this scope will include these attributes.
"""
return get_isolation_scope().set_attributes(attributes)


@scopemethod
def remove_attribute(attribute: str) -> None:
"""
Expand Down
14 changes: 12 additions & 2 deletions sentry_sdk/scope.py
Original file line number Diff line number Diff line change
Expand Up @@ -2027,11 +2027,21 @@ def set_attribute(self, attribute: str, value: "AttributeValue") -> None:
"""
Set an attribute on the scope.

Any attributes-based telemetry (logs, metrics) captured while this scope
is active will inherit attributes set on the scope.
Any attributes-based telemetry (logs, metrics, streamed spans) captured
while this scope is active will inherit attributes set on the scope.
"""
self._attributes[attribute] = format_attribute(value)

def set_attributes(self, attributes: "dict[str, AttributeValue]") -> None:
"""
Set multiple attributes on the scope.

Any attributes-based telemetry (logs, metrics, streamed spans) captured
while this scope is active will inherit attributes set on the scope.
"""
for attribute, value in attributes.items():
self.set_attribute(attribute, value)

def remove_attribute(self, attribute: str) -> None:
"""Remove an attribute if set on the scope. No-op if there is no such attribute."""
try:
Expand Down
11 changes: 11 additions & 0 deletions tests/test_attributes.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,16 @@ def test_top_level_api(sentry_init, capture_items):
items = capture_items("trace_metric")

sentry_sdk.set_attribute("set", "value")
sentry_sdk.set_attributes(
{
"set1": "value1",
"set2": "value2",
"discarded": 47,
}
)
sentry_sdk.set_attribute("removed", "value")
sentry_sdk.remove_attribute("removed")
sentry_sdk.remove_attribute("discarded")
# Attempting to remove a nonexistent attribute should not raise
sentry_sdk.remove_attribute("nonexistent")

Expand All @@ -19,7 +27,10 @@ def test_top_level_api(sentry_init, capture_items):
(metric,) = metrics

assert metric["attributes"]["set"] == "value"
assert metric["attributes"]["set1"] == "value1"
assert metric["attributes"]["set2"] == "value2"
assert "removed" not in metric["attributes"]
assert "discarded" not in metric["attributes"]


def test_scope_precedence(sentry_init, capture_items):
Expand Down
Loading