Lightweight idempotent one-shot job runner
Project description
orchesjob
Overview
orchesjob is a lightweight, idempotent one-shot job runner designed for remote orchestration scenarios.
It is intended to be used with external orchestrators such as Apache Airflow, Amazon MWAA, cron, CI/CD pipelines, or SSH-based automation, where a remote job needs to be started, monitored, and safely resumed across retries.
A primary goal of orchesjob is to prevent duplicate execution of non-idempotent remote jobs when the orchestrator retries a start operation after SSH failures, timeouts, worker interruptions, or network issues.
Features
- Idempotency — safe to call multiple times with the same run key while a job is active
- Re-runnable — finished jobs can be re-triggered under the same run key
- Run history — all past executions are retained and queryable
- SQLite backend — fast indexed lookups that stay fast as history grows
- Sync & async modes — wait for completion or fire and forget
- Structured output — every command prints JSON
Requirements
- Python ≥ 3.12
- No third-party dependencies
Installation
Recommended — pipx (isolated, globally available CLI):
pipx install orchesjob
pip:
pip install orchesjob
The default state directory is /var/lib/orchesjob. Override it with the
ORCHESJOB_HOME environment variable:
export ORCHESJOB_HOME=~/.local/share/orchesjob
Quick Start
# Start a job (async)
orchesjob start --run-key nightly-backup -- /usr/local/bin/backup.sh
# Start a job and wait for it to finish
orchesjob start --run-key nightly-backup --sync -- /usr/local/bin/backup.sh
# Check the current status
orchesjob status --run-key nightly-backup
# Print stdout
orchesjob logs --run-key nightly-backup --stream stdout
Commands
start
Start a job or return the existing one if it is still running.
orchesjob start --run-key KEY [--sync] [--strict] [--] COMMAND [ARGS...]
| Flag | Description |
|---|---|
--run-key KEY |
Idempotency key (required) |
--sync |
Block until the job finishes |
--strict |
One execution per run key, ever — see below |
-- |
Separator between orchesjob flags and the command |
Idempotency rules:
| Existing job state | Default behaviour | With --strict |
|---|---|---|
RUNNING / STARTING |
Returns the existing job | Returns the existing job |
Terminal (SUCCEEDED, FAILED, LOST, CANCELLED) |
Starts a new job | Returns the existing job |
| None | Starts a new job | Starts a new job |
Strict idempotency
By default, orchesjob provides active-execution idempotency: repeated start
calls with the same run_key return the existing job only while it is
STARTING or RUNNING.
Use --strict when the same run_key must never create more than one physical
execution, even after the previous job has already reached a terminal state.
This is useful when the run key already encodes uniqueness (e.g. a date or
event ID) and re-triggering would be a bug.
orchesjob start --run-key daily-import-2026-05-02 --strict -- /jobs/import.sh
Example output:
{
"accepted": true,
"existing": false,
"mode": "sync",
"strict": false,
"run_key": "nightly-backup",
"job_id": "3f2a1b4c-...",
"pid": 12345,
"command": ["/usr/local/bin/backup.sh"],
"status": "SUCCEEDED",
"stdout_file": "/var/lib/orchesjob/logs/3f2a1b4c-....stdout",
"stderr_file": "/var/lib/orchesjob/logs/3f2a1b4c-....stderr",
"exit_code": 0,
"started_at": "2026-05-01T02:00:00.123456+09:00",
"finished_at": "2026-05-01T02:05:42.654321+09:00"
}
status
Get the current status of a job, or the full run history for a run key.
orchesjob status (--run-key KEY | --job-id ID) [--all]
| Flag | Description |
|---|---|
--run-key KEY |
Look up by run key |
--job-id ID |
Look up by job ID |
--all |
Return all past executions for the run key as a JSON array (requires --run-key) |
Without --all, returns a single JSON object for the most recent job.
With --all, returns a JSON array ordered by started_at descending.
logs
Print the stdout or stderr of a job.
orchesjob logs (--run-key KEY | --job-id ID) [--stream stdout|stderr]
| Flag | Description |
|---|---|
--stream stdout |
Print stdout (default) |
--stream stderr |
Print stderr |
clean
Delete terminal jobs finished before a given point in time, along with their
log files. Jobs that are currently RUNNING or STARTING are never deleted.
orchesjob clean --before DATETIME [--dry-run]
| Flag | Description |
|---|---|
--before DATETIME |
ISO 8601 datetime cutoff. Times without a timezone offset are interpreted as local time. |
--dry-run |
Print what would be deleted to stderr without making any changes |
Examples:
# Delete all finished jobs from before 2026-01-01 (local time)
orchesjob clean --before 2026-01-01
# Preview what would be removed from the last 7 days
orchesjob clean --before "$(date -d '7 days ago' -Iseconds)" --dry-run
Output:
{ "deleted": 42, "errors": 0 }
Job Statuses
| Status | Description |
|---|---|
STARTING |
Job record created; worker process not yet confirmed running |
RUNNING |
Worker is executing the command |
SUCCEEDED |
Command exited with code 0 |
FAILED |
Command exited with a non-zero code, or failed to launch |
LOST |
Worker process disappeared without writing a result |
CANCELLED |
Job was cancelled (reserved for future use) |
State Directory Layout
$ORCHESJOB_HOME/
├── orchesjob.db # SQLite database (run keys + job metadata)
└── logs/
├── <job-id>.stdout
└── <job-id>.stderr
Exit Codes
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | General error |
| 2 | Invalid arguments |
| 3 | Job / run key not found |
| 4 | Inconsistent internal state |
| 5 | Lock error |
License
MIT — Copyright (c) 2026 Ryosuke Muraki
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file orchesjob-1.0.2.tar.gz.
File metadata
- Download URL: orchesjob-1.0.2.tar.gz
- Upload date:
- Size: 16.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
75a5d2e11d1117a914c6da60e7565bf46c77eecf35b7436a39b9cbeec8c23749
|
|
| MD5 |
c9cbd0136a81f38183cfe50fa1342a2b
|
|
| BLAKE2b-256 |
b4a18f8b47675daaea912b5437fb56e74b910c7e0966e1d37782645738edc900
|
Provenance
The following attestation bundles were made for orchesjob-1.0.2.tar.gz:
Publisher:
publish-pypi.yml on rmuraki/orchesjob
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
orchesjob-1.0.2.tar.gz -
Subject digest:
75a5d2e11d1117a914c6da60e7565bf46c77eecf35b7436a39b9cbeec8c23749 - Sigstore transparency entry: 1429045776
- Sigstore integration time:
-
Permalink:
rmuraki/orchesjob@68ef568bb9851d44ccec78d5fc656d2f57ab9212 -
Branch / Tag:
refs/tags/v1.0.2 - Owner: https://github.com/rmuraki
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@68ef568bb9851d44ccec78d5fc656d2f57ab9212 -
Trigger Event:
push
-
Statement type:
File details
Details for the file orchesjob-1.0.2-py3-none-any.whl.
File metadata
- Download URL: orchesjob-1.0.2-py3-none-any.whl
- Upload date:
- Size: 12.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4d6b563a75d7f3e959b0b8181bf574b14502ea4bf4e13f0915de359039badf35
|
|
| MD5 |
08576259ceb7e52ca54a48ea52a1d059
|
|
| BLAKE2b-256 |
0e3c57800094098506eadda8e716c68a1d6eb5bcbcfebec2bb4d9a253078cf0e
|
Provenance
The following attestation bundles were made for orchesjob-1.0.2-py3-none-any.whl:
Publisher:
publish-pypi.yml on rmuraki/orchesjob
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
orchesjob-1.0.2-py3-none-any.whl -
Subject digest:
4d6b563a75d7f3e959b0b8181bf574b14502ea4bf4e13f0915de359039badf35 - Sigstore transparency entry: 1429045779
- Sigstore integration time:
-
Permalink:
rmuraki/orchesjob@68ef568bb9851d44ccec78d5fc656d2f57ab9212 -
Branch / Tag:
refs/tags/v1.0.2 - Owner: https://github.com/rmuraki
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@68ef568bb9851d44ccec78d5fc656d2f57ab9212 -
Trigger Event:
push
-
Statement type: