rsync-ssh-client
A flexible Python client for rsync over SSH.
Installation
pip install rsync-ssh-client
# or from source
pip install -e .
Features
- Secure file transfers using
rsyncover SSH - Supports both password and SSH private key authentication
- SSH auth via
sshpassor key file - Configurable via Python, YAML, or CLI
- Preserves file ownership and permissions
- Fully typed and testable
--dry-runsupport for safe previews- Avoids host key prompts by writing to
/dev/null
Usage
1. As a Library (Python)
Via direct configuration:
from rsync_ssh_client import RsyncSSHClient, RsyncConfig, RsyncOptions
options = RsyncOptions(
exclude_file=".rsyncignore",
owner=1000,
group=1000,
delete=True,
chmod_flags="Du=rwx,Dgo=rx,Fu=rw,Fog=r",
use_super=True,
rsync_flags=["-avzP"]
)
config = RsyncConfig(
user="deploy",
host="example.com",
ssh_port=22,
ssh_private_key="~/.ssh/id_rsa",
password=None,
use_sshpass=False,
options=options
)
client = RsyncSSHClient(config)
client.put("build/", "/remote/path")
client.get("/remote/logs", "logs/")
Via config file:
# config.yaml
user: deploy
host: example.com
ssh_port: 22
ssh_private_key: ~/.ssh/id_rsa
use_sshpass: false
options:
exclude_file: .rsyncignore
owner: 1000
group: 1000
chmod_flags: Du=rwx,Dgo=rx,Fu=rw,Fog=r
delete: true
use_super: true
rsync_flags:
- -avzP
import yaml
from rsync_ssh_client import RsyncSSHClient, RsyncConfig, RsyncOptions
with open("config.yaml") as f:
data = yaml.safe_load(f)
config = RsyncConfig(
**{
**{k: v for k, v in data.items() if k != "options"},
"options": RsyncOptions(**data.get("options", {}))
}
)
client = RsyncSSHClient(config)
client.put("src", "/dst")
CLI Usage
# using config file
rsync-client put --config config.yaml ./build /remote
rsync-client get --config config.yaml /remote/logs ./logs
# or passing options manually
rsync-client put --user deploy --host example.com ./src /dst \
--exclude-file .rsyncignore --dry-run --use-sshpass --password secret
rsync-client get --user deploy --host example.com /srv/data ./data \
--use-sshpass --password secret --dry-run
Docker Testing
A Dockerfile is included for local testing with an SSH+rsync server:
docker build -t rsync-test .
docker run -d --name rsync-test -p 2222:22 rsync-test
Default credentials:
- user:
rsyncuser - password:
rsyncpass - port:
2222
Optionally mount volumes:
docker run -d --name rsync-test -p 2222:22 -v $(pwd)/remote:/home/rsyncuser/remote rsync-test
Automated test script
Run the following script to:
- create a 1024-byte file with random data
- transfer it via
put - fetch it back via
get - verify the contents match
- perform dry-run tests
#!/bin/bash
set -euo pipefail
mkdir -p test_data test_result
touch .rsyncignore
# Create input file
echo "🔧 Preparing test input..."
head -c 1024 </dev/urandom > test_data/random.bin
# Upload
rsync-client put \
--user rsyncuser \
--host localhost \
--port 2222 \
--password rsyncpass \
--use-sshpass \
--chmod=u+rw \
--exclude-file=.rsyncignore \
--delete \
--use-super \
test_data/random.bin \
/home/rsyncuser/random.bin
# Download
rsync-client get \
--user rsyncuser \
--host localhost \
--port 2222 \
--password rsyncpass \
--use-sshpass \
--chmod=u+rw \
--exclude-file=.rsyncignore \
--delete \
--use-super \
/home/rsyncuser/random.bin \
test_result/random.bin
cmp test_data/random.bin test_result/random.bin && echo "Files match!"
# Dry-run PUT
rsync-client put \
--user rsyncuser \
--host localhost \
--port 2222 \
--password rsyncpass \
--use-sshpass \
--dry-run \
test_data/random.bin \
/home/rsyncuser/random_dryrun.bin
# Dry-run GET
rsync-client get \
--user rsyncuser \
--host localhost \
--port 2222 \
--password rsyncpass \
--use-sshpass \
--dry-run \
/home/rsyncuser/random.bin \
test_result/random_dryrun.bin
echo "Dry-run tests executed (no files should have been transferred)"
Development
Install dev dependencies:
pip install -r requirements-dev.txt
Run checks:
ruff check . --fi
black .
mypy rsync_ssh_client/
pytest
License
Licensed under the Apache License 2.0
Author
Created by ilia iakhin
Metadata
Release files for rsync-ssh-client 0.1.4
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| rsync_ssh_client-0.1.4.tar.gz | 9.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| rsync_ssh_client-0.1.4-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 19.3 kB
Release files / rsync_ssh_client-0.1.4.tar.gz
| Download URL | rsync_ssh_client-0.1.4.tar.gz |
|---|---|
| Size | 9.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3c27ceeee6ce0114d8cb9ec402fca2ca8da86bc51231a62afb2952bba59c5a24
|
|
BLAKE2b-256 checksum How to use checksums |
f343d8d3c3e09de4063caae8e5c294c66048e9654413a27d212cd6cdc40da1b2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.2
|
Release files / rsync_ssh_client-0.1.4-py3-none-any.whl
| Download URL | rsync_ssh_client-0.1.4-py3-none-any.whl |
|---|---|
| Size | 10.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b040ea536d3388e290b7c92c80178973094f562f56e284114a187fec2a3f5806
|
|
BLAKE2b-256 checksum How to use checksums |
866f39a59c4a36bffccd79b4dd36941d68c4ef0d06e6c22222464b84ad87e977
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.2
|