From 10b2fb436cface53e18e7067afcade32dc5130b7 Mon Sep 17 00:00:00 2001 From: etserend Date: Thu, 9 Jul 2026 12:14:07 -0500 Subject: [PATCH] feat(export): expose include_code_metric_metadata on export_records (HYBIM-788) Port upstream commit e42a569 from rungalileo/galileo-python. Co-Authored-By: Claude Opus 4.7 --- src/splunk_ao/export.py | 10 +++++++- .../models/log_records_export_request.py | 11 +++++++++ tests/test_export.py | 24 +++++++++++++++++++ 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/src/splunk_ao/export.py b/src/splunk_ao/export.py index 01e6c57..dc9be26 100644 --- a/src/splunk_ao/export.py +++ b/src/splunk_ao/export.py @@ -40,6 +40,7 @@ def records( experiment_id: str | None = None, column_ids: list[str] | None = None, redact: bool = True, + include_code_metric_metadata: bool = False, ) -> Iterator[dict[str, Any]]: if filters is None: filters = [] @@ -56,6 +57,7 @@ def records( column_ids=column_ids, sort=sort, redact=redact, + include_code_metric_metadata=include_code_metric_metadata, ), ) @@ -78,8 +80,9 @@ def export_records( experiment_id: str | None = None, column_ids: list[str] | None = None, redact: bool = True, + include_code_metric_metadata: bool = False, ) -> Iterator[dict[str, Any]]: - """Exports records from a Galileo project. + """Exports records from a Splunk AO project. Defaults to the first logstream if `log_stream_id` and `experiment_id` are not provided. @@ -103,6 +106,10 @@ def export_records( A sort clause to order the exported records. redact Redact sensitive data from the response. + include_code_metric_metadata + If True, include per-row scorer metadata (the dict returned alongside the score by + code-based scorers via the (score, metadata) tuple-return contract) on each + MetricSuccess in the export. Off by default to keep payloads small. Returns ------- @@ -132,4 +139,5 @@ def export_records( column_ids=column_ids, sort=sort, redact=redact, + include_code_metric_metadata=include_code_metric_metadata, ) diff --git a/src/splunk_ao/resources/models/log_records_export_request.py b/src/splunk_ao/resources/models/log_records_export_request.py index 8d3b7cb..930669d 100644 --- a/src/splunk_ao/resources/models/log_records_export_request.py +++ b/src/splunk_ao/resources/models/log_records_export_request.py @@ -44,6 +44,9 @@ class LogRecordsExportRequest: 'LogRecordsTextFilter']]]): Filters to apply on the export sort (Union['LogRecordsSortClause', None, Unset]): Sort clause for the export. Defaults to native sort (created_at, id descending). + include_code_metric_metadata (Union[Unset, bool]): If True, include per-row scorer metadata (the dict + returned alongside the score by code-based scorers via the (score, metadata) tuple-return contract) on + each MetricSuccess in the export. Default: False. """ root_type: RootType @@ -69,6 +72,7 @@ class LogRecordsExportRequest: ] ) = UNSET sort: Union["LogRecordsSortClause", None, Unset] = UNSET + include_code_metric_metadata: Unset | bool = False additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: @@ -136,6 +140,8 @@ def to_dict(self) -> dict[str, Any]: else: sort = self.sort + include_code_metric_metadata = self.include_code_metric_metadata + field_dict: dict[str, Any] = {} field_dict.update(self.additional_properties) field_dict.update({"root_type": root_type}) @@ -157,6 +163,8 @@ def to_dict(self) -> dict[str, Any]: field_dict["filters"] = filters if sort is not UNSET: field_dict["sort"] = sort + if include_code_metric_metadata is not UNSET: + field_dict["include_code_metric_metadata"] = include_code_metric_metadata return field_dict @@ -313,6 +321,8 @@ def _parse_sort(data: object) -> Union["LogRecordsSortClause", None, Unset]: sort = _parse_sort(d.pop("sort", UNSET)) + include_code_metric_metadata = d.pop("include_code_metric_metadata", UNSET) + log_records_export_request = cls( root_type=root_type, column_ids=column_ids, @@ -324,6 +334,7 @@ def _parse_sort(data: object) -> Union["LogRecordsSortClause", None, Unset]: metrics_testing_id=metrics_testing_id, filters=filters, sort=sort, + include_code_metric_metadata=include_code_metric_metadata, ) log_records_export_request.additional_properties = d diff --git a/tests/test_export.py b/tests/test_export.py index 32a4546..c863e67 100644 --- a/tests/test_export.py +++ b/tests/test_export.py @@ -272,3 +272,27 @@ def test_export_records_redact(mock_export_records_stream, redact_param): mock_export_records_stream.assert_called_once() request_body = mock_export_records_stream.call_args.kwargs["body"] assert request_body.redact == redact_param + + +@patch("splunk_ao.export.export_records_stream") +def test_export_records_include_code_metric_metadata_default(mock_export_records_stream): + project_id = str(uuid4()) + mock_export_records_stream.return_value = iter([]) + + list(export_records(project_id=project_id, log_stream_id=str(uuid4()))) + + request_body = mock_export_records_stream.call_args.kwargs["body"] + assert request_body.include_code_metric_metadata is False + assert request_body.to_dict()["include_code_metric_metadata"] is False + + +@patch("splunk_ao.export.export_records_stream") +def test_export_records_include_code_metric_metadata_opt_in(mock_export_records_stream): + project_id = str(uuid4()) + mock_export_records_stream.return_value = iter([]) + + list(export_records(project_id=project_id, log_stream_id=str(uuid4()), include_code_metric_metadata=True)) + + request_body = mock_export_records_stream.call_args.kwargs["body"] + assert request_body.include_code_metric_metadata is True + assert request_body.to_dict()["include_code_metric_metadata"] is True