Data Sources & Snapshots
Data sources
Section titled “Data sources”A data source is a named dataset attached to a model. Data can come from:
- CSV/Excel upload — via
ingest_file_upload(max 100 MB) - Google Sheets — via
refresh_google_sheet_snapshot(Picker-connected sheet)
All uploaded data is converted to Parquet format and stored in S3. Each upload creates an immutable snapshot.
Snapshots
Section titled “Snapshots”A snapshot is a point-in-time copy of your data. When a model runs, it mounts the most recent snapshot for its data sources.
Why snapshots?
Section titled “Why snapshots?”- Reproducibility — re-running a model against the same snapshot produces the same results
- Audit trail — you can see exactly which data a model run used
- Safety — uploading new data doesn’t retroactively change past runs
Snapshot tools
Section titled “Snapshot tools”| Tool | Description |
|---|---|
list_data_sources with include_snapshots=true | List current, historical, detached, and reclaimed generations for one data source using opaque snapshot_id values |
remove_data_source with action='detach' | Disconnect a data source from future runs while retaining its snapshot lineage |
remove_data_source with action='delete_snapshot' | Delete one unreferenced, non-current snapshot by opaque snapshot_id |
Discovering data sources
Section titled “Discovering data sources”Before writing a query_data SQL statement, use list_data_sources to see all data sources attached to a model, their DuckDB table names, and column schemas. This avoids guessing table or column names:
list_data_sources → inspect tables/columns → query_datalist_data_sources returns one entry per source with tables (exact DuckDB table names to use in SQL) and schema (column names and types per table). Ready browser-uploaded CSVs use their logical source name as a table. For Google Sheet sources, snapshot_taken_at shows when the data was last synced — call refresh_google_sheet_snapshot to refresh stale snapshots.
Querying data
Section titled “Querying data”The query_data tool lets you run read-only SQL (SELECT/WITH) against your data sources via DuckDB. It supports browser-uploaded/ingested CSVs, uploaded Parquet files, and Google Sheet snapshots:
- Browser-uploaded or ingested CSV files — table name is the
source_namegiven at upload time. - Uploaded Parquet files (
ingest_file_upload) — table name is thesource_namegiven at upload time. - Google Sheet snapshots (
refresh_google_sheet_snapshot) — each tab becomes a table named{source_name}_{tab_name}(non-alphanumeric characters in the tab name are replaced with underscores).
-- Query an uploaded Parquet file (source_name = "revenue_data"):SELECT product_line, SUM(revenue) AS totalFROM revenue_dataGROUP BY product_lineORDER BY total DESCLIMIT 10
-- Query a linked Google Sheet (source = "budget", tab = "Q1 Revenue"):SELECT * FROM budget_Q1_Revenue LIMIT 10Results are capped at 10,000 rows. The sources field in the response lists each loaded source, its DuckDB table names, and snapshot_taken_at (for Google Sheet sources) so you can verify freshness.
Google Sheets integration
Section titled “Google Sheets integration”The refresh_google_sheet_snapshot tool snapshots a Picker-connected Google Sheet into a model:
- Bridge Town reads the specified tabs (or all tabs)
- Converts each tab to CSV, uploads to S3 as Parquet
- Records the snapshot metadata for future model runs and freshness checks
The sheet must be connected once through the Bridge Town web app (Picker-based
OAuth) before the tool can run. Bridge Town uses drive.file scope — it can
only access Sheets you explicitly selected or that it created for you.
After running a model, publish outputs with publish_run_output_to_google_sheet.
Start with confirmed=false to receive a bounded preview, then repeat with
confirmed=true after reviewing the explicit source_name or
spreadsheet_id, tab-qualified cell_range, and row count.
mode="replace"— writes to a targeted A1 notation range (e.g."Forecast!A1"or"Sheet1!B2:F20"). Only cells within the output rectangle are overwritten; content outside is preserved.mode="append"— adds rows after existing content in the named tab without overwriting.
For already-materialized values, use append_google_sheet_rows. To create an
empty linked Sheet, use create_google_spreadsheet with a title and
source_name.