17 toolsOAuth bearer
gsheets_example.py
Sheet1!A1:C10 — and on get, update, append and clear they travel in
the URL path.
Sheets speaks protobuf JSON, which is a poor thing to hand a model. Two Format
markers absorb that: the model sends a plain 2-D array and a list of field paths,
and the API receives the encodings it expects.
Authenticating
This pack takes a Google OAuth bearer token, andconfigure() is optional when $GOOGLE_ACCESS_TOKEN is set. Which credential provider you hand it depends on whose account the calls run as.
Refer to Google’s provider page for the “GOOGLE” constant the snippets below name, the scopes these 17 tools ask for, and this server’s refresh behaviour.
A token you hold
For a script, or a notebook.EnvTokenProvider re-reads the variable on every call, so a token rotated beside the process is picked up without a restart; StaticTokenProvider takes one you already hold as a string. Neither renews anything, so the calls stop when the token expires.
gsheets_script.py
One account, refreshed
For an agent or a server acting as you.OAuth2Client turns a client registration and a stored refresh token into an access token, and renews it before it lapses.
gsheets_agent.py
No refresh token yet? Your own account is the one-time consent flow that hands you one.
Many end users
For a product whose users each connect their own account.SubjectProvider builds one credential per user through a factory you write, and use_subject names the user a call acts for. Your users’ accounts is the consent route inside your app; serving many users is the per-subject cache and its eviction.
gsheets_server.py
The client
oauth_tool_factory is the whole client: a thin wrapper over httpx that attaches your token and these endpoint constants to each request. google-api-python-client and google-auth do not enter your dependency tree.credentials is whichever of the three you built in Authenticating. A pack takes it through configure(); a client you build takes the same object as credential_provider, and has no configure() of its own.
Tools
Each is aTool, called with
ainvoke as in the snippet above. The name
links to its parameters, its response and what it costs.
Valuesspreadsheets_values_getGETReturns a range of values from a spreadsheet.spreadsheets_values_updatePUTSets values in a range of a spreadsheet.spreadsheets_values_appendPOSTAppends values to a spreadsheet.spreadsheets_values_clearPOSTClears values from a spreadsheet.spreadsheets_values_batch_getGETReturns one or more ranges of values from a spreadsheet.spreadsheets_values_batch_updatePOSTSets values in one or more ranges of a spreadsheet.spreadsheets_values_batch_clearPOSTClears one or more ranges of values from a spreadsheet.values_batch_get_by_data_filterPOSTReturns one or more ranges of values that match the specified data filters.values_batch_update_by_data_filterPOSTSets values in one or more ranges of a spreadsheet.values_batch_clear_by_data_filterPOSTClears one or more ranges of values from a spreadsheet.Spreadsheetsspreadsheets_createPOSTCreate a new spreadsheet.spreadsheets_getGETGet spreadsheet metadata and structure.spreadsheets_batch_updatePOSTApply a list of updates to a spreadsheet.spreadsheets_sheets_copy_toPOSTCopy a single sheet from one spreadsheet to another.spreadsheets_get_by_data_filterPOSTGet a spreadsheet, selecting which ranges to return with DataFilters (an A1 range, a GridRange, or developer metadata).Developer metadataspreadsheets_developer_metadata_getGETGet one developer metadata entry by its spreadsheet-scoped ID.spreadsheets_developer_metadata_searchPOSTFind developer metadata matching one or more DataFilters.
Every tool declares quota_cost 1. Sheets meters requests per minute per user
rather than charging different amounts per call, so a uniform 1 is the honest
number; the link in the wire table is where the real limits live.
The two transforms
ValueRange.values is marked Format("proto_json"). The model sends what anyone
would write by hand:
gsheets_append_rows.py
fields on the batchUpdate requests is marked Format("field_mask"). A
FieldMask is a comma-joined string on the wire and a list of paths in the
schema, so the model sends ["userEnteredValue", "userEnteredFormat"] and Sheets
receives userEnteredValue,userEnteredFormat. See transforms.
Gotchas
value_input_option decides whether a formula is a formula
value_input_option decides whether a formula is a formula
RAW writes =SUM(A1:A2) as the literal nine characters. USER_ENTERED
parses it the way typing it into the cell would — which also means 1/2
becomes a date and a leading + becomes a formula. The argument is required
on spreadsheets_values_append, spreadsheets_values_update and the batch
writes, deliberately: there is no safe default, and the wrong one is silent.Append writes after the last row of a detected table, not at the range
Append writes after the last row of a detected table, not at the range
The
range you pass to spreadsheets_values_append is a search hint:
Sheets finds the table that overlaps it and appends below that table’s last
row. Passing Sheet1!A1 does not mean “write at A1”. To write at an exact
address, use spreadsheets_values_update.Nothing in this pack pages
Nothing in this pack pages
Sheets has no cursor. A large sheet is read by asking for a narrower A1
range, which is why no tool here declares a
Pagination — and why
next_page_args on these tools would have nothing to return.Range is a path parameter, so it is URL-encoded
Range is a path parameter, so it is URL-encoded
Sheet1!A1:C10 goes into the path, and a sheet name containing a space or an
apostrophe needs Sheets’ own quoting — 'My Sheet'!A1:C10. The escaping for
the URL is handled; the quoting for Sheets’ grammar is yours.spreadsheets_create takes the whole spreadsheet object
spreadsheets_create takes the whole spreadsheet object
Its one argument is
spreadsheet, the same resource spreadsheets_get
returns. Titles, sheet tabs and initial data all go inside it; there is no
flat title shortcut.Related
- Google — consent screen, scopes, refresh
- Transforms —
proto_jsonandfield_maskin detail