Skip to main content

A Python library for Google Sheets with high-level API, automatic type inference, and efficient caching.

Project description

SmartSpread

Python library for Google Sheets operations with automatic type inference, caching, and multiple data format support. Built on gspread.

Core Concepts

Two main classes:

  • SmartSpread: Represents a Google Sheets spreadsheet, manages authentication and tab access
  • SmartTab: Represents a single worksheet tab, handles data read/write operations

Three data formats:

  • DataFrame: pandas DataFrame (default) - best for data manipulation
  • dict: List of dictionaries - each row is a dict with column names as keys
  • list: List of lists - first row is headers, remaining rows are data

Type inference:

  • Empty cells → None
  • Integers → nullable Int64 dtype (preserves None)
  • Floats → float64
  • Strings → object dtype
  • Empty columns → inferred as needed when data is added

Caching behavior:

  • Data is cached after first read to minimize API calls
  • Hash comparison prevents unnecessary writes
  • Use refresh() to reload from Google Sheets after external changes

Installation & Setup

pip install smartspread

Authentication requirements:

  1. Google Cloud Project with Sheets API enabled
  2. Service account credentials JSON file
  3. Spreadsheet shared with service account email

Usage Patterns

Basic workflow

from smartspread import SmartSpread

spread = SmartSpread(
    sheet_identifier="spreadsheet-id-or-name",
    key_file="credentials.json"
)
tab = spread.tab("MyTab")  # Get or create tab
tab.data["new_column"] = "value"  # Modify DataFrame
tab.write_data(overwrite_tab=True)  # Write to Sheets

Data format selection

tab_df = spread.tab("Sheet1", data_format="DataFrame")  # pandas DataFrame
tab_dict = spread.tab("Sheet2", data_format="dict")     # [{"col": "val"}, ...]
tab_list = spread.tab("Sheet3", data_format="list")     # [["header"], ["val"], ...]

Update or insert rows

# Updates existing row where ID=123, or inserts new row if not found
tab.update_row_by_column_pattern(
    column="ID",
    value=123,
    updates={"Status": "completed", "Date": "2024-01-01"}
)
tab.write_data(overwrite_tab=True)

Filter and refresh

filtered = tab.filter_rows_by_column("Name", "Alice")  # Returns DataFrame
tab.refresh()  # Reload from Sheets after external changes

API Reference

SmartSpread(sheet_identifier, key_file=None, service_account_data=None, user_email=None)

Constructor parameters:

  • sheet_identifier: Spreadsheet ID or name
  • key_file: Path to service account JSON credentials
  • service_account_data: Dict of credentials (alternative to key_file)
  • user_email: Email for user-based auth (alternative to service account)

Methods:

  • tab(tab_name, data_format="DataFrame", keep_number_formatting=False) → SmartTab
  • refresh() → None (clears cache, reloads metadata)
  • grant_access(email, role="owner") → None

Properties:

  • tab_names → list[str]
  • url → str
  • tab_exists(tab_name) → bool

SmartTab

Attributes:

  • data: DataFrame | list[dict] | list[list] (mutable, modify directly)
  • tab_name: str
  • data_format: "DataFrame" | "dict" | "list"

Methods:

  • read_data() → DataFrame | list[dict] | list[list]
  • write_data(overwrite_tab=False, as_table=False) → None
  • update_row_by_column_pattern(column, value, updates) → None (modifies data in-place)
  • filter_rows_by_column(column, pattern) → DataFrame
  • refresh() → None (reloads from Sheets)

Important Implementation Details

Type handling:

  • Empty cells → None (not empty string)
  • Nullable integers use Int64 dtype (not int64)
  • Mixed-type columns automatically convert to object dtype when needed
  • pd.NA values are sanitized to None in dict/list formats
  • NaN values are converted to empty strings before writing to Sheets

Write behavior:

  • write_data() only writes if data hash has changed
  • overwrite_tab=True clears entire tab before writing
  • overwrite_tab=False updates only the data range
  • as_table=True adds header formatting and freeze

Rate limits:

  • Google Sheets API: 60 requests/minute (free tier)
  • Caching minimizes API calls automatically

Error handling:

  • Empty tabs raise ValueError on read
  • Missing columns are auto-created with None values
  • Type mismatches trigger automatic dtype conversion

Changelog

v1.1.5 (2024)

  • Fixed: InvalidJSONError with NaN values in dict format by sanitizing in _data_as_list dict branch

v1.1.4 (2024)

  • Fixed: TypeError when writing strings to float64 columns in update_row_by_column_pattern
  • Fixed: InvalidJSONError with NaN values in write_data by converting to object dtype before fillna

v1.1.3 (2024)

  • Fixed: pd.NA values sanitized to None in list/dict formats

v1.1.2 (2024)

  • Changed: Package renamed to smartspread (no underscore)

v1.1.1 (2024)

  • Fixed: JSON serialization with Int64 columns containing pd.NA

Links

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

smartspread-1.1.5.tar.gz (13.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

smartspread-1.1.5-py3-none-any.whl (10.2 kB view details)

Uploaded Python 3

File details

Details for the file smartspread-1.1.5.tar.gz.

File metadata

  • Download URL: smartspread-1.1.5.tar.gz
  • Upload date:
  • Size: 13.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for smartspread-1.1.5.tar.gz
Algorithm Hash digest
SHA256 34c55a9c6bd6851f31ea83fb3a432371de0bc09acacf75cc9559a5723ba98e8d
MD5 052b9448f0aa3be38711f9bf5cd97ad6
BLAKE2b-256 9bcbddaacdb72750656e1de4d35b26959e5c0d4663f510d888fd3100864b7f80

See more details on using hashes here.

File details

Details for the file smartspread-1.1.5-py3-none-any.whl.

File metadata

  • Download URL: smartspread-1.1.5-py3-none-any.whl
  • Upload date:
  • Size: 10.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for smartspread-1.1.5-py3-none-any.whl
Algorithm Hash digest
SHA256 5a45e2055d35f3c3dc2ab1b74408858cf7c57d464ff3f0fe490700d6ebba33dc
MD5 6be6a421d25d8fe66fc4370104860948
BLAKE2b-256 7c6b7b0077927243506218ef4bd2fb4f3a6f2e2d5b9bbe8c971e7efa03c21bba

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page