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
24 changes: 18 additions & 6 deletions src/sentry/seer/explorer/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,24 @@ def execute_trace_query_chart(
)
data = resp.data

# Normalize response format: single-axis returns flat format, multi-axis returns nested
# We always want the nested format {"metric": {"data": [...]}}
if isinstance(data, dict) and "data" in data and len(y_axes) == 1:
# Single axis response - wrap it
metric_name = y_axes[0]
return {metric_name: data}
# Always normalize to the nested {"metric": {"data": [...]}} format for consistency
metric_is_single = len(y_axes) == 1
metric_name = y_axes[0] if metric_is_single else None
if metric_name and metric_is_single:
# Handle grouped data with single metric: wrap each group's data in the metric name
if group_by:
return {
group_value: (
{metric_name: group_data}
if isinstance(group_data, dict) and "data" in group_data
else group_data
)
for group_value, group_data in data.items()
}

# Handle non-grouped data with single metric: wrap data in the metric name
if isinstance(data, dict) and "data" in data:
return {metric_name: data}

return data

Expand Down
16 changes: 13 additions & 3 deletions tests/sentry/seer/explorer/test_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -258,10 +258,20 @@ def test_execute_trace_query_chart_with_groupby(self):
# Should have different span.op values like "db", "http.client", etc.
assert len(result) > 0

# Each group should have the metric
# Each group should have the metric wrapped in normalized format
# Format: {"group_value": {"count()": {"data": [...]}}}
for group_value, metrics in result.items():
if isinstance(metrics, dict) and "count()" in metrics:
assert "data" in metrics["count()"]
assert isinstance(
metrics, dict
), f"Expected dict for {group_value}, got {type(metrics)}"
assert (
"count()" in metrics
), f"Missing count() in metrics for {group_value}: {metrics.keys()}"
assert "data" in metrics["count()"], f"Missing data in count() for {group_value}"

# Verify we can get actual count data
data_points = metrics["count()"]["data"]
assert isinstance(data_points, list)

def test_execute_trace_query_table_with_groupby(self):
"""Test table query with group_by for aggregates mode"""
Expand Down
Loading