Skip to main content

A Python wrapper for rsync over SSH

Project description

PyPI - Downloads PyPI License

rsync-ssh-client

A flexible Python client for rsync over SSH.

🚀 Installation

pip install rsync-ssh-client  # when published
# or from source
pip install -e .

📦 Features

  • Secure file transfers using rsync over SSH
  • Supports both password and SSH private key authentication
  • SSH auth via sshpass or key file
  • Configurable via Python, YAML, or CLI
  • Preserves file ownership and permissions
  • Fully typed and testable
  • --dry-run support for safe previews

🧑‍💻 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

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

rsync_ssh_client-0.1.3.tar.gz (8.9 kB view details)

Uploaded Source

Built Distribution

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

rsync_ssh_client-0.1.3-py3-none-any.whl (9.9 kB view details)

Uploaded Python 3

File details

Details for the file rsync_ssh_client-0.1.3.tar.gz.

File metadata

  • Download URL: rsync_ssh_client-0.1.3.tar.gz
  • Upload date:
  • Size: 8.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.2

File hashes

Hashes for rsync_ssh_client-0.1.3.tar.gz
Algorithm Hash digest
SHA256 94369f32f994a79838d8790867dba64db7264e8d79689d150c51585572314e76
MD5 f90201b63469a5128f9595cc78af394d
BLAKE2b-256 cb984f4f8a845b815bb0743f771926d7099a9438ce0e6a59099f41eb9fc76440

See more details on using hashes here.

File details

Details for the file rsync_ssh_client-0.1.3-py3-none-any.whl.

File metadata

File hashes

Hashes for rsync_ssh_client-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 705ad7d634fbfa645b7a915416c670b013e612a6ebc3a07ec5dfb2b771aba7d0
MD5 13c0e8d49b2a99b0ccd880966b0c26c7
BLAKE2b-256 448a97668478fa590581ce3500880b485401c599c819c30cba053a22200f36c4

See more details on using hashes here.

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