feat(export): expose include_code_metric_metadata on export_records (HYBIM-788)#73
Conversation
…HYBIM-788) Port upstream commit e42a569 from rungalileo/galileo-python. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
fercor-cisco
left a comment
There was a problem hiding this comment.
🤖 This review was generated by the Astra agent (claude-opus-4-8). It may contain mistakes.
Verdict: request_changes — New field was hand-added to generated code without updating openapi.yaml, so it will be silently dropped on the next client regen and break export_records; the author's two blocking Jira questions are also unresolved.
General Comments
- 🟠 major (bug):
src/splunk_ao/resources/models/log_records_export_request.pyis generated code.scripts/auto-generate-api-client.shbacks up, deletes, and fully regenerates the entireresources/directory fromopenapi.yamlwith--overwrite, and theLogRecordsExportRequestschema inopenapi.yaml(lines 28475-28555) was NOT updated to addinclude_code_metric_metadata. Consequences on the next regen (HYBIM-853, the 0.29.0 regen the author flagged in the ticket is already pending):
- The manual
include_code_metric_metadatafield is dropped from the regenerated model. export.pystill passesinclude_code_metric_metadata=...into theLogRecordsExportRequest(...)constructor (lines 60 and 142), which will then raiseTypeError: __init__() got an unexpected keyword argument, breakingexport_records()entirely.
The repo already has an established pattern for regen-surviving patches (patch_http_validation_error.py, wired in as a post-generation step). This change uses no such mechanism. Please add the property to the LogRecordsExportRequest schema in openapi.yaml (mirroring the redact entry, with default: false) so it survives regeneration — or, if the intent is to wait for HYBIM-853, coordinate as the author's own ticket question #1 asks before merging. This is the same concern the author raised in HYBIM-788 and it appears to be unanswered.
- 🟡 minor (question): The new field defaults to
Falserather thanUNSET, soto_dict()always emitsinclude_code_metric_metadata: falseon every export request (unlike optional fields such asfilters/sortwhich are omitted when unset). This matches upstream and mirrorsredact(also default-non-UNSET), but the author explicitly asked in HYBIM-788 whether always sending this field is intended on the backend side, and whether the backend even accepts the field yet. That question is unresolved, and the field is not part of the API contract inopenapi.yaml. Please confirm the backend accepts (and does not reject) an unknown/extra field before this ships.
Follow-ups
Suggested follow-up work that could be tracked as Shortcut stories:
src/splunk_ao/resources/models/log_records_export_request.py:324-337: Round-trip asymmetry:from_dictdefaultsinclude_code_metric_metadatatoUNSETwhen the key is absent, while the constructor/__init__default isFalse. So deserializing a payload lacking the key yieldsUNSET, notFalse. This is consistent with how openapi-python-client generates other fields and is harmless here, but worth noting if the field is ever added to the spec with a non-UNSET default (regen would produced.pop(..., False)instead).
| ] | ||
| ) = UNSET | ||
| sort: Union["LogRecordsSortClause", None, Unset] = UNSET | ||
| include_code_metric_metadata: Unset | bool = False |
There was a problem hiding this comment.
🟠 major (bug): This field was manually added to a file generated by openapi-python-client, but the corresponding property is missing from the LogRecordsExportRequest schema in openapi.yaml. Running scripts/auto-generate-api-client.sh will regenerate this file and silently drop the field, after which the constructor calls in export.py (include_code_metric_metadata=...) will raise TypeError. Add the property to openapi.yaml so the codegen output includes it.
🤖 Generated by the Astra agent
fercor-cisco
left a comment
There was a problem hiding this comment.
@etserend were the changes to src/splunk_ao/resources/models/log_records_export_request.py done manually or via the source code generation script?
If they were done manually, they would be lost in the next regeneration.
…est in openapi.yaml The field was hand-added to the generated model (mirroring upstream e42a569) but missing from the schema, so it would be silently dropped on the next regen (HYBIM-853). Adding it here mirrors the redact entry (type: boolean, default: false) and ensures the field survives regeneration. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
0bb77aa to
64b29da
Compare
Yes, manually — same as upstream e42a569 (they also hand-patched without updating openapi.yaml). |
fercor-cisco
left a comment
There was a problem hiding this comment.
🤖 This review was generated by the Astra agent (claude-opus-4-8). It may contain mistakes.
Verdict: approve — Correct, well-tested param plumbing; the prior openapi.yaml concern is resolved. One non-blocking coverage gap in sibling wrappers.
General Comments
- 🟡 minor (design): This PR exposes
include_code_metric_metadataon the module-levelexport_records()andExportClient.records(), but the two sibling convenience wrappers —LogStream.export_records()(src/splunk_ao/log_stream.py:747) andExperiment.export_records()(src/splunk_ao/experiment.py:1374) — also delegate toExportClient().records()and forwardredactyet do not expose or forward the new parameter. As a result, users of those higher-level APIs silently getinclude_code_metric_metadata=Falsewith no way to opt in. If this is intentional for this port (commit 1 of 3), consider a short note; otherwise forwarding the param through both wrappers would keep the feature symmetric withredact.
Follow-ups
Suggested follow-up work that could be tracked as Shortcut stories:
src/splunk_ao/log_stream.py:747-817: Consider forwardinginclude_code_metric_metadatathroughLogStream.export_records()andExperiment.export_records()(experiment.py:1374) so all three export entry points expose the new feature consistently, matching howredactis handled.
Verified: this asymmetry is inherited from upstream I checked the source commit against the two wrappers:
So the Keeping it as-is preserves fidelity with the port (commit 1 of 3). If upstream later closes this gap, it would come through in a subsequent ported commit. Leaving this note here to document that the divergence is intentional rather than an oversight. |
Port verification vs. upstream
|
| Change | Source (galileo) |
PR (splunk_ao) |
Match |
|---|---|---|---|
records() gets include_code_metric_metadata: bool = False param |
✔ | ✔ | ✅ |
| Threaded into request body construction | ✔ | ✔ | ✅ |
export_records() param + docstring section |
✔ | ✔ | ✅ |
LogRecordsExportRequest model: field decl, to_dict(), from_dict() |
✔ (11 lines) | ✔ (identical 11 lines) | ✅ |
2 tests (default-False, opt-in-True) |
✔ | ✔ | ✅ |
Refactoring/renaming correctly applied
galileo.export.export_records_stream→splunk_ao.export.export_records_streamin the@patchdecorators ✅- Docstring
"Exports records from a Galileo project."→"...from a Splunk AO project."✅ (this is the extra 9 additions/1 deletion vs. the source's 8 additions — an intentional, correct namespace fix) ExportClient.recordsstructure preserved (line 19/32) ✅
One legitimate addition beyond the source commit
The PR adds an openapi.yaml change (5 lines) that the upstream commit did not have. This is expected: in galileo-python that model is codegen'd from a separate spec, whereas splunk-ao-python vendors openapi.yaml in-repo. I confirmed it's placed under the correct schema (LogRecordsExportRequest, line 28475), adjacent to redact, with matching default: false and a description consistent with the code. This is a correct adaptation, not a discrepancy.
Summary
Port of upstream commit
e42a569fromrungalileo/galileo-python(#587) — first commit in the HYBIM-788 migration, applied in chronological order.include_code_metric_metadata: bool = Falseparam toExportClient.records()and module-levelexport_records()True, includes per-row scorer metadata (the dict returned by code-based scorers via the(score, metadata)tuple-return contract) on eachMetricSuccessin the export — off by default to keep payloads smallLogRecordsExportRequestmodel (log_records_export_request.py) to carry the new field throughto_dict()/from_dict()Falseand opt-in-TrueNamespace translation applied
All
galileo.*references rewritten tosplunk_ao.*per HYBIM-788 translation rules.galileo-coreandgalileo_core.*intentionally unchanged (external dep).Test plan
poetry run pytest tests/test_export.py -v— 17/17 passedpoetry run ruff check src/splunk_ao/export.py tests/test_export.py— cleanPart of
HYBIM-788 — commits applied in order: 1 of 3 (e42a569 → fa93ab2 → 6ccd06a)