Commands
Full reference for every harumi CLI command, flag, and the Python library.
Every command accepts --api-url, --git-url, and --org to override the
resolved configuration for a single invocation. Commands
that act on a project take --project, -p; if you omit it, the CLI uses the
.harumi binding written by harumi init (searched upward from the current
directory).
Authentication
harumi login # existing account: email + one-time code
harumi login --signup # create the account first, then send the code
harumi whoami # show the current user (email + id)
harumi logout # clear the local sessionProp
Type
Discover kernels
Kernel specs determine the compute size and image your code runs on. List the
ones available to you before passing --kernel to run:
harumi specsPrints a table of name, display_name, cpu, memory, and whether the
spec requires a subscription. Use the name value (e.g. or_python_small,
gurobi_python_medium) as the --kernel argument.
Projects
harumi projects create <NAME> # create + bind this directory
harumi projects create <NAME> --no-bind # create without binding
harumi projects create <NAME> --customer-id <id> --template-id <id>
harumi notebooks # list projects and their repos
harumi notebooks --project <PROJECT_ID> # only that project
harumi init --project <PROJECT_ID> # bind an existing projectProp
Type
harumi init (and projects create when binding) writes .harumi/config.json
with the project id and its Gitea repo, then configures a git remote named
harumi for HTTPS + token pushes.
Repo provisioning is an assumed contract
POST /projects is live, but under the git-first pivot it is expected to
provision a Gitea repo alongside the project row. If the backend doesn't yet
return repo metadata, projects create errors clearly instead of leaving you
with a project you can't harumi init into.
Run
harumi run
harumi run --branch <b> --commit <sha> --command <c> --kernel <k> --watch --output-dir <dir>See The run model for the flag table and how scratch branches work.
Outputs
harumi outputs # table of all outputs
harumi outputs --latest # only the most recent
harumi outputs --download <OUTPUT_ID> --output-dir ./outProp
Type
Data sources
Project-scoped database connections. These hit real, live endpoints today. Credentials are always prompted interactively (hidden input) — never passed as a flag — and the server never returns them.
harumi datasources list
harumi datasources get <name>
harumi datasources add <name> --type postgresql --host <host> --port 5432 --database <db> --username <user>
harumi datasources update <name> --host <new-host> --set-credentials
harumi datasources query <name> --sql "SELECT * FROM orders LIMIT 10" --csv ./out.csv
harumi datasources test --type postgresql --host <host> --port 5432 --database <db> --username <user>
harumi datasources remove <name> --yesProp
Type
Read-only queries
datasources query only allows SELECT/WITH; anything else is rejected
with an explicit error naming the forbidden keyword, and results are capped
server-side. Use it to validate SQL before wiring it into solver code.
Schedules
Project-scoped cron schedules. Cron is a raw 5-field expression interpreted in UTC and validated server-side. There is no pause/enable flag — delete the schedule to stop it firing.
harumi schedules list
harumi schedules get <SCHEDULE_ID>
harumi schedules add --cron "0 9 * * *" --kernel or_python_small --email-to team
harumi schedules update <SCHEDULE_ID> --cron "0 6 * * 1-5"
harumi schedules remove <SCHEDULE_ID> --yesProp
Type
Assumed endpoints
The git-first pivot re-keys schedules from notebook_id to project_id.
Until that backend change lands, these commands no-op with a clear error.
Configuration
Every setting resolves in this order: CLI flag > environment variable >
~/.harumi/config.json > default.
| Setting | Env var | Config key | Default |
|---|---|---|---|
| API base URL | HARUMI_API_URL | api_url | https://api.harumi.io/api |
| Gitea URL | HARUMI_GIT_URL | git_url | https://git.dev.harumi.io |
| Organization | HARUMI_ORG | org_id | none (resolved at login) |
harumi config set-org <ORG_ID> # persist the org sent as X-Organizationset-org writes org_id into ~/.harumi/config.json. Set HARUMI_HOME to
relocate the whole config directory (credentials, config, and tokens all live
under it).
Files the CLI uses
~/.harumi/credentials.json— session tokens and the Gitea token (mode0600).~/.harumi/config.json— resolvedapi_url,git_url,org_id.<project>/.harumi/config.json— per-directory project binding (project_id+ repo), searched upward from the current directory.
Python library
The same functionality is available as a library — useful in notebooks or your own automation.
from harumi import Client
from harumi.config import ProjectBinding
binding = ProjectBinding.load() # reads .harumi/config.json
client = Client() # reads ~/.harumi/credentials.json
response = client.execute_project(
binding.project_id,
branch="feature/solver-v2",
command="python main.py",
)
from harumi.execution import wait_for_output
output = wait_for_output(client.api, binding.project_id, response.output_id)
print(output.status, output.output_url)
client.download_output(binding.project_id, output.id, "./out")