Skip to content

Echo records_format back on search responses - #15

Open
sagargg wants to merge 1 commit into
mainfrom
feat/echo-records-format
Open

Echo records_format back on search responses#15
sagargg wants to merge 1 commit into
mainfrom
feat/echo-records-format

Conversation

@sagargg

@sagargg sagargg commented Jul 29, 2026

Copy link
Copy Markdown
Member

What

datastore_search accepts records_format (objects / lists / csv / tsv), but the response never said which shape it returned. A client holding only the response body had to remember its own query string to know how to parse records.

This adds result.records_format to the search envelope, next to records:

"fields": [{"id": "auction_id", "type": "integer"}],
"records_format": "objects",
"records": [ ... ]

How

The value comes from the writer, not the service. Each stream_* function in datastore/services/streaming.py already knows its own format, so it passes a literal to _stream_envelope. datastore_search_sql streams through stream_objects and therefore reports objects for free — no change needed in services/read.py.

  • datastore/services/streaming.pyrecords_format param on _stream_envelope, emitted before "records"; the four writers pass their own value.
  • datastore/schemas/responses.pyrecords_format: str = "objects" on DatastoreSearchResponse.Result so OpenAPI documents it.
  • Postman: two new datastore_search requests (records_format=lists, records_format=csv) from new example_payload/ files; collection.json regenerated (27 requests, was 25).
  • Docs: API.md + CLAUDE.md §6.2 / §6.4 response examples.

Additive and backwards compatible — no existing field changes shape.

Docs correction

The docs claimed records_format=csv / tsv put a header row first. They don't — _records_delimited_string emits data rows only, and test_csv_format_streams_data_rows has always pinned that ("144,DCL,47.82\n…"). Column names live on result.fields. Corrected in that function's docstring, API.md, and CLAUDE.md. No behaviour change — flagging in case the header was actually intended, which would be a separate PR.

Testing

pytest — 368 passed. Assertions added to the four records_format routing tests plus the search_sql happy path.

ruff check reports one pre-existing import-order error in tests/test_cors.py, untouched here (its fix lives on another branch).

Summary by CodeRabbit

  • New Features

    • Datastore search responses now explicitly report the applied records_format (objects, lists, csv, or tsv).
    • Added example payloads and Postman scenarios for list and CSV response formats.
  • Documentation

    • Clarified response behavior for JSON, CSV, and TSV formats, including that delimited results contain data rows without headers.

`datastore_search` accepts `records_format` (objects / lists / csv / tsv)
but the response never said which shape it returned, so a client holding
only the body had to remember its own query string to parse `records`.

Emit `result.records_format` next to `records`. The value comes from the
writer itself — each `stream_*` function passes its own literal to
`_stream_envelope` — so `datastore_search_sql`, which always streams
through `stream_objects`, reports `objects` without any plumbing in the
service layer.

Also corrects a stale claim in the docs: `records_format=csv` / `tsv`
emit data rows only, with column names on `result.fields`. There is no
header row inside the records string (`test_csv_format_streams_data_rows`
has always pinned this).
@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The datastore response envelope now echoes records_format for objects, lists, CSV, and TSV outputs. Response schemas, streaming code, tests, API documentation, payload fixtures, and Postman examples were updated accordingly.

Changes

Records format response contract

Layer / File(s) Summary
Streaming response contract
datastore/schemas/responses.py, datastore/services/streaming.py
Adds result.records_format to the response schema and streaming envelope, with explicit values for each supported format.
Response contract tests
tests/test_datastore_search.py, tests/test_datastore_search_sql.py
Verifies the echoed format for datastore search formats and the SQL endpoint’s "objects" response.
Documentation and request examples
API.md, CLAUDE.md, example_payload/datastore_search/*, postman/*
Documents the response field and delimited-record behavior, and adds lists and CSV request examples to payloads and Postman scenarios.

Estimated code review effort: 2 (Simple) | ~10 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: search responses now echo records_format back in the response payload.
Docstring Coverage ✅ Passed Docstring coverage is 84.62% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Fix failing CI checks
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/echo-records-format

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
datastore/schemas/responses.py (1)

163-163: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Constrain records_format to the supported values.

Using str leaves the response contract open-ended in generated API documentation. Use Literal["objects", "lists", "csv", "tsv"] while retaining the "objects" default so clients can discover and validate the four supported formats.

Proposed type change
-        records_format: str = "objects"
+        records_format: Literal["objects", "lists", "csv", "tsv"] = "objects"

Add the corresponding Literal import.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@datastore/schemas/responses.py` at line 163, Update the records_format field
in the response schema to use Literal with the supported values "objects",
"lists", "csv", and "tsv", preserving "objects" as the default. Add the required
Literal import and leave other response fields unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@API.md`:
- Around line 299-302: Update the pagination guidance in API.md lines 299-302
and CLAUDE.md lines 703-705 to distinguish empty-page representations:
object/list records use empty arrays, while CSV/TSV records are JSON strings and
use an empty string. Apply the equivalent clarification at both documented
sites.

---

Nitpick comments:
In `@datastore/schemas/responses.py`:
- Line 163: Update the records_format field in the response schema to use
Literal with the supported values "objects", "lists", "csv", and "tsv",
preserving "objects" as the default. Add the required Literal import and leave
other response fields unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: b38aa26e-c9cd-44b5-883c-ca1d13717b42

📥 Commits

Reviewing files that changed from the base of the PR and between daf5825 and 4c7e5ac.

📒 Files selected for processing (10)
  • API.md
  • CLAUDE.md
  • datastore/schemas/responses.py
  • datastore/services/streaming.py
  • example_payload/datastore_search/records_format_csv.json
  • example_payload/datastore_search/records_format_lists.json
  • postman/collection.json
  • postman/generate_postman.py
  • tests/test_datastore_search.py
  • tests/test_datastore_search_sql.py

Comment thread API.md
Comment on lines +299 to +302
- `records_format=csv` / `tsv` → `records` is a single text body of data rows,
still inside the JSON envelope; column names are on `fields`, not in the text.
- `result.records_format` echoes the format that was applied, so a client can tell
which `records` shape it got without re-reading its own query string.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Document empty CSV/TSV pages as strings. Delimited records values are JSON strings, so their empty-page representation is "", not [].

  • API.md#L299-L302: update the adjacent pagination guidance to distinguish object/list empty arrays from CSV/TSV empty strings.
  • CLAUDE.md#L703-L705: make the equivalent distinction in the datastore search pagination guidance.
📍 Affects 2 files
  • API.md#L299-L302 (this comment)
  • CLAUDE.md#L703-L705
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@API.md` around lines 299 - 302, Update the pagination guidance in API.md
lines 299-302 and CLAUDE.md lines 703-705 to distinguish empty-page
representations: object/list records use empty arrays, while CSV/TSV records are
JSON strings and use an empty string. Apply the equivalent clarification at both
documented sites.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant