remote-task
Upload code to an Ubuntu host, register jobs in a remote ledger, then queue or run them over SSH. Does not kill processes already running on the host.
- PyPI name:
remote-task - CLI:
rtask - Import:
remote_task - SSH prefers local
ssh/rsync/scp(password viasshpass+RTASK_SSH_PASS); falls back to paramiko - Optional encryption:
pip install 'remote-task[encrypt]'(uses pyfernet-payload)
Install
pip install remote-task
# with pyfernet encrypt/run helpers
pip install 'remote-task[encrypt]'
From a local clone:
python3 -m pip install .
# or editable
python3 -m pip install -e '.[dev]'
Host settings
Passwords stay in environment variables. Never put them in config files.
| Variable | Meaning |
|---|---|
RTASK_SSH |
user@host |
RTASK_SSH_PORT |
SSH port (default 22) |
RTASK_SSH_PASS |
password (optional if you use keys) |
RTASK_REMOTE_CWD |
remote working directory |
RTASK_PYTHON |
remote interpreter (default python3) |
PYFERNET_PASSWORD |
passphrase for encrypt/run (optional extra) |
JSON config (--config) may contain only host, port, remote_cwd / cwd, python.
{
"host": "user@example.com",
"port": 22,
"remote_cwd": "/home/user/work",
"python": "/usr/bin/python3"
}
Remote job ledger
Jobs live on the remote host at:
<remote_cwd>/.remote-task/jobs.json
Example entry:
{
"version": 1,
"jobs": [
{
"id": "next",
"block": ["queue-remote-wait.py prev", "train_foo.py"],
"run": "/usr/bin/python3 -u train_bar.py",
"note": "",
"created_at": "2026-10-28T07:00:00Z",
"encrypt": false,
"payload": null
}
]
}
block uses | on the CLI. Include the previous waiter as queue-remote-wait.py <prev-id> plus the script name the previous job will launch, so the hand-off gap does not start the next job early.
CLI
export RTASK_SSH=user@host
export RTASK_SSH_PASS='…' # optional with keys
export RTASK_REMOTE_CWD=/path/work
# register
rtask register --id next \
--block 'queue-remote-wait.py prev|train_foo.py' \
--run '/usr/bin/python3 -u train_bar.py'
rtask list
# upload code (default excludes .git .venv runs models *.pt …; no --delete)
rtask upload ./my_train
# queue after current work
rtask queue --job next
# or start immediately
rtask run --job next
# status
rtask status
rtask status --json --days 3 --limit 15
Force local tools or paramiko:
rtask status --backend local
rtask status --backend paramiko
Optional encrypt flow
export PYFERNET_PASSWORD='…'
rtask encrypt ./my_train -o dist/train.enc -e train.py \
--upload \
--register-id enc1 \
--block 'queue-remote-wait.py prev|train.py'
rtask queue --job enc1
The registered run is roughly:
python3 -m pyfernet run train.enc --password-env PYFERNET_PASSWORD
The remote host must already have pyfernet-payload installed. The passphrase is not stored in jobs.json; set PYFERNET_PASSWORD in the remote environment for the waiter / process (for example via your login env or a wrapper).
Library sketch
from remote_task.config import resolve_host
from remote_task.ssh import open_backend
from remote_task.jobs import Job
from remote_task.remote_jobs import register_job
from remote_task.upload import upload_dir
from remote_task.queue import start_queue
spec = resolve_host()
with open_backend(spec) as backend:
cwd = spec.require_cwd()
upload_dir(backend, "./my_train", cwd)
register_job(
backend,
cwd,
Job(id="next", block=["queue-remote-wait.py prev", "train_foo.py"],
run="/usr/bin/python3 -u train_bar.py"),
force=True,
)
print(start_queue(
backend,
remote_cwd=cwd,
wait_id="next",
block="queue-remote-wait.py prev|train_foo.py",
run="/usr/bin/python3 -u train_bar.py",
python=spec.python,
))
Build
python3 -m pip install build
python3 -m build
# artifacts in dist/
Safety
- Does not kill remote processes
- Same wait id already running → will not start a second waiter
- Default upload does not use
--delete - Passwords only via env (
RTASK_SSH_PASS,PYFERNET_PASSWORD)
Metadata
Release files for remote-task 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| remote_task-0.1.0.tar.gz | 22.7 kB | Without provenance | Details for remote_task-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| remote_task-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for remote_task-0.1.0-py3-none-any.whl |
Total release size: 47.8 kB
Release files / remote_task-0.1.0.tar.gz
| Download URL | remote_task-0.1.0.tar.gz |
|---|---|
| Size | 22.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c71a173d6ab060ea90b9c068653336522c34d94cb6822deea3cb275cd4c874ab
|
|
BLAKE2b-256 checksum How to use checksums |
1ec96ac6f60158f7932c69195507188ebb657fb1ec4a8ef1a4bfa60f5779ce37
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.10.18
|
Release files / remote_task-0.1.0-py3-none-any.whl
| Download URL | remote_task-0.1.0-py3-none-any.whl |
|---|---|
| Size | 25.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
8e9fa33844fc774d6964e0aa5a65790e970817ab36a71dc8c4fac80b8ae428fc
|
|
BLAKE2b-256 checksum How to use checksums |
c657420d665140040bbbd1fbcb92e33b42d9a2d62aec14de88df6c7ba0671df2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.10.18
|
Security for remote-task 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.