Skip to main content

Onyx Developer Script

Deploy Status PyPI

ods is onyx.app's devtools utility script. It is packaged as a python wheel and available from PyPI.

Installation

A stable version of ods is provided in the default python venv which is synced automatically if you have pre-commit hooks installed.

While inside the Onyx repository, activate the root project's venv,

source .venv/bin/activate

Prerequisites

Some commands require external tools to be installed and configured:

  • Docker - Required for compose, logs, and pull commands

  • uv - Required for backend commands

  • GitHub CLI (gh) - Required for run-ci, cherry-pick, and trace commands

  • AWS CLI - Required for screenshot-diff commands (S3 baseline sync)

Autocomplete

ods provides autocomplete for bash, fish, powershell and zsh shells.

For more information, see ods completion <shell> --help for your respective <shell>.

zsh

Linux

ods completion zsh | sudo tee "${fpath[1]}/_ods" > /dev/null

macOS

ods completion zsh > $(brew --prefix)/share/zsh/site-functions/_ods

bash

ods completion bash | sudo tee /etc/bash_completion.d/ods > /dev/null

Note: bash completion requires the bash-completion package be installed.

Commands

compose - Launch Docker Containers

Launch Onyx docker containers using docker compose.

ods compose [profile]

Profiles:

  • dev - Use dev configuration (exposes service ports for development)
  • multitenant - Use multitenant configuration

Flags:

Flag Default Description
--down false Stop running containers instead of starting them
--wait true Wait for services to be healthy before returning
--force-recreate false Force recreate containers even if unchanged
--tag Set the IMAGE_TAG for docker compose (e.g. edge, v2.10.4)

Examples:

# Start containers with default configuration
ods compose

# Start containers with dev configuration
ods compose dev

# Start containers with multitenant configuration
ods compose multitenant

# Stop running containers
ods compose --down
ods compose dev --down

# Start without waiting for services to be healthy
ods compose --wait=false

# Force recreate containers
ods compose --force-recreate

# Use a specific image tag
ods compose --tag edge

logs - View Docker Container Logs

View logs from running Onyx docker containers. Service names are available as arguments to filter output, with tab-completion support.

ods logs [service...]

Flags:

Flag Default Description
--follow true Follow log output
--tail Number of lines to show from the end of the logs

Examples:

# View logs from all services (follow mode)
ods logs

# View logs for a specific service
ods logs api_server

# View logs for multiple services
ods logs api_server background

# View last 100 lines and follow
ods logs --tail 100 api_server

# View logs without following
ods logs --follow=false

pull - Pull Docker Images

Pull the latest images for Onyx docker containers.

ods pull

Flags:

Flag Default Description
--tag Set the IMAGE_TAG for docker compose (e.g. edge, v2.10.4)

Examples:

# Pull images
ods pull

# Pull images with a specific tag
ods pull --tag edge

backend - Run Backend Services

Run backend services (API server, model server) with environment loaded from .vscode/.env. On first run, copies .vscode/env_template.txt to .vscode/.env if the .env file does not already exist.

Enterprise Edition features are enabled by default with license enforcement disabled, matching the compose command behavior.

ods backend <subcommand>

Subcommands:

  • api - Start the FastAPI backend server (uvicorn onyx.main:app --reload)
  • model_server - Start the model server (uvicorn model_server.main:app --reload)

Flags:

Flag Default Description
--no-ee false Disable Enterprise Edition features (enabled by default)
--port 8080 (api) / 9000 (model_server) Port to listen on

Shell environment takes precedence over .env file values, so inline overrides work as expected (e.g. S3_ENDPOINT_URL=foo ods backend api).

Examples:

# Start the API server
ods backend api

# Start the API server on a custom port
ods backend api --port 9090

# Start without Enterprise Edition
ods backend api --no-ee

# Start the model server
ods backend model_server

# Start the model server on a custom port
ods backend model_server --port 9001

web - Run Frontend Scripts

Run bun scripts from web/package.json without manually changing directories.

ods web <script> [args...]

Script names are available via shell completion (for supported shells via ods completion), and are read from web/package.json.

Examples:

# Start the Next.js dev server
ods web dev

# Run web lint task
ods web lint

# Forward extra args to the script
ods web test --watch

dev - Devcontainer Management

Manage the Onyx devcontainer. Also available as ods dc.

Requires the devcontainer CLI (bun install -g @devcontainers/cli).

ods dev <subcommand>

Subcommands:

  • up - Start the devcontainer (pulls the image if needed)
  • into - Open a zsh shell inside the running devcontainer
  • exec - Run an arbitrary command inside the devcontainer
  • restart - Remove and recreate the devcontainer
  • rebuild - Pull the latest published image and recreate
  • stop - Stop the running devcontainer

The devcontainer image is published to onyxdotapp/onyx-devcontainer and referenced by tag in .devcontainer/devcontainer.json — no local build needed.

Examples:

# Start the devcontainer
ods dev up

# Open a shell
ods dev into

# Run a command
ods dev exec -- bun test

# Restart the container
ods dev restart

# Pull latest image and recreate
ods dev rebuild

# Stop the container
ods dev stop

# Same commands work with the dc alias
ods dc up
ods dc into

db - Database Administration

Manage PostgreSQL database dumps, restores, and migrations.

ods db <subcommand>

Subcommands:

  • dump - Create a database dump
  • restore - Restore from a dump
  • upgrade/downgrade - Run database migrations
  • drop - Drop a database

Run ods db --help for detailed usage.

openapi - OpenAPI Schema Generation

Generate OpenAPI schemas and client code.

ods openapi all

check-lazy-imports - Verify Lazy Import Compliance

Check that specified modules are only lazily imported (used for keeping backend startup fast).

ods check-lazy-imports

audit - Audit Dependencies for Vulnerabilities

Scan the JavaScript (bun.lock) and Python (uv.lock) lockfiles via osv-scanner (vendored as a library, no external binary required) and open GitHub Dependabot security alerts for known vulnerabilities. With no selector flags, all sources are audited.

Accepted advisories are suppressed via an allowlist fetched from S3 at runtime (s3://onyx-internal-tools/audit/ignores.json by default), so a release can be unblocked without a code change. The command exits non-zero when an unignored finding at or above --fail-on (default critical) remains, which is how it gates deploys.

ods audit [--web] [--python] [--dependabot] [--format text[,json][,sarif]] [--fail-on critical|high|moderate|low] [--ignore-url s3://...]

--format takes a comma-separated list. The machine-readable formats (json, sarif) are written to stdout, while the human-readable text report is written to stderr when combined with one of them. This lets a single run produce a SARIF file for upload and a readable report in the log: ods audit --format=sarif,text > audit.sarif sends SARIF to the file and the report (plus, when the gate fails, a runbook explaining how to resolve or suppress each finding) to the terminal. A lone format always goes to stdout, so --format=sarif > audit.sarif is unchanged. At most one machine-readable format may be requested.

Examples:

# Audit everything; fail on unignored criticals
ods audit

# Only the Python lockfile
ods audit --python

# Emit a SARIF report (used by the nightly GitHub code-scanning job)
ods audit --python --format=sarif > audit.sarif

# SARIF to a file for upload, readable report to the log (used by CI gates)
ods audit --format=sarif,text > audit.sarif

Managing the allowlist

Suppress a reviewed-and-accepted advisory so it stops blocking the gate:

# Interactive editor (add/edit/delete rows, then upload after a confirmation)
ods audit ignore

# Non-interactive add of a single suppression (a --reason is required)
ods audit ignore add GHSA-xxxx-xxxx-xxxx --ecosystem npm \
  --reason "not reachable in our usage" --expires 2026-09-01

ods audit ignore add stamps added_by from your git email, shows a diff, and uploads the updated allowlist to S3 after a confirmation prompt (--yes skips it). Suppress only advisories you've assessed — the allowlist gates every deploy.

The allowlist is a JSON document of the form:

{
  "ignores": [
    {
      "id": "GHSA-xxxx-xxxx-xxxx",
      "ecosystem": "npm",
      "reason": "not reachable in our usage",
      "added_by": "you@onyx.app",
      "expires": "2026-09-01"
    }
  ]
}

id matches a finding's id or any of its aliases (case-insensitive); ecosystem and expires are optional (an expired entry stops suppressing).

run-ci - Run CI on Fork PRs

Pull requests from forks don't automatically trigger GitHub Actions for security reasons. This command creates a branch and PR in the main repository to run CI on a fork's code.

ods run-ci <pr-number>

Example:

# Run CI for PR #7353 from a fork
ods run-ci 7353

cherry-pick - Backport Commits to Release Branches

Cherry-pick one or more commits to release branches and automatically create PRs. Cherry-pick PRs created by this command are labeled cherry-pick 🍒.

ods cherry-pick <commit-sha> [<commit-sha>...] [--release <version>]

Examples:

# Cherry-pick a single commit (auto-detects release version)
ods cherry-pick abc123

# Cherry-pick to a specific release
ods cherry-pick abc123 --release 2.5

# Cherry-pick to multiple releases
ods cherry-pick abc123 --release 2.5 --release 2.6

# Cherry-pick multiple commits
ods cherry-pick abc123 def456 ghi789 --release 2.5

screenshot-diff - Visual Regression Testing

Compare Playwright screenshots against baselines and generate visual diff reports. Baselines are stored per-project and per-revision in S3:

s3://<bucket>/baselines/<project>/<rev>/

This allows storing baselines for main, release branches (release/2.5), and version tags (v2.0.0) side-by-side. Revisions containing / are sanitised to - in the S3 path (e.g. release/2.5release-2.5).

ods screenshot-diff <subcommand>

Subcommands:

  • compare - Compare screenshots against baselines and generate a diff report
  • upload-baselines - Upload screenshots to S3 as new baselines

The --project flag provides sensible defaults so you don't need to specify every path. When set, the following defaults are applied:

Flag Default
--baseline s3://onyx-playwright-artifacts/baselines/<project>/<rev>/
--current web/output/screenshots/
--output web/output/screenshot-diff/<project>/index.html
--rev main

The S3 bucket defaults to onyx-playwright-artifacts and can be overridden with the PLAYWRIGHT_S3_BUCKET environment variable.

compare Flags:

Flag Default Description
--project Project name (e.g. admin); sets sensible defaults
--rev main Revision baseline to compare against
--from-rev Source (older) revision for cross-revision comparison
--to-rev Target (newer) revision for cross-revision comparison
--baseline Baseline directory or S3 URL (s3://...)
--current Current screenshots directory or S3 URL (s3://...)
--output screenshot-diff/index.html Output path for the HTML report
--threshold 0.2 Per-channel pixel difference threshold (0.0–1.0)
--max-diff-ratio 0.01 Max diff pixel ratio before marking as changed

upload-baselines Flags:

Flag Default Description
--project Project name (e.g. admin); sets sensible defaults
--rev main Revision to store the baseline under
--dir Local directory containing screenshots to upload
--dest S3 destination URL (s3://...)
--delete false Delete S3 files not present locally

Examples:

# Compare local screenshots against the main baseline (default)
ods screenshot-diff compare --project admin

# Compare against a release branch baseline
ods screenshot-diff compare --project admin --rev release/2.5

# Compare two revisions directly (both sides fetched from S3)
ods screenshot-diff compare --project admin --from-rev v1.0.0 --to-rev v2.0.0

# Compare with explicit paths
ods screenshot-diff compare \
  --baseline ./baselines \
  --current ./web/output/screenshots/ \
  --output ./report/index.html

# Upload baselines for main (default)
ods screenshot-diff upload-baselines --project admin

# Upload baselines for a release branch
ods screenshot-diff upload-baselines --project admin --rev release/2.5

# Upload baselines for a version tag
ods screenshot-diff upload-baselines --project admin --rev v2.0.0

# Upload with delete (remove old baselines not in current set)
ods screenshot-diff upload-baselines --project admin --delete

The compare subcommand writes a summary.json alongside the report with aggregate counts (changed, added, removed, unchanged). The HTML report is only generated when visual differences are detected.

trace - View Playwright Traces from CI

Download Playwright trace artifacts from a GitHub Actions run and open them with playwright show-trace. Traces are only generated for failing tests (retain-on-failure).

ods trace [run-id-or-url]

The run can be specified as a numeric run ID, a full GitHub Actions URL, or omitted to find the latest Playwright run for the current branch.

Flags:

Flag Default Description
--branch, -b Find latest run for this branch
--pr Find latest run for this PR number
--project, -p Filter to a specific project (admin, exclusive, lite)
--list, -l false List available traces without opening
--no-open false Download traces but don't open them

When multiple traces are found, an interactive picker lets you select which traces to open. Use arrow keys or j/k to navigate, space to toggle, a to select all, n to deselect all, and enter to open. Falls back to a plain-text prompt when no TTY is available.

Downloaded artifacts are cached in /tmp/ods-traces/<run-id>/ so repeated invocations for the same run are instant.

Examples:

# Latest run for the current branch
ods trace

# Specific run ID
ods trace 12345678

# Full GitHub Actions URL
ods trace https://github.com/onyx-dot-app/onyx/actions/runs/12345678

# Latest run for a PR
ods trace --pr 9500

# Latest run for a specific branch
ods trace --branch main

# Only download admin project traces
ods trace --project admin

# List traces without opening
ods trace --list

Testing Changes Locally (Dry Run)

Both run-ci and cherry-pick support --dry-run to test without making remote changes:

# See what would happen without pushing
ods run-ci 7353 --dry-run
ods cherry-pick abc123 --release 2.5 --dry-run

Upgrading

To upgrade the stable version, upgrade it as you would any other requirement.

Building from source

Generally, go build . or go install . are sufficient.

go build . will output a tools/ods/ods binary which you can call normally,

./ods --version

while go install . will output to your GOPATH (defaults ~/go/bin/ods),

~/go/bin/ods --version

Typically, GOPATH is added to your shell's PATH, but this may be confused easily during development with the pip version of ods installed in the Onyx venv.

To build the wheel,

uv build --wheel

To build and install the wheel,

uv pip install .

Deploy

Releases are deployed automatically when git tags prefaced with ods/ are pushed to GitHub.

The release-tag package can be used to calculate and push the next tag automatically,

tag --prefix ods

See also, .github/workflows/release-devtools.yml.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

onyx_devtools-0.10.5-py3-none-win_arm64.whl (16.0 MB view details)

Uploaded Python 3Windows ARM64

onyx_devtools-0.10.5-py3-none-win_amd64.whl (17.9 MB view details)

Uploaded Python 3Windows x86-64

onyx_devtools-0.10.5-py3-none-manylinux_2_17_x86_64.whl (17.7 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ x86-64

onyx_devtools-0.10.5-py3-none-manylinux_2_17_aarch64.whl (15.9 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ ARM64

onyx_devtools-0.10.5-py3-none-macosx_11_0_arm64.whl (16.5 MB view details)

Uploaded Python 3macOS 11.0+ ARM64

onyx_devtools-0.10.5-py3-none-macosx_10_12_x86_64.whl (17.8 MB view details)

Uploaded Python 3macOS 10.12+ x86-64

File details

Details for the file onyx_devtools-0.10.5-py3-none-win_arm64.whl.

File metadata

  • Download URL: onyx_devtools-0.10.5-py3-none-win_arm64.whl
  • Upload date:
  • Size: 16.0 MB
  • Tags: Python 3, Windows ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.25 {"installer":{"name":"uv","version":"0.11.25","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for onyx_devtools-0.10.5-py3-none-win_arm64.whl
Algorithm Hash digest
SHA256 83dcc0583934034f48ba069c1dfb30cfb7acce3d7d76ec9c3cb76f9d7b38acbd
MD5 e38d2c5081b116b0f547aea2e7970b17
BLAKE2b-256 f586e4a8ea0d6088ae4a5c7bf7b32f90bb93fd4d19e21ddb59d8afe1348fb4c7

See more details on using hashes here.

File details

Details for the file onyx_devtools-0.10.5-py3-none-win_amd64.whl.

File metadata

  • Download URL: onyx_devtools-0.10.5-py3-none-win_amd64.whl
  • Upload date:
  • Size: 17.9 MB
  • Tags: Python 3, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.25 {"installer":{"name":"uv","version":"0.11.25","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for onyx_devtools-0.10.5-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 64242470aca860e1a6dd1e307e41d7be123894a69c2f897d01aef113b0665e1c
MD5 d5a386de8220cd197bcc665ed2cefc36
BLAKE2b-256 d9b278e2252e8dbf0cd36e7dd96b7072b48343085feda15a0df466c9e3d788cd

See more details on using hashes here.

File details

Details for the file onyx_devtools-0.10.5-py3-none-manylinux_2_17_x86_64.whl.

File metadata

  • Download URL: onyx_devtools-0.10.5-py3-none-manylinux_2_17_x86_64.whl
  • Upload date:
  • Size: 17.7 MB
  • Tags: Python 3, manylinux: glibc 2.17+ x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.25 {"installer":{"name":"uv","version":"0.11.25","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for onyx_devtools-0.10.5-py3-none-manylinux_2_17_x86_64.whl
Algorithm Hash digest
SHA256 82c2b8d1d3c93603b8d2e7089787c8c929dce578dc3330e720cb8ce5584203e7
MD5 7c474ce795d8f313a8d7b55d9e154892
BLAKE2b-256 3a234da3c4c9e81d83e0cbbeca8fe5d73208e03ce3a8a92a59daa4378e325bdd

See more details on using hashes here.

File details

Details for the file onyx_devtools-0.10.5-py3-none-manylinux_2_17_aarch64.whl.

File metadata

  • Download URL: onyx_devtools-0.10.5-py3-none-manylinux_2_17_aarch64.whl
  • Upload date:
  • Size: 15.9 MB
  • Tags: Python 3, manylinux: glibc 2.17+ ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.25 {"installer":{"name":"uv","version":"0.11.25","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for onyx_devtools-0.10.5-py3-none-manylinux_2_17_aarch64.whl
Algorithm Hash digest
SHA256 ff5fb6fd7b86530f926246a946a40cba4fe5fe7ee1f0f7458593d37d8f7abbfe
MD5 7bd6ea5a5c87fb494791ed1a47b5e45d
BLAKE2b-256 97bcd1e82f5d18fb61474e1f279cf0ffdaef6b43ea901ca855160be9d786c9e4

See more details on using hashes here.

File details

Details for the file onyx_devtools-0.10.5-py3-none-macosx_11_0_arm64.whl.

File metadata

  • Download URL: onyx_devtools-0.10.5-py3-none-macosx_11_0_arm64.whl
  • Upload date:
  • Size: 16.5 MB
  • Tags: Python 3, macOS 11.0+ ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.25 {"installer":{"name":"uv","version":"0.11.25","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for onyx_devtools-0.10.5-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 cb5b5b6263fb8a3925ce4e59530e8b6c7c1fcddf3e25b3b1425ab2516b588501
MD5 c22f5fc96ded586644c953d70eb8e565
BLAKE2b-256 1aad22330f0cb215add16490b9ee912e1b6fa14dd8a22aeaa4f664e9338a984f

See more details on using hashes here.

File details

Details for the file onyx_devtools-0.10.5-py3-none-macosx_10_12_x86_64.whl.

File metadata

  • Download URL: onyx_devtools-0.10.5-py3-none-macosx_10_12_x86_64.whl
  • Upload date:
  • Size: 17.8 MB
  • Tags: Python 3, macOS 10.12+ x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.25 {"installer":{"name":"uv","version":"0.11.25","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for onyx_devtools-0.10.5-py3-none-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 f44b76d7de8d81b1cb38e97d19d67486e39c89b03528963c4d7c7f6673bf1310
MD5 8f38d21b0422d3bc9982b3a9d193f2cb
BLAKE2b-256 c4f28e55f6475a9b6710561e534d192763b79a14b1f48f080be7e831d9e95312

See more details on using hashes here.

Release history Release notifications | RSS feed

0.12.2

6 files

0.12.1

6 files

0.12.0

6 files

0.11.1

6 files

0.11.0

6 files

0.10.6

6 files

This release

0.10.5 This release

6 files

0.10.4

6 files

0.10.3

6 files

0.10.2

6 files

0.10.1

6 files

0.10.0

6 files

0.9.6

6 files

0.9.5

6 files

0.9.4

6 files

0.9.3

6 files

0.9.2

6 files

0.9.1

4 files

0.9.0

6 files

0.8.3

6 files

0.8.2

6 files

0.8.1

6 files

0.8.0

6 files

0.7.8

6 files

0.7.7

6 files

0.7.6

6 files

0.7.5

6 files

0.7.4

6 files

0.7.3

6 files

0.7.2

6 files

0.7.1

6 files

0.7.0

6 files

0.6.4

6 files

0.6.3

7 files

0.6.2

7 files

0.6.1

7 files

0.6.0

7 files

0.5.7

7 files

0.5.6

7 files

0.5.5

7 files

0.5.4

7 files

0.5.3

7 files

0.5.2

7 files

0.5.1

7 files

0.5.0

7 files

0.4.1

7 files

0.4.0

7 files

0.3.2

7 files

0.3.1

7 files

0.3.0

7 files

0.2.2

7 files

0.2.1

7 files

0.2.0

7 files

0.1.1

7 files

0.1.0

7 files

0.0.3

2 files

0.0.2

7 files

0.0.1

7 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page