Configuration
Kitaru config directory, execution defaults, environment variables, and precedence
This guide covers Kitaru's configuration system: where settings live on disk, how to set execution defaults, how headless environments are bootstrapped, and how precedence is resolved.
Config directory
Kitaru stores all of its state — settings, database, credentials, and local stores — in a single directory. By default this is your platform's standard application config directory:
Linux: ~/.config/kitaru/
macOS: ~/Library/Application Support/kitaru/
Windows: %APPDATA%\\kitaru\\Inside that directory you will find:
kitaru.yaml # Log-store, model aliases, and other Kitaru settings
config.yaml # Internal runtime configuration (managed automatically)
local_stores/ # SQLite database and local artifact storageYou can see the active config directory by running kitaru status or
kitaru info.
If you want to relocate that directory, set:
export KITARU_CONFIG_PATH=/app/.kitaruThis moves everything — settings, database, and credentials — to the new location. Kitaru reads that path immediately, but it only creates the directory on first write.
Configure runtime defaults in Python
Use kitaru.configure(...) to set process-local defaults:
import kitaru
kitaru.configure(
stack="local",
cache=False,
retries=1,
image=kitaru.ImageSettings(
base_image="python:3.12-slim",
environment={"OPENAI_API_KEY": "{{ OPENAI_KEY }}"},
),
)These defaults apply to flows started in the current Python process.
Flow-level and invocation-level overrides
Flow defaults can override configured runtime defaults, and invocation-time arguments can override both.
from kitaru import flow
@flow(cache=True, retries=2, stack="gpu-cluster")
def my_flow(topic: str) -> str:
...
handle = my_flow.run("kitaru", retries=3, stack="prod-cluster")In this example, resolved retries are 3, and the execution runs on
prod-cluster for that one submission.
The important distinction is:
kitaru.configure(stack="...")sets a process-local default@flow(stack="...")sets a default for one flow definitionmy_flow.run(stack="...")overrides both for one execution- none of those change the persisted active stack selected by
kitaru stack use ...
Environment variables
Kitaru's public env-var surface uses KITARU_* names.
Connection
These are the key env vars for non-interactive setup:
KITARU_SERVER_URLKITARU_AUTH_TOKENKITARU_PROJECT
For normal interactive use:
kitaru loginstarts and connects to a local serverkitaru login <server>connects to a remote server
The KITARU_* connection variables are mainly for Docker, CI, and other
headless environments.
Use them together for Docker, CI, or any other headless environment:
export KITARU_SERVER_URL=https://my-server.example.com
export KITARU_AUTH_TOKEN=kat_abc123...
export KITARU_PROJECT=my-projectThere are two guardrails:
KITARU_SERVER_URLandKITARU_AUTH_TOKENmust be set together.- If a remote server is configured via env vars,
KITARU_PROJECTis required at first use (KitaruClient(),my_flow.run(), replay, etc.).
Internally, Kitaru translates these public env vars into the ZenML env vars the
runtime already understands. That means you should configure KITARU_*, not
ZENML_*, in normal Kitaru docs and examples.
Execution
Execution settings:
KITARU_STACKKITARU_CACHEKITARU_RETRIESKITARU_IMAGE(JSON object or plain image string)
LLM
KITARU_DEFAULT_MODELsets the default model forkitaru.llm()when no explicitmodel=argument is provided.KITARU_LLM_MOCK_RESPONSEremains available for tests and demos.
KITARU_DEFAULT_MODEL first tries local alias lookup. If the value is not a
registered alias, Kitaru passes it straight through as a raw LiteLLM model
string. This lookup happens before Kitaru falls back to the locally configured
default alias.
If you want the full secret-backed setup path for kitaru.llm(), see
Secrets + Model Registration.
Housekeeping
KITARU_CONFIG_PATHKITARU_DEBUGKITARU_ANALYTICS_OPT_IN
kitaru status
kitaru status shows an Environment section when KITARU_* vars are
active. Secret values such as KITARU_AUTH_TOKEN and
KITARU_LOG_STORE_API_KEY are masked.
Precedence (highest to lowest)
- Invocation-time overrides (
my_flow.run(..., stack="prod")) - Flow decorator defaults (
@flow(stack="prod")) kitaru.configure(...)- Environment variables (
KITARU_STACK,KITARU_SERVER_URL, etc.) - Project config (
pyproject.tomlunder[tool.kitaru]) - Persisted active stack fallback plus global user config (for example connection defaults)
- Built-in defaults (
cache=True,retries=0)
In practice, stack starts unset in the built-in defaults and is then resolved
from the persisted active stack when one is available.
For connection-specific resolution, Kitaru uses this lower-to-higher order:
- Persisted global connection (
kitaru login) - Direct
ZENML_*env vars for compatibility KITARU_*env vars- Runtime overrides from
kitaru.configure(...)
Project config in pyproject.toml
[tool.kitaru]
stack = "prod"
cache = false
retries = 2
[tool.kitaru.image]
base_image = "python:3.12-slim"
[tool.kitaru.image.environment]
OPENAI_API_KEY = "{{ OPENAI_KEY }}"Automatic package injection
Kitaru automatically adds itself to the container image requirements for remote
execution when Kitaru is assembling the image from requirements. You usually do
not need to add kitaru to your requirements list manually.
If you specify your own requirements, Kitaru appends itself without duplicating:
kitaru.configure(
image=kitaru.ImageSettings(
requirements=["httpx", "pydantic"],
),
)
# Remote container installs: httpx, pydantic, kitaruIf you already include kitaru (with or without a version pin), it is not added
again:
kitaru.configure(
image=kitaru.ImageSettings(
requirements=["kitaru>=0.2.0", "httpx"],
),
)
# Remote container installs: kitaru>=0.2.0, httpx (no duplicate)If you specify a custom base_image or dockerfile, you control the image
contents yourself. In that case, Kitaru does not auto-inject the SDK, so
your image must already include kitaru.
Replicating your local environment
During development, you can replicate your entire local Python environment into
the remote container. This installs all locally installed packages (via
pip freeze) so the remote container matches your dev setup exactly:
from kitaru import flow
@flow(image={"replicate_local_python_environment": True})
def my_flow(topic: str) -> str:
...System packages
If your flow needs system-level dependencies (e.g., git, ffmpeg), use
apt_packages:
from kitaru import flow
import kitaru
@flow(
image=kitaru.ImageSettings(
apt_packages=["git", "ffmpeg"],
requirements=["httpx"],
),
)
def my_flow(topic: str) -> str:
...Project selection
There are really two different stories here:
- Persisted login / default setup — if you connect with
kitaru login <server>, Kitaru can usually just follow the server-side default project and you do not need to think about it much. - Env-driven remote bootstrap — if you connect with
KITARU_SERVER_URL/KITARU_AUTH_TOKEN, thenKITARU_PROJECTis required at first use.
Bare kitaru login is the local-server path instead: it does not use
KITARU_SERVER_URL or KITARU_AUTH_TOKEN, and it warns instead of failing if
those remote auth env vars are already set in your shell.
You can set the project explicitly with either:
- Environment variable (preferred):
KITARU_PROJECT=my-project - SDK call (advanced/internal):
kitaru.configure(project="my-project")
configure(project=...) is an internal/testing escape hatch, not a normal
user-facing setting. Prefer KITARU_PROJECT for standard usage.
When an explicit project override is set, it appears in kitaru info output
as "Project override". It does not appear in kitaru status except as part of
the raw Environment section when KITARU_PROJECT itself is active.
Headless / Docker / CI recipe
# Connection
export KITARU_SERVER_URL=https://my-server.example.com
export KITARU_AUTH_TOKEN=kat_abc123...
export KITARU_PROJECT=my-project
# Execution
export KITARU_STACK=my-remote-stack
export KITARU_CACHE=true
export KITARU_RETRIES=2
# LLM
export OPENAI_API_KEY=sk-...
export KITARU_DEFAULT_MODEL=openai/gpt-4o
# Observability
export KITARU_LOG_STORE_BACKEND=datadog
export KITARU_LOG_STORE_ENDPOINT=https://http-intake.logs.datadoghq.com
export KITARU_LOG_STORE_API_KEY=...
# Housekeeping
export KITARU_CONFIG_PATH=/app/.kitaru
export KITARU_DEBUG=false
export KITARU_ANALYTICS_OPT_IN=falseCompatibility note
Direct ZENML_* env vars still work because the underlying runtime understands
them, but Kitaru docs use KITARU_* as the public interface.
Frozen execution spec
At flow start, Kitaru computes a fully resolved execution config and persists it
with the execution metadata (kitaru_execution_spec). This keeps execution
behavior stable even if config changes later.
Example in this repository
uv sync --extra local
uv run examples/basic_flow/flow_with_configuration.py
uv run pytest tests/test_phase10_configuration_example.pyFor the broader catalog, see Examples.