Skip to main content
GuideServerConfigure and deploy Tabsdata servers on your machine.TutorialsConfigure data integration workflows within a running Tabsdata server.Advanced TutorialsBuild end-to-end workflows between two specific systems.API ReferenceCLI ReferenceRelease Notes
Version: 2.0.0

Publish data from Google Cloud Storage

Ingest objects from a bucket

Each entry in paths fills one input slot and produces one output table. Credentials are a service account JSON key rather than an id and secret pair, so the whole key goes in as one value.

warning

There are several ways to pass secrets into Tabsdata. See Secrets Management for more info if you are planning to have an LLM register secrets into Tabsdata's credential store.

Can you publish departments.csv and the monthly employees files out of google cloud storage

Listed 1 directory, called tabsdata 3 times (ctrl+o to expand)

The GCS publisher guide and connection template are loaded. Four values left, then I generate and register. Reply with them one per line, or point me at a file that has them:

  • collection name
  • bucket and project
  • service account JSON key
  • object names or patterns
everything you need is in

Read 2 files, called tabsdata 2 times (ctrl+o to expand)

Service account key read from ~/acme-sa.json and held as one secret value. Reading back what is not secret: bucket acme-ingest, project acme-analytics, collection hr_src, base path /hr.

Called tabsdata 4 times (ctrl+o to expand)

Connection written to , and collection hr_src created from it in group sources with base_path /hr. Connection check passed. employees_*.csv matches 3 objects under /hr:

  • employees_2026_01.csv
  • employees_2026_02.csv
  • employees_2026_03.csv

Called tabsdata 2 times (ctrl+o to expand)

The publisher, registered in hr_src. The exact name returns its one frame, and the glob folds its three with concat():

@publisher(
source=GCSSrc(
paths=["departments.csv", "employees_*.csv"],
initial_last_modified="2026-01-01T00:00:00Z",
),
output_tables=["departments", "employees"],
)
def read_hr(
departments: TableFramesSpec,
employees: TableFramesSpec,
) -> tuple[TableFrameSpec, TableFrameSpec]:
return (departments[0], concat(employees))

Called tabsdata 6 times (ctrl+o to expand)

Execution committed, 0 failures.

Two tables are live in hr_src. initial_last_modified was set to the start of the year, so this first run took only objects modified since then:

┌─────────────┬────────────────────────────────────┬───────┬─────────┐
    table                    from                 rows   columns 
├─────────────┼────────────────────────────────────┼───────┼─────────┤
 departments  departments.csv                     14     3       
├─────────────┼────────────────────────────────────┼───────┼─────────┤
 employees    3 objects matching employees_*.csv  3,612  11      
└─────────────┴────────────────────────────────────┴───────┴─────────┘

The cutoff advances on its own after that first run, so each later trigger reads only what arrived since the previous one. Paths resolve against the connection's base_path, so the publisher names objects and never the bucket.