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
# 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
  • 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

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.4.tar.gz (9.2 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.4-py3-none-any.whl (10.1 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: rsync_ssh_client-0.1.4.tar.gz
  • Upload date:
  • Size: 9.2 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.4.tar.gz
Algorithm Hash digest
SHA256 3c27ceeee6ce0114d8cb9ec402fca2ca8da86bc51231a62afb2952bba59c5a24
MD5 9951b6b96e169c92ec488069fadb1f8f
BLAKE2b-256 f343d8d3c3e09de4063caae8e5c294c66048e9654413a27d212cd6cdc40da1b2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for rsync_ssh_client-0.1.4-py3-none-any.whl
Algorithm Hash digest
SHA256 b040ea536d3388e290b7c92c80178973094f562f56e284114a187fec2a3f5806
MD5 9a573c7a998241124f6454c137f61c41
BLAKE2b-256 866f39a59c4a36bffccd79b4dd36941d68c4ef0d06e6c22222464b84ad87e977

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