File-based Google Sheets representation library for LLM agents
Project description
extrasheet
File-based Google Sheets representation library for LLM agents.
Overview
extrasheet transforms Google Sheets into a file-based representation optimized for LLM agents. Instead of working with complex API responses, agents interact with simple files:
- data.tsv - Cell values in tab-separated format (formulas show computed values)
- formula.json - Sparse dictionary mapping cell coordinates to formulas
- format.json - Cell formatting definitions
- feature.json - Advanced features (charts, pivot tables, filters, etc.)
This separation allows LLM agents to selectively load only the data they need, reducing token usage and enabling efficient "fly-blind" editing.
Installation
pip install extrasheet
Or with uv:
uv add extrasheet
Quick Start
import asyncio
from extrasheet import SheetsClient, GoogleSheetsTransport
async def main():
# Create transport with access token
transport = GoogleSheetsTransport(access_token="your_token")
# Initialize client with transport
client = SheetsClient(transport)
# Pull spreadsheet to local files
files = await client.pull(
"1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms",
"./output",
max_rows=100, # Default: 100 rows per sheet
save_raw=True, # Default: saves raw API responses
)
# Clean up
await transport.close()
asyncio.run(main())
# Files created:
# ./output/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms/
# ├── spreadsheet.json # Spreadsheet metadata
# ├── Sheet1/
# │ ├── data.tsv # Cell values
# │ ├── formula.json # Cell formulas
# │ ├── format.json # Cell formatting
# │ └── feature.json # Charts, pivot tables, etc.
# ├── .raw/
# │ ├── metadata.json # Raw metadata API response
# │ └── data.json # Raw data API response
# └── .pristine/
# └── spreadsheet.zip # Pristine copy for diff/push
CLI Usage
# Pull a spreadsheet to local files (defaults to ./<spreadsheet_id>/)
python -m extrasheet pull <spreadsheet_url_or_id> [output_dir]
# Limit rows fetched per sheet (default: 100)
python -m extrasheet pull <url> --max-rows 500
# Fetch all rows (may timeout on large spreadsheets)
python -m extrasheet pull <url> --no-limit
# Don't save raw API responses
python -m extrasheet pull <url> --no-raw
Architecture
The library uses a transport-based architecture for clean separation of concerns:
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ SheetsClient │────▶│ Transport │────▶│ Google API / │
│ (orchestration) │ │ (data fetching) │ │ Local Files │
└─────────────────┘ └──────────────────┘ └─────────────────┘
│
▼
┌─────────────────┐ ┌──────────────────┐
│ Transformer │────▶│ FileWriter │
│ (API → files) │ │ (disk I/O) │
└─────────────────┘ └──────────────────┘
Transport implementations:
GoogleSheetsTransport- Production transport using Google Sheets APILocalFileTransport- Test transport reading from local golden files
Testing with Golden Files
The library supports golden file testing without mocking:
import pytest
from pathlib import Path
from extrasheet import SheetsClient, LocalFileTransport
@pytest.fixture
def client():
transport = LocalFileTransport(Path("tests/golden"))
return SheetsClient(transport)
@pytest.mark.asyncio
async def test_pull(client, tmp_path):
files = await client.pull("my_spreadsheet", tmp_path)
assert (tmp_path / "my_spreadsheet" / "Sheet1" / "data.tsv").exists()
Golden files are stored as:
tests/golden/
my_spreadsheet/
metadata.json # First API call response
data.json # Second API call response
Documentation
- On-Disk Format - Complete specification of the file format
- LLM Agent Guide - How to use extrasheet output for spreadsheet modifications
- API Types - TypedDict definitions generated from Google Sheets API
Development
cd extrasheet
uv sync --all-extras
uv run pytest tests/ -v
uv run ruff check .
uv run ruff format .
uv run mypy src/extrasheet
License
MIT License - see LICENSE for details.
Part of ExtraSuite
This package is part of the ExtraSuite project, which provides AI agents with secure access to Google Workspace files.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file extrasheet-0.1.0.tar.gz.
File metadata
- Download URL: extrasheet-0.1.0.tar.gz
- Upload date:
- Size: 210.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
34c920d69a85e94f0161a9e1057027e3c7d1f75879a1dc719bd189778bb44de3
|
|
| MD5 |
e540da4eb790a748b493e14daf293a7d
|
|
| BLAKE2b-256 |
952a83221db5ad76bfdf6c9edf04845f4774850d535a2b151639222f0c65822c
|
Provenance
The following attestation bundles were made for extrasheet-0.1.0.tar.gz:
Publisher:
publish-extrasheet.yml on think41/extrasuite
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
extrasheet-0.1.0.tar.gz -
Subject digest:
34c920d69a85e94f0161a9e1057027e3c7d1f75879a1dc719bd189778bb44de3 - Sigstore transparency entry: 939833642
- Sigstore integration time:
-
Permalink:
think41/extrasuite@92396324101378569eada467da2e82e7cd4f629c -
Branch / Tag:
refs/tags/extrasheet-v0.1.0 - Owner: https://github.com/think41
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-extrasheet.yml@92396324101378569eada467da2e82e7cd4f629c -
Trigger Event:
push
-
Statement type:
File details
Details for the file extrasheet-0.1.0-py3-none-any.whl.
File metadata
- Download URL: extrasheet-0.1.0-py3-none-any.whl
- Upload date:
- Size: 111.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5086ff874e2f22fd35564fee3d6070ae1450cc95b9991e38a9143713a0e12cc2
|
|
| MD5 |
e7c603cf159b70fc567ae11ca25b9853
|
|
| BLAKE2b-256 |
6f7409cf4ec07ac343fc1e7d847e45eb29afae9cb229f79c002c6e173730577c
|
Provenance
The following attestation bundles were made for extrasheet-0.1.0-py3-none-any.whl:
Publisher:
publish-extrasheet.yml on think41/extrasuite
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
extrasheet-0.1.0-py3-none-any.whl -
Subject digest:
5086ff874e2f22fd35564fee3d6070ae1450cc95b9991e38a9143713a0e12cc2 - Sigstore transparency entry: 939833657
- Sigstore integration time:
-
Permalink:
think41/extrasuite@92396324101378569eada467da2e82e7cd4f629c -
Branch / Tag:
refs/tags/extrasheet-v0.1.0 - Owner: https://github.com/think41
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-extrasheet.yml@92396324101378569eada467da2e82e7cd4f629c -
Trigger Event:
push
-
Statement type: