Skip to content

Install Dosi

One command puts dosi and dosi-server on Linux or macOS. There's nothing else to install: no toolchain, no database, no client libraries.

$ curl -fsSL https://dosi.datus.ai/install.sh | sh
$ curl -fsSL https://dosi.datus.ai/install.sh | DOSI_SHAPE=lean sh
$ curl -fsSL https://dosi.datus.ai/install.sh | DOSI_SOURCE=oss sh
$ pip install dosi-engine

Needs Python 3.12+. See Python bindings.

Then check it:

$ dosi --version
dosi 0.1.12

Not sure which build you need? Take the default. The lean build exists for machines without a C++ runtime; Which download? covers the difference. If you'd rather not pipe a script into sh, use the manual download. To confirm the install can read a model, continue to Verify it works.

What the install script does

The script detects your CPU, downloads the matching archive, verifies its SHA-256 checksum, and installs dosi and dosi-server into ~/.local/bin — plus libduckdb.so beside them, for the default build. Add that directory to your PATH if it isn't there already.

Switching between the two later is just re-running the script with or without DOSI_SHAPE=lean; it overwrites what is there. Going from the default to lean leaves an unused libduckdb.so behind, which is harmless — delete it if you want the space back.

The example models travel with the binaries, into ~/.local/share/dosi/examples. The script prints the path when it finishes.

By default both the manifest and the archive come straight from GitHub. DOSI_SOURCE=oss fetches both from the Aliyun OSS mirror instead — mainland China should use it. There's no automatic fallback between sources: a chosen source that fails fails the install outright, rather than silently retrying elsewhere. DOSI_OSS_MIRROR points the mirror at an internal one instead of the default; it stores an archive under v<version>/<file> and a manifest under both v<version>/manifest.json and latest/manifest.json.

Which download?

Take the default. It is the complete product: everything the lean build does, plus DuckDB running in your process for local queries.

There is exactly one reason to choose lean, and it is not the download size: the default build needs a C++ runtime on the machine (libstdc++ with GLIBCXX_3.4.22, GCC 6 and up), because DuckDB is written in C++. The lean build is pure Rust against libc and needs no C++ at all. If your target is a distroless or otherwise minimal image, or an older distribution, that difference is the whole decision.

Default Lean
Archive dosi-<version>-<target>.tar.gz dosi-<version>-<target>-lean.tar.gz
Local DuckDB queries in process, Arrow-native runs a duckdb CLI from your PATH
Files dosi, dosi-server, libduckdb.so dosi, dosi-server
Needs on the machine glibc ≥ 2.28, libstdc++ glibc ≥ 2.28. A duckdb CLI only if you run local queries
Warehouse connectors all all — identical
Download ~63 MB ~41 MB

Everything else is the same: the same compiler, the same dialects, the same connectors (Postgres, MySQL/TiDB/StarRocks/Doris, Hologres, DWS, GaussDB, Oracle, ClickHouse, Trino, Snowflake, BigQuery, Databricks, Arrow Flight). Compiling a metric query to SQL is identical in both, and so is executing against a warehouse. Only local DuckDB execution differs.

Using the default build

libduckdb.so has to sit next to dosi and dosi-server — the executables look beside themselves for it. The install script puts all three in the same directory; if you unpack an archive by hand, keep them together, and if you copy dosi somewhere else, copy the library with it.

Using the lean build

Local execution (--execute against --db) runs whatever duckdb is on your PATH, so install one from duckdb.org if you need it. Without a CLI, dosi still compiles SQL and still queries every warehouse — you only lose local DuckDB, with cannot start duckdb CLI if you ask for it.

Two things to know about that path:

  • It is verified against the DuckDB v1.4.x series, and dosi warns once if the CLI it finds is outside it. Results come back through JSON there, so type fidelity for large integers, DECIMAL and TIMESTAMPTZ is version-sensitive in a way the default build's Arrow path is not.
  • Each statement runs in a fresh process, so an in-memory database keeps nothing between calls. Use a file database (--db) when you need state.

Which one did I install?

$ dosi info
dosi       0.1.12
...
build      engine (DuckDB in process)

build reports engine or lean; dosi info --format json carries the same value under shape.

Manual download

Dosi ships for Linux and macOS:

Platform Archive Lean archive
Linux x86_64 dosi-<version>-x86_64-unknown-linux-gnu.tar.gz dosi-<version>-x86_64-unknown-linux-gnu-lean.tar.gz
Linux arm64 dosi-<version>-aarch64-unknown-linux-gnu.tar.gz dosi-<version>-aarch64-unknown-linux-gnu-lean.tar.gz
macOS Apple Silicon dosi-<version>-aarch64-apple-darwin.tar.gz dosi-<version>-aarch64-apple-darwin-lean.tar.gz

Not every release carries every row. Which platforms a release was built for is whatever manifest.json lists for it — macOS Intel in particular is built only on request. The installer reads that file rather than guessing a file name, so it fails with no build for <target> instead of downloading the wrong archive.

On Linux the binaries need glibc 2.28 or newer — RHEL/Rocky/Alma 8, Ubuntu 20.04, Debian 10, and anything more recent. The default build additionally needs libstdc++ with GLIBCXX_3.4.22 (GCC 6+), which comes from libduckdb; the lean build has no C++ dependency at all. CentOS 7 is below both floors — run Dosi in a container there. On macOS the floor is macOS 11 (Big Sur); nothing outside the system frameworks is required.

Archives are attached to each release on the downloads repository. manifest.json names the current release and carries the checksum of every archive in it — fetch it from the latest path and you never have to hardcode a version:

$ curl -fsSL https://github.com/Datus-ai/dosi-dist/releases/latest/download/manifest.json
$ VERSION=0.1.12 TARGET=x86_64-unknown-linux-gnu
$ BASE=https://github.com/Datus-ai/dosi-dist/releases/download/v$VERSION
$ curl -fsSLO $BASE/dosi-$VERSION-$TARGET.tar.gz
$ curl -fsSLO $BASE/SHA256SUMS
$ sha256sum --ignore-missing -c SHA256SUMS   # macOS: shasum -a 256 -c SHA256SUMS --ignore-missing
$ tar xzf dosi-$VERSION-$TARGET.tar.gz
$ sudo install dosi-$VERSION-$TARGET/dosi /usr/local/bin/dosi
$ sudo install dosi-$VERSION-$TARGET/dosi-server /usr/local/bin/dosi-server
$ sudo install -m 0644 dosi-$VERSION-$TARGET/libduckdb.so /usr/local/bin/libduckdb.so

That last line is not optional for the default build: the executables look for libduckdb.so in their own directory, so installing them without it gives you libduckdb.so: cannot open shared object file on the first run. For the lean archive (…-$TARGET-lean.tar.gz) there is no library and no third line.

Verify the checksum before you run the binary — SHA256SUMS covers every archive in the release.

What's in the archive

dosi-<version>-<target>/
├── dosi              the CLI
├── dosi-server       the REST / Arrow-Flight / MCP server
├── libduckdb.so      DuckDB — default build only; keep it beside the two above
├── LICENSE
└── examples/
    ├── orders/       the model used by the tutorial
    └── tpcds/        the model used by the CLI reference

The lean archive is the same tree without libduckdb.so.

The install script puts both executables on your PATH. dosi-server is what the REST API and MCP server pages invoke.

Verify it works

dosi info needs no model, so it doubles as a version probe — it reports the Apache Ossie spec version, the Datus extension version, which build you installed, and the Datus extension keys it understands:

$ dosi --version
dosi 0.1.12
$ dosi info
dosi       0.1.12
osi spec   0.2.0.dev0
datus-ext  1.9 (accepts 1.0 and up)
mode       datus
build      engine (DuckDB in process)
examples   /home/you/.local/share/dosi/examples
...

The examples line is the one to note: it is where the bundled models landed — ~/.local/share/dosi/examples if you used the install script, the examples/ directory inside the archive if you unpacked it yourself. Every page in these docs refers to them through $DOSI_EXAMPLES, so export it once:

$ export DOSI_EXAMPLES=~/.local/share/dosi/examples

Then validate one of them:

$ dosi validate --model $DOSI_EXAMPLES/orders/model.yaml
✓ 1 semantic model(s) valid

If you see that line, you're ready for the first-metric-query tutorial.

Warehouses

Both published builds include every connector — MySQL/TiDB/StarRocks/Doris, Postgres, Hologres, DWS, GaussDB/openGauss, Oracle, ClickHouse, Trino, Snowflake, BigQuery, Databricks. The choice between them is about local DuckDB execution only (see Which download?), never about which warehouses you can reach. Per-warehouse connection setup (hosts, credentials, TLS) lives in Connect a warehouse.

Compiling SQL for any dialect never needs a connector; they only matter for --execute.

Python bindings

To call Dosi from Python (module dosi_engine), install the wheel. Requires Python 3.12+:

$ pip install dosi-engine

Quick check:

$ python -c "from dosi_engine import Engine; print('ok')"
ok

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.10'
>>> [k["key"] for k in dosi_engine.DATUS_EXT["keys"]]
['join_type', 'fill_nulls_with', 'time_dimension', 'time_granularity', 'window',
 'dataset', 'derive', 'measure', 'params', 'time', 'is_dimension',
 'cardinality', 'lod']

Each entry in DATUS_EXT["keys"] also carries the version that introduced it and what it costs to ignore it; see datus-extensions.md.

Agent integrations can obtain the complete authoring contract directly from the installed engine instead of carrying a version-keyed copy:

contract = dosi_engine.DATUS_AUTHORING_CONTRACT
digest = dosi_engine.DATUS_AUTHORING_CONTRACT_DIGEST
prompt_yaml = dosi_engine.render_datus_authoring_spec()

The contract is dialect-neutral. Supply the active Ossie expression dialect to the agent separately; it depends on the datasource, not the engine extension version. The digest is stable for identical contract content and can be used in prompt-cache keys.

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.

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. The spec itself is now Apache Ossie (formerly OSI); the engine-mode flags --osi-basic / --osi-datus and OSSIE_DIR keep their names.

License

Dosi is licensed under the Elastic License 2.0 (ELv2) — the LICENSE file in every archive carries the full text. You may download, use, and redistribute it free of charge, in production and commercially. The three limitations: you may not offer Dosi to third parties as a hosted or managed service, circumvent its license key functionality, or remove its licensing notices. For a hosting arrangement or any use ELv2 does not allow, contact Datus.

Next steps