Metadata-Version: 2.4
Name: runpod-deploy
Version: 0.8.4
Summary: Config-driven RunPod orchestration for reusable GPU project deployments.
Project-URL: Homepage, https://github.com/brandon-behring/runpod-deploy
Project-URL: Source, https://github.com/brandon-behring/runpod-deploy
Project-URL: Issues, https://github.com/brandon-behring/runpod-deploy/issues
Project-URL: Changelog, https://github.com/brandon-behring/runpod-deploy/blob/main/CHANGELOG.md
Project-URL: Documentation, https://brandon-behring.github.io/runpod-deploy/
Project-URL: Releases, https://github.com/brandon-behring/runpod-deploy/releases
Author: Brandon Behring
License-Expression: MIT
License-File: LICENSE
Keywords: deployment,gpu,mlops,orchestration,runpod
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.13
Classifier: Typing :: Typed
Requires-Python: >=3.13
Requires-Dist: pyyaml>=6.0
Provides-Extra: completion
Requires-Dist: argcomplete>=3.5; extra == 'completion'
Provides-Extra: dev
Requires-Dist: argcomplete>=3.5; extra == 'dev'
Requires-Dist: black>=26.0; extra == 'dev'
Requires-Dist: mypy>=1.10; extra == 'dev'
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
Requires-Dist: pytest-markdown-docs>=0.9; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.15; extra == 'dev'
Requires-Dist: types-pyyaml; extra == 'dev'
Provides-Extra: docs
Requires-Dist: linkify-it-py>=2.0; extra == 'docs'
Requires-Dist: myst-nb>=1.1; extra == 'docs'
Requires-Dist: pydata-sphinx-theme>=0.16; extra == 'docs'
Requires-Dist: sphinx-autobuild>=2024.10.3; extra == 'docs'
Requires-Dist: sphinx-autodoc-typehints>=2.0; extra == 'docs'
Requires-Dist: sphinx-copybutton>=0.5; extra == 'docs'
Requires-Dist: sphinx-design>=0.6; extra == 'docs'
Requires-Dist: sphinx>=7.3; extra == 'docs'
Description-Content-Type: text/markdown

# runpod-deploy

[![PyPI version](https://img.shields.io/pypi/v/runpod-deploy.svg)](https://pypi.org/project/runpod-deploy/)
[![CI](https://github.com/brandon-behring/runpod-deploy/actions/workflows/test.yml/badge.svg)](https://github.com/brandon-behring/runpod-deploy/actions/workflows/test.yml)
[![Docs](https://github.com/brandon-behring/runpod-deploy/actions/workflows/docs.yml/badge.svg)](https://brandon-behring.github.io/runpod-deploy/)
[![Python](https://img.shields.io/pypi/pyversions/runpod-deploy.svg)](https://pypi.org/project/runpod-deploy/)
[![Downloads](https://static.pepy.tech/badge/runpod-deploy)](https://pepy.tech/project/runpod-deploy)
[![License](https://img.shields.io/pypi/l/runpod-deploy.svg)](https://github.com/brandon-behring/runpod-deploy/blob/main/LICENSE)

`runpod-deploy` is a config-driven RunPod orchestration package for reusable
GPU project deployments. It owns the RunPod mechanics; consumer repos own their
job configs and project commands.

## Quickstart

```bash
pip install runpod-deploy

# Smoke-test with the bundled hello example (no RunPod account needed):
runpod-deploy run --config examples/hello/hello.yaml --offline-dry-run

# Or against the cheapest end-to-end pipeline:
runpod-deploy validate --config examples/smoke/a4000_smoke.yaml
runpod-deploy run --config examples/smoke/a4000_smoke.yaml --offline-dry-run
runpod-deploy logs --config examples/smoke/a4000_smoke.yaml          # live-tail the active pod's run log
runpod-deploy cleanup --state-file ~/.runpod-smoke-current            # release the active pod's volume disk
runpod-deploy ls-stale                                                # audit every EXITED pod + estimated $/day
runpod-deploy cleanup --all-stopped --yes                             # bulk-release every paused pod
```

`--offline-dry-run` prints the provision/stage/launch/pull/stop command shape
without calling `runpodctl`, SSH, or rsync. For a real end-to-end deploy on a
cheap GPU, see [`examples/smoke/README.md`](examples/smoke/README.md) — it
walks through the per-host setup (SSH key registration, rsync version) once.

For new consumers, [`docs/source/quickstart.md`](docs/source/quickstart.md) is the 5-minute
onboarding walkthrough, and [`docs/source/lifecycle.md`](docs/source/lifecycle.md) explains
what happens at each phase of a `runpod-deploy run`.

**Optional**: shell tab completion. Install via the `[completion]` extra and
register with your shell:

```bash
pip install runpod-deploy[completion]
eval "$(register-python-argcomplete runpod-deploy)"   # bash/zsh
```

Add the `eval` line to your `~/.bashrc` or `~/.zshrc` for persistence.

**Contributors**: see [`CONTRIBUTING.md`](CONTRIBUTING.md) for the editable
install (`uv pip install -e ".[dev]"`), pre-commit setup, and the
fork → branch → PR → CI flow.

## Examples

| Config | What it does |
| --- | --- |
| [`smoke/a4000_smoke.yaml`](examples/smoke/a4000_smoke.yaml) | Minimal nvidia-smi check on RTX A4000/A4500/A100 in EU-RO-1 — cheapest end-to-end pipeline test |
| [`prompt-injection-v3/v3_1_ephemeral.yaml`](examples/prompt-injection-v3/v3_1_ephemeral.yaml) | Full prompt-injection-v3 threshold-free study on A100/H100, ephemeral storage |
| [`prompt-injection-sdd/headline_resume.yaml`](examples/prompt-injection-sdd/headline_resume.yaml) | Headline/resume evaluation, network-volume storage |
| [`research-kb/pdf_embed_gpu.yaml`](examples/research-kb/pdf_embed_gpu.yaml) | GPU-accelerated PDF embedding pipeline |
| [`post_transformers/gpu_benchmark.yaml`](examples/post_transformers/gpu_benchmark.yaml) | post-transformers GPU benchmark workload |

## Consumer-owned configs

The recommended pattern is for the *consumer* repo to own its runpod-deploy
job YAML alongside the project. The YAML lives at
`consumer-repo/configs/runpod/*.yaml`, and `local.project_root` is set
relative to that file's directory:

```
my-project/
├── pyproject.toml
├── src/...
└── configs/
    └── runpod/
        └── headline.yaml          # local.project_root: ../..
```

```yaml
# configs/runpod/headline.yaml
local:
  project_root: ../..   # one level for runpod/, one for configs/
```

`../..` resolves to `my-project/`, which is what gets rsynced to the pod.
A common off-by-one — `../../..` from the same location — resolves to your
$HOME directory and would stage the entire home tree to the pod;
`runpod-deploy validate` (and any `run`) fails-fast in this case.

The example configs under `examples/` are *not* consumer-owned — they live
inside this repo, so they use longer paths (`../../../prompt-injection-v3`)
to reach back to a sibling consumer repo. Don't copy that pattern when
authoring configs *inside* your own consumer repo.

## Model

Version 1 supports one job per YAML file:

- RunPod pod settings: image, datacenter, GPU order, storage mode, cost cap.
- Local staging: rsync pushes from the consumer repo to the pod.
- Remote setup and preflight commands.
- Detached remote run script, success marker, and failure markers.
- Artifact pulls and a reproducibility manifest.

The core is intentionally project-neutral. If a project needs special behavior,
put it in its config or shell commands. Python hooks are reserved for a future
schema version after at least two projects need the same extension point.

## Docs

**Full site (searchable, with API reference):**
**[https://brandon-behring.github.io/runpod-deploy/](https://brandon-behring.github.io/runpod-deploy/)**

Direct links to the GitHub-rendered markdown:

- [Quickstart](docs/source/quickstart.md) — 5-minute onboarding
- [Lifecycle](docs/source/lifecycle.md) — what happens at each phase of a `run`
- [Config reference](docs/source/config-reference.md)
- [RunPod gotchas](docs/source/runpod-gotchas.md)
- [Extending guide](docs/source/extending.md)
- [V3 migration guide](docs/source/migration-v3.md)
- [Coding standards](STYLE.md)
