Skip to content

feat(sheets): expose cell notes in read_sheet_values#580

Merged
taylorwilsdon merged 4 commits intotaylorwilsdon:mainfrom
Bortlesboat:feat/517-cell-notes
Mar 15, 2026
Merged

feat(sheets): expose cell notes in read_sheet_values#580
taylorwilsdon merged 4 commits intotaylorwilsdon:mainfrom
Bortlesboat:feat/517-cell-notes

Conversation

@Bortlesboat
Copy link
Copy Markdown
Contributor

@Bortlesboat Bortlesboat commented Mar 15, 2026

Summary

  • Fixes Expose cell notes in read_sheet_values #517 — adds include_notes parameter to read_sheet_values to expose Google Sheets cell notes
  • Default False preserves existing behavior with zero extra API calls
  • Follows the same pattern as existing include_hyperlinks parameter

Implementation

  • include_notes: bool = False parameter on read_sheet_values
  • When True, fetches notes via spreadsheets.get with includeGridData=True and fields scoped to only note (minimal payload)
  • Three new helpers in sheets_helpers.py:
    • _extract_cell_notes_from_grid() — extracts [{"cell": "A1", "note": "..."}] from grid data
    • _fetch_sheet_notes() — API call with tight range bounds and 5000-cell cap
    • _format_sheet_notes_section() — formats notes into readable output (max 25 entries)

Test plan

  • Call read_sheet_values without include_notes — verify unchanged behavior, no extra API call
  • Call with include_notes=True on a sheet with notes — verify notes appear in output
  • Call with include_notes=True on a sheet without notes — verify graceful empty response
  • Verify large ranges respect the 5000-cell guard rail

Summary by CodeRabbit

  • New Features
    • Retrieve and display cell notes from Google Sheets when reading sheet values (optional).
    • Notes appear in a human-readable section with truncation and an overflow summary for large sets.
    • Metadata retrieval (hyperlinks/notes) consolidated for more efficient single-request fetches; a cell-cap prevents overly large requests.
    • Reading sheet values gains an optional parameter to include notes in output.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 15, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 279a3cc2-af24-402e-b42b-f4f12c353a48

📥 Commits

Reviewing files that changed from the base of the PR and between 2e0d639 and ba3db90.

📒 Files selected for processing (2)
  • gsheets/sheets_helpers.py
  • gsheets/sheets_tools.py

📝 Walkthrough

Walkthrough

Adds support for retrieving and formatting Google Sheets cell notes and consolidates grid metadata fetching (notes and hyperlinks) into a single bounded, single-request helper; exposes an include_notes option on read_sheet_values.

Changes

Cohort / File(s) Summary
Notes & Grid-metadata helpers
gsheets/sheets_helpers.py
Added _extract_cell_notes_from_grid, _fetch_sheet_notes, _format_sheet_notes_section, _fetch_grid_metadata, and MAX_GRID_METADATA_CELLS + logger. Implements tight-range calculation, 5000-cell cap, combined fields selector, and formatting for notes/hyperlinks.
Read flow integration
gsheets/sheets_tools.py
Updated read_sheet_values(...) signature to accept include_notes: bool = False; replaced per-range hyperlink logic with _fetch_grid_metadata call and integrated notes_section into output. Removed legacy constants/imports tied to old hyperlink fetch path.

Sequence Diagram

sequenceDiagram
    participant User
    participant sheets_tools as sheets_tools.read_sheet_values
    participant sheets_helpers as sheets_helpers._fetch_grid_metadata
    participant GoogleSheetsAPI as Google Sheets API

    User->>sheets_tools: call read_sheet_values(..., include_notes=True)
    sheets_tools->>sheets_helpers: _fetch_grid_metadata(service, spreadsheet_id, resolved_range, values, include_hyperlinks, include_notes)
    sheets_helpers->>GoogleSheetsAPI: spreadsheets.get(includeGridData=True, fields=...)
    GoogleSheetsAPI-->>sheets_helpers: spreadsheet grid data (cells, notes, links)
    sheets_helpers->>sheets_helpers: _extract_cell_notes_from_grid(...) / format hyperlink section
    sheets_helpers-->>sheets_tools: formatted notes_section, hyperlink_section
    sheets_tools-->>User: composed output including notes_section
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 I nibble through grids by moonlight bright,
I pluck little notes from each cell's quiet light,
I stitch them to output, tidy and neat,
A hop, a fetch — now notes and links meet,
Hooray for sheets made extra sweet! 🥕✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: adding cell notes exposure via the include_notes parameter to read_sheet_values.
Description check ✅ Passed The PR description is comprehensive, covering summary, implementation details, and test plan, though it does not follow the exact template structure with checklist items marked.
Linked Issues check ✅ Passed The PR fully addresses issue #517 by implementing cell notes retrieval in read_sheet_values via the include_notes parameter with three helper functions and appropriate API optimization.
Out of Scope Changes check ✅ Passed All changes are directly scoped to implementing the cell notes feature requested in issue #517; no out-of-scope modifications detected.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
📝 Coding Plan
  • Generate coding plan for human review comments

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 and usage tips.

@taylorwilsdon taylorwilsdon self-requested a review March 15, 2026 21:34
@taylorwilsdon taylorwilsdon self-assigned this Mar 15, 2026
@taylorwilsdon
Copy link
Copy Markdown
Owner

Appreciate this!

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
gsheets/sheets_tools.py (2)

267-267: Consider renaming MAX_HYPERLINK_FETCH_CELLS to a more generic name.

This constant is now used for both hyperlinks and notes fetching. A name like MAX_GRID_DATA_FETCH_CELLS would better reflect its broader usage.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@gsheets/sheets_tools.py` at line 267, The constant MAX_HYPERLINK_FETCH_CELLS
is used for both hyperlink and note fetching and should be renamed to a generic
identifier like MAX_GRID_DATA_FETCH_CELLS; update the constant definition and
all usages (e.g., the conditional in sheets_tools.py that reads "if cell_count
<= MAX_HYPERLINK_FETCH_CELLS:") to the new name, adjust any related
comments/docstrings and imports/exports so tests and other modules reference
MAX_GRID_DATA_FETCH_CELLS consistently, and run a project-wide search/replace to
ensure no stale references remain.

255-287: Consider extracting shared fetch logic to reduce duplication.

The notes fetching block is nearly identical to the hyperlinks block (lines 220-253). Both compute _a1_range_for_values, check cell count against MAX_HYPERLINK_FETCH_CELLS, and have the same error handling structure. A helper function could reduce ~60 lines to ~20.

Additionally, when both include_hyperlinks and include_notes are True, two separate API calls are made. These could potentially be combined into a single spreadsheets.get call with a merged fields selector to halve the API overhead.

💡 Example of potential helper extraction
async def _fetch_grid_metadata(
    service,
    spreadsheet_id: str,
    resolved_range: str,
    values: List[List[object]],
    *,
    include_hyperlinks: bool,
    include_notes: bool,
) -> tuple[str, str]:
    """Fetch hyperlinks and/or notes in a single API call when possible."""
    tight_range = _a1_range_for_values(resolved_range, values)
    if not tight_range:
        return "", ""
    
    cell_count = _a1_range_cell_count(tight_range) or sum(len(row) for row in values)
    if cell_count > MAX_HYPERLINK_FETCH_CELLS:
        return "", ""
    
    # Build combined fields selector based on what's requested
    # ... fetch once and parse both hyperlinks and notes
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@gsheets/sheets_tools.py` around lines 255 - 287, The notes-fetching logic
duplicates the hyperlinks block; extract a helper (e.g., _fetch_grid_metadata)
that takes (service, spreadsheet_id, resolved_range, values, include_hyperlinks,
include_notes) and: compute tight_range via _a1_range_for_values, bail out/log
if None, compute cell_count via _a1_range_cell_count or sum(len(row) for row in
values) and bail if over MAX_HYPERLINK_FETCH_CELLS, build a combined fields
selector for a single spreadsheets.get call when both include_hyperlinks and
include_notes are requested, perform one API call, then parse and return both
formatted sections (reusing
_format_sheet_hyperlinks_section/_format_sheet_notes_section or equivalent) and
propagate/log errors the same way as the current try/except blocks; replace the
existing inline blocks with calls to this helper in read_sheet_values.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@gsheets/sheets_tools.py`:
- Line 267: The constant MAX_HYPERLINK_FETCH_CELLS is used for both hyperlink
and note fetching and should be renamed to a generic identifier like
MAX_GRID_DATA_FETCH_CELLS; update the constant definition and all usages (e.g.,
the conditional in sheets_tools.py that reads "if cell_count <=
MAX_HYPERLINK_FETCH_CELLS:") to the new name, adjust any related
comments/docstrings and imports/exports so tests and other modules reference
MAX_GRID_DATA_FETCH_CELLS consistently, and run a project-wide search/replace to
ensure no stale references remain.
- Around line 255-287: The notes-fetching logic duplicates the hyperlinks block;
extract a helper (e.g., _fetch_grid_metadata) that takes (service,
spreadsheet_id, resolved_range, values, include_hyperlinks, include_notes) and:
compute tight_range via _a1_range_for_values, bail out/log if None, compute
cell_count via _a1_range_cell_count or sum(len(row) for row in values) and bail
if over MAX_HYPERLINK_FETCH_CELLS, build a combined fields selector for a single
spreadsheets.get call when both include_hyperlinks and include_notes are
requested, perform one API call, then parse and return both formatted sections
(reusing _format_sheet_hyperlinks_section/_format_sheet_notes_section or
equivalent) and propagate/log errors the same way as the current try/except
blocks; replace the existing inline blocks with calls to this helper in
read_sheet_values.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e0f39b47-26a4-4de8-bb00-53db85060d1c

📥 Commits

Reviewing files that changed from the base of the PR and between 92b4a78 and 2e0d639.

📒 Files selected for processing (2)
  • gsheets/sheets_helpers.py
  • gsheets/sheets_tools.py

@taylorwilsdon taylorwilsdon merged commit 7fe01c1 into taylorwilsdon:main Mar 15, 2026
4 checks passed
@mickey-mikey mickey-mikey mentioned this pull request Mar 19, 2026
20 tasks
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.

Expose cell notes in read_sheet_values

2 participants