Skip to main content

Open the Pod Bay Door, Hal: run model-backed scripts on RunPod.

Project description

OPBDH

Open the Pod Bay Door, Hal.

In 2001: A Space Odyssey, Dave asks HAL to open the pod bay doors and gets the most famous refusal in cinema: "I'm sorry, Dave, I'm afraid I can't do that."

OPBDH is the obliging counterpart: a small command-line tool that, when asked, actually opens the pod bay door — it launches a RunPod GPU pod, runs your model-backed script on it, brings your results home, and shuts the pod down.

What it does

One opbdh launch performs the whole mission:

  1. Verifies your code statically (Python byte-compiles, shell scripts pass bash -n) before any money is spent.
  2. Picks GPU candidates from a VRAM requirement and an optional hourly-price cap.
  3. Optionally creates or attaches a network volume sized from the Hugging Face model's actual weight files, so model downloads survive across runs.
  4. Creates the pod, uploads your code, pre-downloads the model into the cache, and runs your command.
  5. Monitors the run, continuously syncing remote logs/ and results/ into a local runpod_results/<run_id>/ directory.
  6. Enforces a spend guard — if the estimated cost of the run crosses max_spend_dollars, the job is stopped.
  7. Deletes the pod when the run finishes (or fails), unless you ask to keep it.

Install

pip install opbdh

Requirements: macOS or Linux, Python ≥ 3.11, and ssh/scp on your PATH. An SSH keypair is used to reach the pod (~/.ssh/id_ed25519 by default; configurable).

Configure

Set your RunPod credentials:

export RUNPOD_API_TOKEN="..."
export HF_TOKEN="..."   # optional, for private/gated Hugging Face models

Create a config interactively:

opbdh config wizard

Or write one directly:

opbdh config write --model Qwen/Qwen2.5-0.5B-Instruct --code "{cwd}/run.py" --vram-gb 24 --max-spend 5

Config is merged from the global ~/.config/opbdh/config.json and a local opbdh.json or .opbdh.json (discovered upward from the working directory), with local values overriding global ones and command-line flags overriding both.

String values support placeholders — {cwd}, {model_id}, {model_slug}, {run_id}, {timestamp}, {config_dir} — and environment variables ($VAR / ${VAR}).

Run

The guided way:

opbdh run wizard

The direct way:

opbdh run now ./run.py \
  --model Qwen/Qwen2.5-0.5B-Instruct \
  --vram-gb 48 \
  --max-dollars-per-hour 2 \
  --max-spend 5

Or the short alias:

opbdh launch ./run.py --model Qwen/Qwen2.5-0.5B-Instruct --dry-run

--dry-run verifies your code and prints the full plan without contacting RunPod. Without --yes, every real launch shows the estimated hourly price and asks for confirmation before any billable compute starts.

Inspecting before you fly

opbdh plan ./run.py --model Org/Model     # show the plan for a run
opbdh verify ./run.py                     # static checks only
opbdh gpus --vram-gb 48                   # see GPU candidates and price estimates
opbdh models search qwen                  # search Hugging Face models
opbdh models size Qwen/Qwen2.5-0.5B-Instruct   # weight size + suggested volume

Your script's environment

On the pod, your code runs from /opbdh-run/user/ with:

  • OPBDH_MODEL_ID — the configured Hugging Face model id
  • OPBDH_RESULTS_DIR — write your artifacts here
  • The standard Hugging Face cache variables (HF_HOME, HUGGINGFACE_HUB_CACHE, …) pointed at the pod or network-volume cache, with the model already downloaded if pre_download_model is on
  • HF_TOKEN, if set locally — passed to the job as a session environment variable, never written to disk on the pod
  • A requirements.txt next to your code is pip-installed automatically

Anything your job writes to logs/ and results/ under /opbdh-run is synced back to local runpod_results/<run_id>/ while the run is in progress and again at the end (including on failure).

.env files and the usual junk (.git, .venv, __pycache__, node_modules, …) are never uploaded.

The eye

In an interactive terminal, long waits (pod boot, SSH, upload, your command running) are watched over by a pulsing red HAL eye showing the current phase, elapsed time, and estimated spend:

  ◉  HAL: waiting for pod 3f7a… to boot — 2m 14s · est. $0.08 spent

HAL also has a few things to say at the appropriate moments — declining a launch, completing a mission, or stopping one that got too expensive.

The eye only appears when stdout is a TTY; piped output, CI, and logs are unaffected. Set OPBDH_NO_HAL=1 (or NO_COLOR) to silence HAL entirely.

Safety rails

  • Confirmation gate: real launches require an explicit yes (or --yes).
  • Spend guard: max_spend_dollars caps the estimated cost of a run, measured from pod creation. The estimate is based on OPBDH's built-in price table, which is intentionally conservative — treat it as a guard rail, not an invoice.
  • Cleanup: pods are deleted when the run completes or fails. On failure you get a short window (default 120 s) to opt into keeping the pod for debugging; set keep_pod_on_success to keep it after successful runs.

Development

pip install -e ".[dev]"
ruff check .
pytest

See RELEASING.md for the release process.

License

MIT. Unlike HAL, this software is incapable of refusing to open the pod bay door, becoming sentient, or reading lips.

Project details


Download files

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

Source Distribution

opbdh-0.1.0.tar.gz (22.3 kB view details)

Uploaded Source

Built Distribution

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

opbdh-0.1.0-py3-none-any.whl (24.3 kB view details)

Uploaded Python 3

File details

Details for the file opbdh-0.1.0.tar.gz.

File metadata

  • Download URL: opbdh-0.1.0.tar.gz
  • Upload date:
  • Size: 22.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for opbdh-0.1.0.tar.gz
Algorithm Hash digest
SHA256 19846eb9ce1a9f17c9f78286563ca506e0b6d6996054a219a81764d63144160a
MD5 020f563ccce674bb610c340956ff72cf
BLAKE2b-256 3bc995cb1d2fb1e85a421826ed9b09ba4160c81ccb0891cbd7a23dc9d91f4300

See more details on using hashes here.

Provenance

The following attestation bundles were made for opbdh-0.1.0.tar.gz:

Publisher: publish.yml on lumpenspace/opbdh

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file opbdh-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: opbdh-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 24.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for opbdh-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 17b8bc0a4870988c846ee70707b1dbb5940a81c91f4713fec7c7f3c63a8dcc9c
MD5 7e5f508424cc30c4d63148ce6b53a6b7
BLAKE2b-256 8f00e41aa2bea08f51287ecbffe882c41bce2eb513f4859bac4bf455ee33818a

See more details on using hashes here.

Provenance

The following attestation bundles were made for opbdh-0.1.0-py3-none-any.whl:

Publisher: publish.yml on lumpenspace/opbdh

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

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