Install dosi-engine¶
This guide gets you a working dosi command in a few minutes. By the end you'll
have built the binary and confirmed it can read a model.
Building from source (for now)
dosi-engine is pre-1.0 and doesn't ship prebuilt binaries yet, so you build
it from source with Rust. It's a single cargo build and the default build
needs nothing but Rust — a local DuckDB engine is bundled in, so you can
run real queries immediately with no database to install.
Prerequisites¶
- Rust (stable, 1.75+). Install with rustup:
- Git, to clone the repository.
- (Optional) Python 3.12+, only if you want the Python bindings.
You do not need a database installed to get started — the default build includes an in-process DuckDB.
Build the CLI¶
The binary lands at target/release/dosi. Put it on your PATH, or run it in
place:
$ ./target/release/dosi --help
# or, without copying it anywhere:
$ cargo run --release --bin dosi -- --help
The examples in these docs write dosi … for brevity — read that as
./target/release/dosi … unless you've added it to your PATH.
Verify it works¶
Point dosi at one of the bundled example models and validate it:
If you see that line, you're ready for the first-metric-query tutorial.
Choose what to build (warehouses)¶
The default build talks to local DuckDB only — perfect for learning and for compiling SQL. To execute against a real warehouse, build with the matching feature so the binary stays lean:
| You want to query… | Build with |
|---|---|
| DuckDB (local, bundled) | (default — nothing to add) |
| MySQL, TiDB, StarRocks, Doris | --features exec-mysql |
| Postgres | --features exec-postgres |
| Hologres | --features exec-hologres |
| GaussDB / openGauss | --features exec-gaussdb |
| Oracle | --features exec-oracle |
| ClickHouse, Trino | --features exec-http |
| Snowflake | --features exec-snowflake |
| Everything | --features exec-all |
For example, to build with Postgres and ClickHouse support:
Per-warehouse connection setup (hosts, credentials, TLS) lives in
Connect a warehouse. You can always compile SQL for any
dialect without these features — they only affect --execute.
Optional: Python bindings¶
If you'd rather call dosi-engine from Python (module dosi_engine), build a
wheel with maturin. Requires Python 3.12+:
$ cd crates/dosi-py
$ PYO3_PYTHON=$(command -v python3.12) uvx maturin build --release -o ../../target/wheels
$ pip install ../../target/wheels/dosi_engine-*.whl
Quick check:
The Python API mirrors the CLI — construct an Engine(model_path=…), then call
.metrics(), .compile(...), and .execute(...). (A dedicated Python API
reference page is on the roadmap.)
Module-level constants tell you what this build implements, which is what a
tool that generates models should read before choosing which Datus extension
keys to emit — the same content as dosi info:
>>> import dosi_engine
>>> dosi_engine.SPEC_VERSION # the OSI core spec
'0.2.0.dev0'
>>> dosi_engine.DATUS_EXT_VERSION # the Datus extension version
'1.1'
>>> [k["key"] for k in dosi_engine.DATUS_EXT["keys"]]
['join_type', 'fill_nulls_with', 'time_dimension', 'time_granularity', 'dataset']
Each entry in DATUS_EXT["keys"] also carries the version that introduced it
and what it costs to ignore it; see
datus-extensions.md.
Coming from datus_osi_engine¶
The project was previously named osi-engine, and the Python package went with
it: datus-osi-engine / datus_osi_engine is now dosi-engine /
dosi_engine. New code should import dosi_engine directly.
If you have consumers that still import the old module — the
datus-semantic-osi-engine adapter, for instance — you don't have to change
them. crates/dosi-py/shim/ builds a compatibility shim under the old
datus-osi-engine name that depends on dosi-engine and re-exports it as
datus_osi_engine, raising a DeprecationWarning on import:
$ pip install ./crates/dosi-py/shim # after installing the dosi_engine wheel
$ python -W once -c "import datus_osi_engine"
DeprecationWarning: datus-osi-engine has been renamed to dosi-engine; import
dosi_engine instead (this compatibility shim will be removed in a future release)
(-W once because Python hides DeprecationWarning by default outside
__main__.)
The shim is built from the repository — it is not published, and the wheel
pipeline ships dosi-engine only. It will be removed in a future release, so
treat it as a migration window, not a permanent alias.
Environment variables and the connections file were renamed the same way:
OSI_* → DOSI_*, ./osi-connections.yaml → ./dosi-connections.yaml,
~/.config/osi/ → ~/.config/dosi/. The old file paths are still discovered
as fallbacks (connectors.md); the old
environment variables are not. OSSIE_DIR is unchanged — "OSI" still names the
spec.
Next steps¶
-
Go from a model to real, verifiable results in 10 minutes.
-
What OSI is and why an engine, in plain language.
-
Point dosi-engine at Postgres, Snowflake, ClickHouse, and more.