Reading public Google Sheets into polars_result
Project description
read-google-sheet
Load public Google Sheets directly into Polars LazyFrame or DataFrame — with railway-oriented error handling via polars-result.
Requires Python 3.14+
Features
- 📊 Polars-native — returns
LazyFrameby default,DataFrameon request - 🚂 Railway-oriented — every operation returns
Result[T, Exception], never raises - ✅ Validated — sheet ID and name are validated before any network request
- 📦 Minimal dependencies — Polars, requests, polars-result
Installation
uv add read-google-sheet
pip install read-google-sheet
Quick Start
from polars_result import Ok, Err
from read_google_sheet import read_google_sheet
result = read_google_sheet(
sheet_id="1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgVE2upms",
sheet_name="Sheet1",
)
match result:
case Ok(lf):
print(lf.collect())
case Err(e):
print(f"Failed: {e}")
API Reference
read_google_sheet
def read_google_sheet(
sheet_id: str,
sheet_name: str,
as_dataframe: bool = False,
parse_dates: bool = True,
) -> Result[pl.LazyFrame | pl.DataFrame, Exception]
| Parameter | Description |
|---|---|
sheet_id |
44-character Google Sheet ID from the sheet URL |
sheet_name |
Tab name within the spreadsheet |
as_dataframe |
Return a collected DataFrame instead of a LazyFrame |
parse_dates |
Attempt to parse date columns automatically |
GoogleSheetConfig
Low-level dataclass for direct access and step-by-step control:
from read_google_sheet import GoogleSheetConfig
config = GoogleSheetConfig(
sheet_id="1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgVE2upms",
sheet_name="Sheet1",
timeout=10,
)
result = config.to_lazyframe() # Result[pl.LazyFrame, Exception]
result = config.to_dataframe() # Result[pl.DataFrame, Exception]
url = config.create_url() # Result[str, Exception]
data = config.fetch_data() # Result[StringIO, Exception]
Exceptions
All exceptions inherit from GoogleSheetError:
| Exception | Raised when |
|---|---|
ConfigurationError |
Invalid sheet ID or empty sheet name |
SheetFetchError |
HTTP request fails or returns a non-200 status |
NetworkError |
Connection error or timeout |
SheetTransformError |
CSV parsing or LazyFrame collection fails |
ValidationError |
General validation failure |
Error Handling Patterns
Pattern 1: Match on result
from read_google_sheet import read_google_sheet, ConfigurationError, NetworkError
match read_google_sheet(sheet_id="...", sheet_name="Sheet1"):
case Ok(lf):
df = lf.collect()
case Err(ConfigurationError() as e):
print(f"Config problem: {e}")
case Err(NetworkError() as e):
print(f"Network problem: {e}")
case Err(e):
print(f"Unexpected error: {e}")
Pattern 2: Chain operations
import polars as pl
from polars_result import Ok
from read_google_sheet import read_google_sheet
result = (
read_google_sheet(sheet_id="...", sheet_name="Sheet1")
.map(lambda lf: lf.filter(pl.col("amount") > 0))
.map(lambda lf: lf.select("vessel", "service", "amount"))
.and_then(lambda lf: Ok(lf.collect()))
)
Pattern 3: Fallback to another sheet
result = (
read_google_sheet(sheet_id="...", sheet_name="live")
.or_else(lambda _: read_google_sheet(sheet_id="...", sheet_name="backup"))
.unwrap_or(pl.LazyFrame())
)
Pattern 4: Unwrap with default
lf = read_google_sheet(sheet_id="...", sheet_name="Sheet1").unwrap_or(pl.LazyFrame())
Usage in Marimo Notebooks
import marimo as mo
from polars_result import Ok, Err
from read_google_sheet import read_google_sheet
result = read_google_sheet(
sheet_id="1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgVE2upms",
sheet_name="Sheet1",
as_dataframe=True,
)
match result:
case Ok(df):
mo.ui.table(df)
case Err(e):
mo.callout(mo.md(f"**Failed to load sheet:** {e}"), kind="danger")
How It Works
The package uses Google Sheets' public CSV export endpoint — no API key or OAuth required. The sheet must be set to "Anyone with the link can view".
The URL format used internally:
https://docs.google.com/spreadsheets/d/{sheet_id}/gviz/tq?tqx=out:csv&sheet={sheet_name}
Development
uv sync # install dependencies
uv run pytest # run tests
uv run pytest --cov=src/read_google_sheet --cov-report=html # with coverage
uv run ruff check src/ tests/ # lint
uv run ruff format src/ tests/ # format
uv run ty check # type check
Contributing
Contributions welcome — please open an issue or PR on GitHub.
License
MIT — see LICENSE for details.
Project details
Release history Release notifications | RSS feed
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 read_google_sheet-0.1.0.tar.gz.
File metadata
- Download URL: read_google_sheet-0.1.0.tar.gz
- Upload date:
- Size: 36.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.17 {"installer":{"name":"uv","version":"0.9.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3c7dce25de32419d6351a91d7a3314f96b19871973165719d8119736748f10a8
|
|
| MD5 |
746fcc3ed407ae094b8fa0cd5ab9d7b8
|
|
| BLAKE2b-256 |
b4d1d9db83b5e555d7a24e28ed165eb538e77db9844fca065bf050e52d3246e2
|
File details
Details for the file read_google_sheet-0.1.0-py3-none-any.whl.
File metadata
- Download URL: read_google_sheet-0.1.0-py3-none-any.whl
- Upload date:
- Size: 9.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.17 {"installer":{"name":"uv","version":"0.9.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9b7ece7bb6fb08fbda14cafb608a34a8fcb1ca793ede538cba3e34524bbaa656
|
|
| MD5 |
d63d5a324a526d9e52b97adb5454f8dc
|
|
| BLAKE2b-256 |
13bdb3525dfe7ed11d66480263f9f20a7bf753a856339d35891baa13086fc866
|