Models

A model consists of code that populates a single table or view, along with metadata properties that define how your users can interact with the model.

Models define a data processing step and frequently represent some bit of business logic. They can be written in SQL or Python. Models can reference each other, and SBT will automatically build your complete data processing pipeline by parsing the model code for dependencies. A bundle of models powers an app on the Insight Cloud platform.

Models all live in the models/ directory of your SBT project. A model consists of two parts:

  • A definition — a python or sql file that contains the code for that model. The name of the file will become the unique identifier for the model.

  • A configuration — a yaml block that contains metadata for the model. Must have a named config matching the model name from the definition file.

Example

Directory structure:

sbt-project/
├── sources/
│   └── sources.yml
└── models/
    ├── my_first_model.sql
    └── configs.yml

The model definition is a SQL file. It uses standard SQL plus some special syntax to access the Seek Run Context object (the seek object) for sources, variables, and other model outputs — all compiled at runtime.

my_first_model.sql

select
  src.*,
  '{seek.params[TEST_VAR]}' as user_param_value
from {seek.sources[vendor.table]} src

configs.yml

models:
  - name: my_first_model
    config:
      language: sql
      materialized: table
      type: output
      variables:
        - name: TEST_VAR
          display_name: Test Variable
          type: VARCHAR
          default: No test var set
          values_query: values_test

Model Configs

The model config lives in yaml. The filename doesn't matter — one central yaml or many nested ones both work; SBT searches all yaml files for models: keys.

Model Object Fields

Field

Description

Available Values

name

The name of the model, must be unique. Used as the name of tables created by this model.

string, unique

config.packages

Python packages installed in the model's runtime environment. On the beta path these must be Anaconda-channel names. See Dependencies.

list of strings

config.py_modules

Python wheel files attached to the model at deploy time. Files live in the modules/ directory. See Dependencies.

list of strings

config.materialized

The type of db object to create in Snowflake

table or view

config.language

The language of the model

python or sql

config.type

The type of model

output, mapping, or shared — see Model types below

config.write_mode

How output is written

overwrite (default)

config.visibility

Whether the output is exposed to consumers

public (default) or private

config.sigma_table_attribute

The Sigma user attribute that will carry this model's output table name for dashboards

string

config.variables

Variables users can set when running the app

list of objects (below)

config.max_age

Skip runs whose output is still fresh — see Model Reuse

object

Model Variable Fields

Field

Description

Available Values

name

The name of the variable. Your model reads it via seek.params['NAME'].

string

display_name

The name shown to users in Insight Cloud

string

type

The Snowflake data type of the variable

string

default

The default value

string / number

values_query

Name of a helper query (a .sql file in helpers/) returning the allowed values; powers the dropdowns in Insight Cloud. Must return exactly two columns aliased value and label.

string

rls

Marks this variable as a row-level security parameter. Requires a values_query. See RLS Parameters.

true / false (default false)

is_bundled

Marks this variable as backed by a bundled source

true / false (default false)

A variable does nothing on its own. It only affects output if the model's code reads it (seek.params[...]). A variable no model reads will appear in the variant UI but change nothing.

Seek Run Context

Models access the platform through an object called seek with properties for sources, params, other models, and run context:

class SeekRunCtx(BaseModel):
    model_name: str
    target_name: str
    current_db: str
    params: dict
    sources: dict
    models: dict

Model Definition

SQL Models

SQL models are select statements in a .sql file, eventually wrapped in CREATE TABLE/VIEW AS SELECT. Wrap references to the run context in single curly braces (the SQL is formatted by Python at runtime):

SELECT * EXCLUDE EPOCH
       RENAME "ITEM NBR" AS item_nbr
FROM {seek.sources[retail_sales.item_list_custom]}

Note: for SQL models, don't quote the source/model/param name you are accessing inside the braces.

Python Models

Python models are .py files containing a function called model that takes session (a Snowpark session) and seek (the run context), and returns a data frame (Snowpark or pandas).

def model(session, seek):
    from snowflake.snowpark.functions import lit

    base_table = session.table(seek.sources["atlas.view_items"])
    pivot_values = base_table.select("Brand Desc").distinct()
    var_df = pivot_values.with_column("vars", lit(seek.params["TEST_VAR"]))
    return var_df

How models execute

SBT Beta (--beta publish): models run as Snowflake stored procedures, orchestrated directly by Insight Cloud. The platform builds each procedure by inlining your model file into the procedure body.

⚠️ Because of this, beta model files must contain no top-level statements other than def model(session, seek):. In particular, from sbt.models import model (the decorator style) at the top of a file will build and publish without error, but every deployed run will fail with ModuleNotFoundError: No module named 'sbt' — the sbt package does not exist inside Snowflake. Local sbt run-app still works, which makes this easy to miss. Put ALL imports inside the model function, and supply third-party packages via packages and py_modules (see Dependencies).

SBT 1.0 (non-beta publish): models run inside the app's container, where the decorator style is supported. Outputs still land as tables or views in Snowflake.

All current production apps are beta: use the yaml-config style with a bare def model(session, seek): function.

App versions come from your config

The version: in your app config yaml is the source of truth — building does not auto-increment anything. Full build/publish flow: App Publishing Lifecycle.

Model types (SBT 1.0)

SBT 1.0 models have a type: output (computed per variant, parameters allowed), mapping (computed once per subscribing organization), or shared (computed once for all subscribers, always private). The legacy data_mapping is still accepted and treated as mapping. See Model Reuse: Freshness and Shared Models.

Model visibility (SBT 1.0.10+)

Models and sources accept an optional visibility setting:

visibility: public   # default
# or
visibility: private

Public outputs appear in the Data layer, app consumption interfaces, and the app context. Private outputs are hidden from direct consumption — use them for intermediate tables. Local runs are not affected. (An earlier issue where marking an installed app's model private did not hide the table was fixed in July 2026; report stragglers through Contact Us.)

Model-level freshness (SBT 1.0)

An optional max_age setting skips model runs whose outputs are still current. See Model Reuse: Freshness and Shared Models.

Related articles

⏭️ Next: Model Reuse: Freshness and Shared Models