Skip to main content

Constellations

dbt for unstructured data. Constellations — installed and invoked as stel — brings the dbt workflow of declarative models, a dependency DAG, ref(), tests, incremental builds, lineage, and a manifest artifact to folders of documents: PDFs, markdown, HTML, JSON, email, and free-form text.

dbt users will recognize the workflow: declare sources and models in YAML, build a DAG, materialize incrementally, test the results, and emit artifacts. stel is a standalone CLI rather than a dbt package or dbt adapter.

Status: active pure-Python preview. Shipped capabilities include DuckDB and BigQuery warehouses, local and GCS sources, metadata-aware deterministic chunk models, record-scoped incremental state, bounded projected warehouse snapshots, an incremental local LanceDB search sink, classic text ML, and six extraction backends. See docs/reference.md for the full reference.

Platform scope

The active platform roadmap is intentionally narrow:

  • Warehouses: DuckDB is the default and reference adapter, and MotherDuck (path: md:<database>) is shipped as its managed deployment — the same adapter and capability contract. BigQuery is shipped; Snowflake is planned.
  • Retrieval: LanceDB is the supported reference store. Additional hosted retrieval-store integrations are not currently planned.
  • Embedded dbt execution: dbt-duckdb only. BigQuery and future Snowflake support use the standalone CLI and dbt source handoff.

Existing inference providers and extraction backends remain supported; this scope governs new platform work rather than removing shipped functionality.

What a pipeline looks like

A project that turns a folder of invoice PDFs into a structured, queryable table — extract the text with pypdf, then use an LLM to pull typed fields:

flowchart LR
    src[("invoice_pdfs<br/><i>source: *.pdf</i>")]
    raw["raw_pdf_text<br/><i>pdf backend · incremental</i>"]
    extracted["extracted_invoices<br/><i>llm transform · cached</i>"]
    src --> raw --> extracted

Each node is a model declared in YAML. The source globs a folder; raw_pdf_text extracts text per document; extracted_invoices calls Claude to turn that text into typed columns — and caches the result so re-runs are free.

The source

# sources/invoices.yml
version: 2
sources:
  - name: invoice_pdfs
    path: "./data/invoices_pdf/"
    file_pattern: "*.pdf"

The extraction model

# models/raw_pdf_text.yml
version: 2
models:
  - name: raw_pdf_text
    source: ref('invoice_pdfs')
    extraction:
      backend: pdf
    materialization: incremental      # re-run only reprocesses changed PDFs
    tests:
      - not_null: [text]
      - unique: source_path

The transform model

# models/extracted_invoices.yml
version: 2
models:
  - name: extracted_invoices
    depends_on: [ref('raw_pdf_text')]
    transform:
      type: python
      module: transforms.llm_extract  # a Polars function you write
    tests:
      - not_null: [vendor, invoice_id, total]
      - unique: invoice_id

Run it

uv run stel init invoices --template pdf   # scaffold a project
# drop your PDFs into ./invoices/data/invoices_pdf/  (or `stel seed` synthetic ones)
cd invoices
uv run stel run                            # build the DAG into DuckDB
uv run stel test                           # run the schema tests
uv run stel show raw_pdf_text               # peek at the scaffolded result
model                 kind        mater.         processed   skipped  deleted    rows   time(s)
-----------------------------------------------------------------------------------------------
raw_pdf_text          extraction  incremental            5         0        0       5     0.31

Why stel

Imperative Python (LlamaIndex) Managed RAG (Cortex Search, Bedrock KB) stel
Declarative models + DAG partial
Tests on extracted data
Incremental / cached DIY
Inspect & swap each stage
Lineage / manifest artifact partial
Reviewable like a dbt PR
Composes with existing dbt partial

stel isn't trying to win on time-to-first-demo (managed services do) or raw flexibility (LlamaIndex does). It wins on reproducibility, testability, and fitting the workflow analytics engineers already use.

What's in the box

  • Six extraction backendsjson, markdown, pdf, html, email, and llm (Claude tool-use with response caching).
  • Built-in text/ML preprocessing — token counting, encoding repair, normalized spaCy token/entity child tables, deterministic entity linking to canonical IDs via alias tables, document-level aggregate features, language detection, text statistics, near-duplicate detection (MinHash), and PII redaction (Microsoft Presidio).
  • Warehouse and source adapters — DuckDB or BigQuery materialization, with local files or generation-pinned GCS objects as source documents.
  • RAG and classic ML primitives — deterministic recursive/token chunking; count, TF-IDF, and hashing features; and naive Bayes text classification.
  • dbt-shaped everythingref(), --select / --exclude selectors with tag: support, structural and deterministic quality tests, custom-Python tests, warn/error severities, source freshness, and profiles with --target.
  • Compile before I/O — strict per-backend and classic-ML contracts fail before source discovery or warehouse access, with file, line, column, and configuration-path diagnostics for invalid YAML.
  • Artifactsmanifest.json, run_results.json, a static docs site, and emit-dbt-sources to hand tables to a dbt project using the matching DuckDB or BigQuery adapter.
  • Composes with dbt — stel does the unstructured → structured "E"; dbt does the SQL "T", reading stel's tables as native sources.

Install

uv add stel
# Optional cloud integrations:
uv add 'stel[bigquery,gcs]'

Quickstart

git clone https://github.com/C00ldudeNoonan/dbt-ml constellations
cd constellations/stel
uv sync
uv run stel --project-dir examples/invoice_pipeline seed --count 5
uv run stel --project-dir examples/invoice_pipeline run
uv run stel --project-dir examples/invoice_pipeline test

Fifteen examples live in examples/, covering invoices, blog posts, support tickets, arXiv quality checks, PDF and direct LLM extraction, classic text ML, document clustering, RAG chunks, governed SQL chunks, dbt handoff and embedded execution, and a metric-plus-evidence agent.

Security model

Only run projects you trust: Python transforms and custom tests execute in the stel process. Project-controlled paths are confined to the project unless an explicit external: true boundary is supported; local source patterns cannot traverse parents or symlinks. Profiles select destinations and opaque credential references and must be reviewed as trusted configuration; credential values and reference names stay out of artifacts and diagnostics. The LLM backend sends document text to Anthropic using the configured environment variable, and the PII transform retains non-target input columns unless you explicitly project or drop them. stel clean removes known local artifacts without resetting a warehouse. See the full security notes before running third-party projects or sensitive documents.

Documentation

  • Full reference — every backend, command, config block, and the roadmap.
  • Contributing — how to add a backend, test, or command.
  • Semantic retrieval architecture — the search: resource and retrieval-store contract, including the shipped local LanceDB proof of concept and its fail-closed boundaries.
  • Provider abstraction — the inference/embedding provider contract, plus the accepted plugin discovery, provider-owned configuration, and failed-outcome accounting design (issue #71).
  • Warehouse-native SQL models — implemented transform.type: sql contract (compiled ref(), the SQL/Jinja trust boundary, and full/incremental adapter materialization).
  • Changelog

License

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

stel-0.12.0.tar.gz (1.7 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

stel-0.12.0-py3-none-any.whl (995.9 kB view details)

Uploaded Python 3

File details

Details for the file stel-0.12.0.tar.gz.

File metadata

  • Download URL: stel-0.12.0.tar.gz
  • Upload date:
  • Size: 1.7 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for stel-0.12.0.tar.gz
Algorithm Hash digest
SHA256 e083e4cf486109a1cd7591e99146e216a0395445e469fdc1be6e409264630da5
MD5 5d7b2b513b86d87019db95932e75e979
BLAKE2b-256 d9ffd8597003f2197c8c92c3493892301f05f5f252fd56a90b097f6f9ab969ea

See more details on using hashes here.

File details

Details for the file stel-0.12.0-py3-none-any.whl.

File metadata

  • Download URL: stel-0.12.0-py3-none-any.whl
  • Upload date:
  • Size: 995.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for stel-0.12.0-py3-none-any.whl
Algorithm Hash digest
SHA256 2414f12281778168f7b338ba7f84bfb7e0cd10049f1534be82da825f626147c1
MD5 f047e999bd899d569a6c85fa0f13c768
BLAKE2b-256 90976c4e05a06a110270e3460051406832f39bf13893ef0f16c3749efe708f2c

See more details on using hashes here.

Release history Release notifications | RSS feed

0.17.0

2 files

0.16.0

2 files

0.15.5

2 files

0.15.4

2 files

0.15.3

2 files

0.15.2

2 files

0.15.1

2 files

0.15.0

2 files

0.14.0

2 files

0.13.0

2 files

This release

0.12.0 This release

2 files

0.11.0

2 files

0.10.0

2 files

0.9.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page