Metadata-Version: 2.4
Name: database-tycoon
Version: 0.1.3
Summary: Database Tycoon — local-first analytics CLI that adapts to your existing data stack
Project-URL: Homepage, https://github.com/Database-Tycoon/tycoon-cli
Project-URL: Repository, https://github.com/Database-Tycoon/tycoon-cli
Project-URL: Issues, https://github.com/Database-Tycoon/tycoon-cli/issues
Author: Database Tycoon Team
License: MIT
License-File: LICENSE
Keywords: analytics,cli,data,dbt,dlt,duckdb
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Database
Requires-Python: >=3.12
Requires-Dist: dbt-core==1.11.8
Requires-Dist: dbt-duckdb==1.10.1
Requires-Dist: dlt[duckdb]==1.26.0
Requires-Dist: duckdb==1.5.2
Requires-Dist: httpx==0.28.1
Requires-Dist: pydantic==2.13.3
Requires-Dist: pyyaml==6.0.3
Requires-Dist: rich==15.0.0
Requires-Dist: typer==0.25.0
Provides-Extra: ask
Requires-Dist: ibis-framework[duckdb]==12.0.0; extra == 'ask'
Requires-Dist: nao-core==0.1.8; extra == 'ask'
Provides-Extra: dagster
Requires-Dist: dagster-dbt==0.29.2; extra == 'dagster'
Requires-Dist: dagster-dlt==0.29.2; extra == 'dagster'
Requires-Dist: dagster-webserver==1.13.2; extra == 'dagster'
Requires-Dist: dagster==1.13.2; extra == 'dagster'
Provides-Extra: server
Requires-Dist: fastapi==0.136.1; extra == 'server'
Requires-Dist: uvicorn[standard]==0.46.0; extra == 'server'
Requires-Dist: websockets==16.0; extra == 'server'
Description-Content-Type: text/markdown

# tycoon

A pip-installable CLI that wires dlt → DuckDB → dbt → Rill into a working local analytics stack. No Docker, no cloud account required.

**Adaptable**: bring your own ingestion (Airbyte, Fivetran), warehouse (Snowflake, BigQuery, MotherDuck), dbt project, BI tool, or orchestrator — `tycoon init` asks before it assumes.

---

## Install

Requires Python >= 3.12.

```bash
pip install database-tycoon
# or
uv add database-tycoon
```

Optional extras:

```bash
pip install "database-tycoon[dagster]"   # Dagster orchestration
pip install "database-tycoon[ask]"       # AI natural language queries (Ollama supported)
```

---

## Quickstart

The fastest path to a working dashboard uses the PokéAPI — no credentials, no signup.

```bash
# 1. Create a project
mkdir my-project && cd my-project
tycoon init --template csv-import

# 2. Add the PokéAPI as a source (press Enter twice for defaults)
tycoon data sources add rest_api

# 3. Ingest into DuckDB
tycoon data sources run pokeapi

# 4. Scaffold dbt models and generate Rill dashboards
tycoon data analyze pokeapi --rill

# 5. Open Rill
tycoon start --only rill
```

Rill opens at `http://localhost:9009` with `pokemon`, `berry`, and `type` tables ready to explore.

Already have a pipeline? `tycoon init` will ask about your ingestion tool, warehouse, dbt project, BI tool, and orchestrator — and configure itself around what you already have.

---

## CLI Reference

| Command | Description |
|---|---|
| `tycoon init` | Scaffold a new project |
| `tycoon data sources catalog` | Browse available source integrations |
| `tycoon data sources add <type>` | Register a new data source |
| `tycoon data sources list` | List sources configured in this project |
| `tycoon data sources list show <name>` | Show detailed config for a source |
| `tycoon data sources run <name>` | Run ingestion for a named source |
| `tycoon data sources run-all` | Run ingestion for all sources |
| `tycoon data transform run` | Run dbt transformations |
| `tycoon data analyze <source>` | Scaffold dbt staging models; add `--rill` to also generate dashboards |
| `tycoon data db query <sql>` | Run a SQL query against the warehouse |
| `tycoon data run-all` | Ingest all sources then run dbt build |
| `tycoon data status` | Show freshness, row counts, and capture counts for each source |
| `tycoon data history` | List recent dlt + dbt runs from the observability metadata DB |
| `tycoon data history show <id>` | Per-run detail (per-table rows for dlt, per-node status for dbt) |
| `tycoon start` | Start Rill, Dagster, Nao, and the web UI |
| `tycoon stop` | Stop all services |
| `tycoon ask chat` | Query your data in natural language (Nao) |
| `tycoon ask context` | Print synced table/schema context as markdown (pipe into any agent) |
| `tycoon run <tool>` | Passthrough to dbt, dlt, rill, dagster |

---

## tycoon.yml Reference

```yaml
name: my-project
version: 0.1.0

database:
  raw: data/raw.duckdb              # dlt output (or md: URI for MotherDuck)
  warehouse: data/warehouse.duckdb  # dbt output — read by Rill and Nao

dbt_project_dir: dbt_project   # path to dbt project (yours or tycoon-scaffolded)
rill_dir: rill                 # path to Rill dashboard definitions

stack:                         # generated by tycoon init — edit as needed
  ingestion: dlt               # dlt | airbyte | fivetran | meltano | none
  ingestion_managed: true      # false = tycoon won't run `data sources run`
  warehouse: duckdb            # duckdb | motherduck | snowflake | bigquery | other
  transformation_managed: true # false = tycoon won't scaffold or overwrite dbt
  bi: rill                     # rill | metabase | looker | tableau | other | none
  bi_managed: true             # false = tycoon won't start Rill
  orchestrator: dagster        # dagster | airflow | prefect | other | none
  orchestrator_managed: true   # false = tycoon won't start Dagster

sources:
  my-github:
    type: github               # matches a catalog source name
    schema: raw_github         # schema name in the raw DuckDB file
    config:
      access_token: ${GITHUB_TOKEN}   # env vars are interpolated
      owner: my-org
      repo: my-repo

ask:                           # optional — requires tycoon[ask]
  llm:
    provider: ollama           # fully local, no API key required
  port: 5005
```

Each source produces its own raw DuckDB file: `data/raw_<source>.duckdb`. All sources write into `data/warehouse.duckdb` after transformation.

### MotherDuck authentication

`tycoon doctor` recognizes two MotherDuck auth modes for a `stack.warehouse: motherduck` project:

- **`MOTHERDUCK_TOKEN` env var** — use this for CI, Tower, Dagster, or any non-interactive path. Get one at [app.motherduck.com/token](https://app.motherduck.com/token).
- **Cached OAuth session** — run `duckdb -c "ATTACH 'md:'"` once locally to authenticate via browser; DuckDB caches the token under `~/.duckdb/` and tycoon picks it up from there.

---

## Catalog Sources

These sources are available via `tycoon data sources add <name>`. They are downloaded on demand via `dlt init` and not bundled in the package.

| Source | Category | Key Tables |
|---|---|---|
| `github` | Developer | commits, issues, pull_requests, repositories |
| `slack` | Communication | channels, messages, users |
| `stripe` | Finance | customers, invoices, products, subscriptions |
| `hubspot` | CRM | companies, contacts, deals, tickets |
| `notion` | Knowledge | databases, pages, users |

---

## Data Directory

Raw DuckDB files follow the naming convention `raw_<source>.duckdb` (written by ingestion) while `warehouse.duckdb` is the single transformed database read by Rill and Nao. See `data/README.md` for details.

---

## Rill Dashboards

Rill is a local-first BI tool. Dashboard definitions are YAML files in the `rill/` directory.
Launch Rill via `tycoon start` or `tycoon start --only rill`.

Auto-generate dashboards for a source after ingestion:

```bash
tycoon data analyze my-source --rill
```

This exports each raw table to Parquet, then generates Rill source, metrics view, and explore
files — one dashboard per table. The `--rill` flag is opt-in; dashboard generation is skipped
by default since it requires a Rill project directory (`rill/`) to already exist.

**Architecture**: sources read from Parquet via Rill's `local_file` connector into its
built-in in-memory OLAP. Dashboards are immediately usable without a dbt run.

---

## Observability (dlt + dbt run history)

Every `tycoon data sources run` mirrors dlt's load history into `.tycoon/metadata.duckdb`.
Every `tycoon data transform run/test/build` parses `target/run_results.json` and records
one row per invocation plus one per model/test. Both captures are best-effort — they never
break the underlying command.

Peek at history from the terminal:

```bash
tycoon data history                  # last 20 runs across dlt + dbt
tycoon data history --tool dbt -n 50 # dbt-only, last 50
tycoon data history show deadbeef    # drill into a specific run (short prefix OK)
```

Or open the two Rill dashboards (`_tycoon_dlt_usage`, `_tycoon_dbt_usage`) that
auto-appear alongside your per-source explores — success rate, duration, rows
loaded, models built, tests passed/failed, all filterable by schema, table,
command, and dbt version.

Query the metadata DB directly for anything the dashboards don't cover:

```bash
tycoon data query --db .tycoon/metadata.duckdb \
  "SELECT invocation_id, command, elapsed_s, success
   FROM dbt_runs ORDER BY started_at DESC LIMIT 10"
```

The metadata DB is disposable — delete `.tycoon/metadata.duckdb` to reset history.

---

## Optional Extras

### Dagster orchestration (`tycoon[dagster]`)

Installs Dagster, dagster-dbt, and dagster-dlt. Provides a full asset graph covering ingestion and transformation. Run the Dagster UI with:

```bash
dagster dev
```

The workspace is defined in `workspace.yaml` at the project root.

### AI queries (`tycoon[ask]`)

Installs Nao and Ibis for natural language querying of the warehouse. Requires a running LLM — Ollama (local) is supported out of the box with no API key.

```bash
tycoon ask init
tycoon ask sync
tycoon ask chat
```

`tycoon ask init` and `tycoon ask sync` also write an `AGENTS.md` at the project root pointing coding agents (Claude Code, Cursor, Windsurf, etc.) at the synced context tree under `.tycoon/nao/`. Commit `AGENTS.md` so it's available to anyone cloning the repo. Pipe context into any agent directly:

```bash
tycoon ask context --table dim_users | claude -p "explain this table"
tycoon ask context --schema mart                   # all tables in a schema
tycoon ask context --rules-only                    # just RULES.md
tycoon ask context                                 # list available tables
```
