Skip to content

Sheets

Sheets

Sheets(auth: GoogleAuth, *, cache: bool = False, cache_ttl: float | None = None, cache_max_entries: int | None = None, dataframe_backend: Literal['pandas', 'polars'] = 'pandas', batch_cell_limit: int | None = 50000)

High-level Google Sheets client.

Inspired by gspread's simple API.

Example

auth = GoogleAuth() auth.authenticate()

sheets = Sheets(auth)

Open by title (like gspread!)

doc = sheets.open("My Spreadsheet")

Or by key/url

doc = sheets.open_by_key("abc123...") doc = sheets.open_by_url("https://docs.google.com/spreadsheets/...")

Work with worksheets

ws = doc.sheet1 data = ws.get_all_values() ws.update("A1", [["Hello", "World"]])

Initialize Sheets client.

Parameters:

Name Type Description Default
auth GoogleAuth

GoogleAuth instance with valid credentials

required
cache bool

Cache reads made through the engine features (upsert, iter_rows, read_as, ...); invalidated by this client's own writes, not by other processes. See clear_cache().

False
cache_ttl float | None

Seconds before a cached read expires (enables the cache)

None
cache_max_entries int | None

LRU size bound (enables the cache)

None
dataframe_backend Literal['pandas', 'polars']

"pandas" or "polars" for read/write_dataframe

'pandas'
batch_cell_limit int | None

Split big writes into requests of at most this many cells (None disables chunking)

50000

service property

service: Any

Lazy-load Sheets API service.

drive property

drive: Any

Lazy-load Drive API service (for listing/sharing).

clear_cache

clear_cache() -> None

Drop every cached read (no-op unless the cache is enabled).

open

open(title: str) -> Spreadsheet

Open a spreadsheet by title.

Parameters:

Name Type Description Default
title str

Spreadsheet title

required

Returns:

Type Description
Spreadsheet

Spreadsheet object

Raises:

Type Description
ValueError

If not found

open_by_key

open_by_key(key: str) -> Spreadsheet

Open a spreadsheet by key (ID).

Parameters:

Name Type Description Default
key str

Spreadsheet ID

required

Returns:

Type Description
Spreadsheet

Spreadsheet object

open_by_url

open_by_url(url: str) -> Spreadsheet

Open a spreadsheet by URL.

Parameters:

Name Type Description Default
url str

Full Google Sheets URL

required

Returns:

Type Description
Spreadsheet

Spreadsheet object

create

create(title: str) -> Spreadsheet

Create a new spreadsheet.

Parameters:

Name Type Description Default
title str

Spreadsheet title

required

Returns:

Type Description
Spreadsheet

Created Spreadsheet

copy

copy(spreadsheet_id: str, title: str | None = None, copy_permissions: bool = False, folder_id: str | None = None) -> Spreadsheet

Copy a spreadsheet (optionally with its sharing, except ownership).

delete

delete(spreadsheet_id: str) -> None

Delete a spreadsheet permanently (Drive).

list_spreadsheets

list_spreadsheets(max_results: int | None = 100) -> list[dict]

List all spreadsheets accessible to the user.

Parameters:

Name Type Description Default
max_results int | None

Maximum spreadsheets to return (None = all)

100

Returns:

Type Description
list[dict]

List of {id, name} dicts

get_values

get_values(spreadsheet_id: str, range: str, value_render: ValueRender = 'FORMATTED_VALUE') -> list[list[Any]]

Get values from a range.

Parameters:

Name Type Description Default
spreadsheet_id str

Spreadsheet ID

required
range str

A1 range including the sheet, e.g. "'Sheet 1'!A1:C10"

required
value_render ValueRender

FORMATTED_VALUE (as displayed), UNFORMATTED_VALUE (numbers as numbers) or FORMULA

'FORMATTED_VALUE'

batch_get_values

batch_get_values(spreadsheet_id: str, ranges: list[str], value_render: ValueRender = 'FORMATTED_VALUE') -> list[list[list[Any]]]

Get several ranges in one request; results follow the order of ranges.

update_values

update_values(spreadsheet_id: str, range: str, values: list[list[Any]], value_input: ValueInput = 'USER_ENTERED') -> dict

Update values in a range.

Parameters:

Name Type Description Default
value_input ValueInput

USER_ENTERED parses values as if typed into the UI ("=SUM(A1:A3)" becomes a formula, "2026-01-01" a date). Use RAW for untrusted data so text starting with "=" stays text.

'USER_ENTERED'

append_values

append_values(spreadsheet_id: str, range: str, values: list[list[Any]], value_input: ValueInput = 'USER_ENTERED') -> dict

Append rows after the table found in range (see update_values for value_input).

clear_values

clear_values(spreadsheet_id: str, range: str) -> dict

Clear values from a range (formatting is kept).

batch_update

batch_update(spreadsheet_id: str, data: list[dict], value_input: ValueInput = 'USER_ENTERED') -> dict

Batch update multiple ranges.

Parameters:

Name Type Description Default
spreadsheet_id str

Spreadsheet ID

required
data list[dict]

List of {range, values} dicts

required
value_input ValueInput

See update_values

'USER_ENTERED'

batch_requests

batch_requests(spreadsheet_id: str, requests: list[dict]) -> list[dict]

Run raw spreadsheets.batchUpdate requests (formatting, structure, ...).

Use for anything this client doesn't wrap; see the Sheets API reference for request types. Returns one reply per request.

format_range

format_range(spreadsheet_id: str, sheet_id: int, range: str, cell_format: dict) -> None

Apply a cell format to a range.

Parameters:

Name Type Description Default
range str

A1 range without the sheet, e.g. "A1:Z1"

required
cell_format dict

A Sheets CellFormat, e.g. {"textFormat": {"bold": True}, "numberFormat": {"type": "CURRENCY", "pattern": "$#,##0.00"}}. Only the top-level keys given are changed.

required

freeze

freeze(spreadsheet_id: str, sheet_id: int, rows: int | None = None, cols: int | None = None) -> None

Freeze the first rows rows and/or cols columns (0 unfreezes).

protect_range

protect_range(spreadsheet_id: str, sheet_id: int, range: str | None = None, description: str | None = None, editors: list[str] | None = None, warning_only: bool = False) -> int

Protect a range (or the whole sheet when range is None).

Parameters:

Name Type Description Default
editors list[str] | None

Emails that can still edit (default: only the owner)

None
warning_only bool

Let everyone edit but show a warning

False

Returns:

Type Description
int

The protected range ID

find_replace

find_replace(spreadsheet_id: str, find: str, replacement: str, sheet_id: int | None = None, match_case: bool = False, match_entire_cell: bool = False, regex: bool = False) -> int

Find and replace text, in one sheet or all of them.

Parameters:

Name Type Description Default
regex bool

Treat find as a regular expression; replacement can use $1-style groups

False

Returns:

Type Description
int

Number of occurrences changed

add_worksheet

add_worksheet(spreadsheet_id: str, title: str, rows: int = 1000, cols: int = 26) -> Worksheet

Add a worksheet to a spreadsheet.

rename_worksheet

rename_worksheet(spreadsheet_id: str, sheet_id: int, title: str) -> None

Rename a worksheet.

duplicate_worksheet

duplicate_worksheet(spreadsheet_id: str, sheet_id: int, new_title: str | None = None, index: int | None = None) -> Worksheet

Copy a worksheet within the spreadsheet (default name: "Copy of ...").

delete_worksheet

delete_worksheet(spreadsheet_id: str, sheet_id: int) -> bool

Delete a worksheet.

Returns:

Type Description
bool

True if deleted, False if the spreadsheet doesn't exist. Other

bool

failures raise, e.g. ValidationError-like 400s when deleting the

bool

last remaining sheet.

share

share(spreadsheet_id: str, email: str, role: str = 'reader', notify: bool = True) -> bool

Share a spreadsheet.

Returns:

Type Description
bool

True if shared, False if the spreadsheet doesn't exist. Other

bool

failures raise.

Spreadsheet dataclass

Spreadsheet(id: str, title: str, url: str, locale: str = 'en_US', time_zone: str = 'America/New_York', worksheets: list[Worksheet] = list(), _sheets: Optional[Sheets] = None)

A Google Spreadsheet.

Contains multiple worksheets (tabs).

sheet1 property

sheet1: Worksheet | None

Get the first worksheet (convenience property like gspread).

worksheet

worksheet(title: str) -> Worksheet | None

Get worksheet by title.

get_worksheet

get_worksheet(index: int) -> Worksheet | None

Get worksheet by index (0-indexed).

add_worksheet

add_worksheet(title: str, rows: int = 1000, cols: int = 26) -> Worksheet

Add a new worksheet.

Parameters:

Name Type Description Default
title str

Worksheet title

required
rows int

Number of rows

1000
cols int

Number of columns

26

Returns:

Type Description
Worksheet

Created Worksheet

duplicate_worksheet

duplicate_worksheet(worksheet: Worksheet, new_title: str | None = None) -> Worksheet

Copy a worksheet (default name: "Copy of ...").

del_worksheet

del_worksheet(worksheet: Worksheet) -> bool

Delete a worksheet.

share

share(email: str, role: str = 'reader', notify: bool = True) -> bool

Share spreadsheet with someone.

Parameters:

Name Type Description Default
email str

Email to share with

required
role str

Permission role (reader, writer)

'reader'
notify bool

Send notification email

True

worksheet_or_create

worksheet_or_create(title: str, rows: int = 100, cols: int = 26) -> Worksheet

The tab titled title, created if missing.

worksheet_by_id

worksheet_by_id(sheet_id: int) -> Worksheet | None

Tab by its numeric ID (gid).

update_title

update_title(title: str) -> None

Rename the spreadsheet.

update_locale

update_locale(locale: str) -> None

Locale used for formats and functions, e.g. "es_AR".

update_timezone

update_timezone(timezone: str) -> None

Time zone, e.g. "America/Argentina/Buenos_Aires".

export

export(format: str = 'pdf') -> bytes

The whole spreadsheet as bytes.

Parameters:

Name Type Description Default
format str

"pdf", "xlsx", "ods", "csv", "tsv" (first sheet only) or "html" (zip)

'pdf'

list_named_ranges

list_named_ranges() -> list[dict[str, Any]]

Named ranges (define them with Worksheet.define_named_range).

delete_named_range

delete_named_range(named_range_id: str) -> None

Remove a named range.

set_developer_metadata

set_developer_metadata(key: str, value: str, visibility: str = 'DOCUMENT') -> None

Attach a hidden key/value to the spreadsheet.

list_developer_metadata

list_developer_metadata() -> list[dict[str, Any]]

Developer metadata of the spreadsheet and its tabs.

delete_developer_metadata

delete_developer_metadata(key: str) -> None

Remove developer metadata by key.

list_permissions

list_permissions() -> list[dict[str, Any]]

Who has access.

remove_permission

remove_permission(value: str, role: str = 'any') -> list[str]

Revoke access of an email or domain (optionally only for role); returns removed IDs.

Worksheet dataclass

Worksheet(id: int, title: str, index: int, row_count: int = 1000, column_count: int = 26, _spreadsheet: Optional[Spreadsheet] = None)

A worksheet (tab) within a spreadsheet.

Provides methods for reading and writing cell data. Ranges are A1 notation without the sheet title ("A1:C10"); the title is added and quoted for you, so tabs named "2024" or "Pablo's" work.

url property

url: str | None

Get URL to this specific worksheet.

get

get(range: str = 'A1', value_render: ValueRender = 'FORMATTED_VALUE') -> list[list[Any]]

Get values from a range.

Parameters:

Name Type Description Default
range str

A1 notation (e.g., "A1:B10", "A:C", "1:5")

'A1'
value_render ValueRender

FORMATTED_VALUE, UNFORMATTED_VALUE or FORMULA

'FORMATTED_VALUE'

Returns:

Type Description
list[list[Any]]

2D list of values

batch_get

batch_get(ranges: list[str]) -> list[list[list[Any]]]

Get several ranges in one request, in the order given.

get_all_values

get_all_values() -> list[list[Any]]

Get all values in the worksheet.

get_all_records

get_all_records(head: int = 1) -> list[dict]

Get all rows as list of dicts using row as headers.

Parameters:

Name Type Description Default
head int

Row number to use as headers (1-indexed)

1

Returns:

Type Description
list[dict]

List of dicts with header keys

row_values

row_values(row: int) -> list[Any]

Get all values in a row (1-indexed).

col_values

col_values(col: int) -> list[Any]

Get all values in a column (1-indexed).

cell

cell(row: int, col: int) -> Any

Get a single cell value (1-indexed).

update

update(range: str, values: list[list[Any]], value_input: ValueInput = 'USER_ENTERED') -> dict

Update a range with values.

Parameters:

Name Type Description Default
range str

A1 notation (a single cell writes from there down/right)

required
values list[list[Any]]

2D list of values

required
value_input ValueInput

USER_ENTERED (parse like the UI: formulas, dates) or RAW (store as-is; use for untrusted text)

'USER_ENTERED'

Returns:

Type Description
dict

Update response

batch_update

batch_update(data: list[dict[str, Any]], value_input: ValueInput = 'USER_ENTERED') -> dict

Write several ranges of this sheet in one request: [{"range": "A1:B2", "values": [...]}].

update_cell

update_cell(row: int, col: int, value: Any) -> dict

Update a single cell (1-indexed).

append_row

append_row(values: list[Any], value_input: ValueInput = 'USER_ENTERED') -> dict

Append a row to the end of the worksheet.

append_rows

append_rows(rows: list[list[Any]], value_input: ValueInput = 'USER_ENTERED') -> dict

Append multiple rows.

clear

clear(range: str | None = None) -> dict

Clear values from a range or entire worksheet.

Parameters:

Name Type Description Default
range str | None

A1 notation (default: entire sheet)

None

format

format(range: str | list[str], cell_format: dict | CellFormat) -> None

Format one or more ranges with a CellFormat object or a raw API dict.

Example

ws.format("A1:Z1", CellFormat(text_format=TextFormat(bold=True))) ws.format("B2:B100", {"numberFormat": {"type": "CURRENCY", "pattern": "$#,##0.00"}})

freeze

freeze(rows: int | None = None, cols: int | None = None) -> None

Freeze header rows and/or columns (0 unfreezes).

protect

protect(range: str | None = None, description: str | None = None, editors: list[str] | None = None, warning_only: bool = False) -> int

Protect a range, or the whole sheet. Returns the protected range ID.

rename

rename(title: str) -> None

Rename this worksheet.

replace

replace(find: str, replacement: str, match_case: bool = False, match_entire_cell: bool = False, regex: bool = False) -> int

Find and replace in this worksheet (server-side).

Returns:

Type Description
int

Number of occurrences changed

find

find(query: str | Pattern[str]) -> tuple[int, int] | None

Find the first cell equal to query, or matching it if it's a regex.

Example

ws.find("Total") ws.find(re.compile(r"\d{3}-\d{4}"))

Returns:

Type Description
tuple[int, int] | None

(row, col) tuple (1-indexed) or None

findall

findall(query: str | Pattern[str]) -> list[tuple[int, int]]

Find all cells equal to query, or matching it if it's a regex.

iter_rows

iter_rows(page_size: int = 1000, skiprows: int = 0) -> Iterator[list[str]]

Yield rows lazily, reading page_size rows per request (big sheets).

iter_records

iter_records(page_size: int = 1000) -> Iterator[dict[str, str]]

Yield rows as {header: value} dicts, lazily (header in row 1).

last_row

last_row() -> int

Index (1-based) of the last row with data; 0 when empty.

update_row

update_row(row: int, values: list[Any], start_column: int | None = None) -> None

Write values into row starting at start_column (1-based, default A).

insert

insert(values: list[list[Any]], row: int | None = None, value_input: ValueInput = 'USER_ENTERED') -> Any

Insert rows at row (1-based), shifting the existing ones down; append when None.

GSpreadManager's insert(fila=...) appended after the table instead: it sent values.append with a range starting at that row, which the API treats as "find the table there and add after it".

import_csv

import_csv(source: Any, *, clear: bool = True, delimiter: str = ',') -> Any

Load a CSV (path or file object) from A1, clearing the sheet first unless clear=False.

upsert

upsert(rows: list[dict[str, Any]] | list[list[Any]], key: str) -> dict[str, int]

Update rows whose key column matches and append the rest.

Returns:

Type Description
dict[str, int]

{"updated": n, "appended": m}

update_where

update_where(where: Where, updates: dict[str, Any]) -> int

Set updates on rows matching where ({column: value} or a predicate).

delete_where

delete_where(where: Where) -> int

Delete rows matching where; returns how many were deleted.

rows_where_column_equals

rows_where_column_equals(column: int, value: Any) -> list[tuple[int, list[str]]]

(row number, row) for rows whose column (0-based, as in GSpreadManager) equals value.

row_with_empty_in_column

row_with_empty_in_column(column_letter: str) -> tuple[list[Any] | None, int | None]

First row with an empty cell in column_letter: (row values, number) or (None, None).

ensure_schema

ensure_schema(model: type, *, create: bool = True, strict: bool = False) -> dict[str, Any]

Check (or write, if the sheet is empty) the header row against model's fields.

read_as

read_as(model: type, skiprows: int = 0) -> list[Any]

Rows as model instances (dataclass or Pydantic), with values converted to field types.

iter_as

iter_as(model: type, page_size: int = 1000) -> Iterator[Any]

Like read_as(), lazily.

append_models

append_models(models: list[Any]) -> Any

Append model instances as rows.

write_models

write_models(models: list[Any], include_header: bool = True, clear: bool = True) -> Any

Write model instances from A1 (header from the fields).

upsert_models

upsert_models(models: list[Any], key: str) -> dict[str, int]

upsert() for model instances.

format_header

format_header(range: str = '1:1', background_hex: str | None = '#D9EAD3') -> None

Bold header with a background color.

set_background

set_background(range: str | list[str], color: Color) -> None

Background color for one or more ranges.

set_text_format

set_text_format(range: str | list[str], *, bold: bool | None = None, italic: bool | None = None, font_size: int | None = None, color: Color | None = None) -> None

Bold, italic, size and/or color of the text.

set_number_format

set_number_format(range: str | list[str], pattern: str, number_type: str = 'NUMBER') -> None

Number format, e.g. ("C2:C100", "#,##0.00", "CURRENCY").

merge

merge(range: str, merge_type: str = 'MERGE_ALL') -> None

Merge cells (MERGE_ALL, MERGE_ROWS or MERGE_COLUMNS).

unmerge

unmerge(range: str) -> None

Undo merges in a range.

set_tab_color

set_tab_color(color: Color) -> None

Color of the tab.

clear_tab_color

clear_tab_color() -> None

Remove the tab color.

add_dropdown

add_dropdown(range: str, values: list[Any], strict: bool = True) -> None

Dropdown with values; strict rejects anything else.

add_checkbox

add_checkbox(range: str) -> None

Checkboxes.

set_data_validation

set_data_validation(range: str, condition_type: str, values: list[Any] | None = None, strict: bool = True, show_custom_ui: bool = True) -> None

Any validation rule, e.g. ("B2:B100", "NUMBER_GREATER", [0]).

add_conditional_format

add_conditional_format(range: str, condition_type: str, values: list[Any], cell_format: CellFormat, index: int = 0) -> None

Format cells meeting a condition, e.g. ("C2:C100", "NUMBER_LESS", [0], red).

insert_rows

insert_rows(at: int, number: int = 1, inherit_from_before: bool = False) -> None

Insert blank rows before row at (1-based).

insert_cols

insert_cols(at: int, number: int = 1, inherit_from_before: bool = False) -> None

Insert blank columns before column at (1-based).

delete_rows

delete_rows(start: int, end: int | None = None) -> None

Delete rows start..end (1-based, inclusive).

delete_cols

delete_cols(start: int, end: int | None = None) -> None

Delete columns start..end (1-based, inclusive).

add_rows

add_rows(number: int) -> None

Grow the grid by number rows.

add_cols

add_cols(number: int) -> None

Grow the grid by number columns.

resize_rows

resize_rows(start: int, end: int, pixels: int) -> None

Row height for rows start..end.

resize_cols

resize_cols(start: int, end: int, pixels: int) -> None

Column width for columns start..end.

hide_rows

hide_rows(start: int, end: int | None = None) -> None

Hide rows.

unhide_rows

unhide_rows(start: int, end: int | None = None) -> None

Show hidden rows.

hide_cols

hide_cols(start: int, end: int | None = None) -> None

Hide columns.

unhide_cols

unhide_cols(start: int, end: int | None = None) -> None

Show hidden columns.

sort_range

sort_range(range: str, *specs: tuple[int, str]) -> None

Sort by columns: sort_range("A2:C100", (1, "asc"), (3, "desc")).

set_basic_filter

set_basic_filter(range: str | None = None) -> None

Turn on the filter (whole sheet by default).

clear_basic_filter

clear_basic_filter() -> None

Turn off the filter.

copy_to

copy_to(destination_spreadsheet_id: str) -> Any

Copy this tab into another spreadsheet.

update_note

update_note(cell: str, text: str) -> None

Set a cell note.

clear_note

clear_note(cell: str) -> None

Remove a cell note.

get_note

get_note(cell: str) -> str

A cell's note ("" if none).

define_named_range

define_named_range(name: str, range: str) -> None

Name a range of this sheet (see Spreadsheet.list_named_ranges).

list_protected_ranges

list_protected_ranges() -> list[dict[str, Any]]

Protected ranges of this sheet.

delete_protected_range

delete_protected_range(protected_range_id: str | int) -> None

Remove a protection (ID from protect() or list_protected_ranges()).

set_developer_metadata

set_developer_metadata(key: str, value: str, visibility: str = 'DOCUMENT') -> None

Attach a key/value to this sheet (hidden from users).

add_chart

add_chart(chart_type: str, domain: str, series: list[str], *, title: str | None = None, anchor_cell: str = 'A1', legend: str = 'BOTTOM_LEGEND') -> int | None

Embedded chart (COLUMN, BAR, LINE, AREA, PIE, SCATTER, ...); returns its ID.

delete_chart

delete_chart(chart_id: int) -> None

Remove an embedded chart.

add_pivot_table

add_pivot_table(source: str, anchor_cell: str, *, rows: list[int], values: list[tuple[int, str]], columns: list[int] | None = None) -> None

Pivot table at anchor_cell over source; values are (column, "SUM"|"COUNTA"|...).

set_banding

set_banding(range: str, *, first_color: Color, second_color: Color, header_color: Color | None = None) -> int | None

Alternating row colors; returns the banding ID.

delete_banding

delete_banding(banded_range_id: int) -> None

Remove alternating colors.

read_dataframe

read_dataframe(skiprows: int = 0, *, drop_empty_rows: bool = False, drop_empty_cols: bool = False, index_col: str | None = None) -> Any

The sheet as a DataFrame of the client's backend (Sheets(dataframe_backend=...)).

Needs gsuite-sdk[pandas] or gsuite-sdk[polars].

write_dataframe

write_dataframe(df: Any, include_header: bool = True, clear: bool = True, *, start_cell: str | None = None, include_index: bool = False) -> Any

Write a pandas or polars DataFrame (from A1 or start_cell).

to_dataframe

to_dataframe(header_row: int = 1) -> pd.DataFrame

Read the worksheet into a pandas DataFrame (needs gsuite-sdk[pandas]).

Parameters:

Name Type Description Default
header_row int

Row with column names (1-indexed); rows above it are skipped

1

Values come back as displayed text; convert types in pandas as needed.

from_dataframe

from_dataframe(df: DataFrame, start: str = 'A1', include_header: bool = True, include_index: bool = False, clear: bool = False, value_input: ValueInput = 'USER_ENTERED') -> dict

Write a pandas DataFrame starting at start.

NaN/None become empty cells and dates are written as ISO strings.

Parameters:

Name Type Description Default
clear bool

Clear the worksheet first (otherwise old cells outside the new data remain)

False

AsyncSheets

AsyncSheets(auth: Any, *, timeout: float | None = None, batch_cell_limit: int | None = 50000, transport: Any = None)

Entry point: open, create, copy and delete spreadsheets.

Parameters:

Name Type Description Default
auth Any

GoogleAuth (OAuth or service account) or google-auth credentials

required
timeout float | None

Seconds per request (default: GSUITE_REQUEST_TIMEOUT)

None
batch_cell_limit int | None

Split big writes into requests of at most this many cells

50000
transport Any

httpx transport (tests)

None

aclose async

aclose() -> None

Close the HTTP connection pool.

open async

open(title: str) -> AsyncSpreadsheet

Open by title (searches Drive).

open_by_key async

open_by_key(key: str) -> AsyncSpreadsheet

Open by ID.

open_by_url async

open_by_url(url: str) -> AsyncSpreadsheet

Open by URL.

create async

create(title: str, folder_id: str | None = None) -> AsyncSpreadsheet

Create a spreadsheet.

copy async

copy(spreadsheet_id: str, title: str | None = None, copy_permissions: bool = False, folder_id: str | None = None) -> AsyncSpreadsheet

Copy a spreadsheet (optionally with its sharing, except ownership).

delete async

delete(spreadsheet_id: str) -> None

Delete a spreadsheet permanently.

list_spreadsheets async

list_spreadsheets(title: str | None = None) -> list[dict[str, Any]]

Spreadsheets visible to the user ({id, name}).

AsyncWorksheet

AsyncWorksheet(spreadsheet: AsyncSpreadsheet, title: str, sheet_id: int)

A tab. Values, streaming, tables and typed rows, async.