Zerobyte SDK
A Python SDK for the Zerobyte backup API — manage volumes, repositories, snapshots, backup schedules, and notifications from Python.
Installation
pip install py-zerobyte
Or install from source:
git clone https://github.com/t0mer/py-zerobyte.git
cd py-zerobyte
pip install -e .
Quick Start
from py_zerobyte import ZerobyteClient
client = ZerobyteClient(
url="http://localhost:4096",
username="admin",
password="your-password"
)
# Auto-login runs on init — you're ready to go
session = client.auth.get_me()
print(f"Logged in as: {session['user']['username']}")
volumes = client.volumes.list()
for v in volumes:
print(f"Volume: {v['name']} shortId: {v['shortId']}")
Features
- Authentication — login, logout, password change via
better-auth - Volumes — create, update, delete, mount/unmount, health check, file browse
- Repositories — manage restic backup repositories (local, S3, R2, SFTP, rclone, …)
- Snapshots — list, inspect, browse files, restore, delete
- Backup Schedules — cron-driven schedules with retention, mirrors, notifications
- Notification Destinations — Telegram, email, Pushover, ntfy, Discord, Slack, webhook
- System — capabilities info, restic password retrieval
Configuration
client = ZerobyteClient(
url="http://localhost:4096", # Zerobyte server URL
username="admin", # Login username
password="your-password", # Login password
auto_login=True # Default: True — logs in during __init__
)
# Manual login (when auto_login=False)
client = ZerobyteClient(url=..., username=..., password=..., auto_login=False)
client.login()
Resource IDs
Zerobyte identifies most resources by a shortId string (e.g. "0-b-U31s", "Eilm20ua"), not by a sequential integer. Always use the shortId field from list/create responses when calling get/update/delete methods.
volumes = client.volumes.list()
vol_id = volumes[0]['shortId'] # e.g. "0-b-U31s"
detail = client.volumes.get(vol_id)
Usage Examples
Authentication
# Check whether any users exist (first-time setup)
status = client.auth.get_status()
if not status['hasUsers']:
client.auth.register("admin", "initial-password")
# Get current session / user info
session = client.auth.get_me()
print(session['user']['username'])
# Change password
client.auth.change_password("old-password", "new-password")
# Logout
client.auth.logout()
Volumes
# List all volumes
volumes = client.volumes.list()
# Create a volume (directory backend)
volume = client.volumes.create({
"name": "my-backup",
"autoRemount": True,
"config": {
"backend": "directory",
"path": "/mnt/backup"
}
})
vid = volume['shortId']
# Get, update, delete
detail = client.volumes.get(vid)
updated = client.volumes.update(vid, {"autoRemount": False})
client.volumes.delete(vid)
# Mount / unmount / health check
client.volumes.mount(vid)
client.volumes.unmount(vid)
health = client.volumes.health_check(vid)
# Browse files
files = client.volumes.list_files(vid, path="/data")
listing = client.volumes.browse_filesystem(path="/mnt")
Repositories
# List all repositories
repos = client.repositories.list()
# Create a local repository
repo = client.repositories.create({
"name": "local-repo",
"compressionMode": "auto",
"config": {
"backend": "local",
"path": "/backups/repo1"
}
})
rid = repo['shortId']
# Get, update (PATCH), delete
detail = client.repositories.get(rid)
updated = client.repositories.update(rid, {"compressionMode": "max"})
client.repositories.delete(rid)
# Doctor (check + repair)
result = client.repositories.doctor(rid)
# List available rclone remotes
remotes = client.repositories.list_rclone_remotes()
Snapshots
# List snapshots for a repository (use repository shortId)
snapshots = client.snapshots.list(repository_name=rid)
if snapshots:
snap_id = snapshots[0]['id']
# Get snapshot detail
detail = client.snapshots.get_details(rid, snap_id)
# Browse files inside a snapshot
files = client.snapshots.list_files(rid, snap_id, path="/home")
# Restore
client.snapshots.restore(rid, {
"target": "/restore/path",
"snapshotId": snap_id,
"include": ["/home/user"],
"exclude": ["/home/user/.cache"]
})
# Delete a snapshot
client.snapshots.delete(rid, snap_id)
Backup Schedules
# List all schedules
schedules = client.backup_schedules.list()
# Create a schedule
schedule = client.backup_schedules.create({
"name": "Daily Backup",
"repositoryId": rid, # repository shortId
"volumeId": 1, # volume numeric id
"cronExpression": "0 2 * * *",
"enabled": True,
"backupPaths": ["/home", "/etc"],
"excludePatterns": ["**/.cache/**"],
"retentionPolicy": {
"keepLast": 7,
"keepDaily": 7,
"keepWeekly": 4,
"keepMonthly": 12
},
"tags": ["daily", "production"]
})
sched_id = schedule['shortId']
# Get, update, delete
detail = client.backup_schedules.get(sched_id)
updated = client.backup_schedules.update(sched_id, {
"repositoryId": rid,
"cronExpression": "0 3 * * *",
"enabled": False
})
client.backup_schedules.delete(sched_id)
# All schedules for one volume
vol_schedules = client.backup_schedules.get_for_volume(volume_id=1)
# Trigger / stop / forget
client.backup_schedules.run_now(sched_id)
client.backup_schedules.stop_backup(sched_id)
client.backup_schedules.run_forget(sched_id)
# Notifications per schedule
client.backup_schedules.update_notifications(sched_id, {
"onSuccess": True,
"onFailure": True,
"destinations": [1, 2]
})
# Mirrors
client.backup_schedules.update_mirrors(sched_id, {
"enabled": True,
"repositories": [rid2]
})
compat = client.backup_schedules.get_mirror_compatibility(sched_id)
# Reorder
client.backup_schedules.reorder({"scheduleIds": ["id-c", "id-a", "id-b"]})
Notifications
# List all destinations
destinations = client.notifications.list_destinations()
# Create a Telegram destination
# Note: the destination type lives inside the config dict
dest = client.notifications.create_destination({
"name": "Telegram Alerts",
"config": {
"type": "telegram",
"botToken": "123456:ABC-DEF",
"chatId": "-1001234567890"
}
})
did = dest['id']
# Create an email destination
client.notifications.create_destination({
"name": "Admin Email",
"config": {
"type": "email",
"from": "backup@example.com",
"to": ["admin@example.com"],
"smtpHost": "smtp.gmail.com",
"smtpPort": 587,
"useTLS": True
}
})
# Get, update, delete
detail = client.notifications.get_destination(did)
updated = client.notifications.update_destination(did, {"name": "Renamed"})
client.notifications.delete_destination(did)
# Send a test message
client.notifications.test_destination(did)
System
# Server capabilities
info = client.system.get_info()
print(info['capabilities']) # {"rclone": bool, "sysAdmin": bool}
# Retrieve the restic repository password (requires account password for verification)
result = client.system.download_restic_password("your-account-password")
Error Handling
from py_zerobyte import (
ZerobyteClient,
ZerobyteError,
AuthenticationError,
APIError,
NotFoundError,
ValidationError,
)
try:
client = ZerobyteClient(url="http://localhost:4096",
username="admin", password="wrong")
except AuthenticationError as e:
print(f"Login failed: {e}")
try:
vol = client.volumes.get("non-existent-id")
except NotFoundError as e:
print(f"Not found (HTTP {e.status_code}): {e}")
try:
client.volumes.create({}) # missing required fields
except ValidationError as e:
print(f"Validation error: {e}")
try:
client.volumes.list()
except APIError as e:
print(f"API error (HTTP {e.status_code}): {e}")
except ZerobyteError as e:
print(f"SDK error: {e}")
Development
# Install with dev extras
pip install -e ".[dev]"
# Run tests
pytest
# Format
black py_zerobyte/
# Lint
flake8 py_zerobyte/
License
MIT — see LICENSE
Links
Changelog
1.2.1
- Migrated auth to
better-authendpoints - Volumes now use
shortId(string) as identifier in all path parameters - Repositories
update()uses PATCH; addedlist_rclone_remotes() - Backup schedules restructured to flat
/api/v1/backupsAPI - Notifications path updated;
update_destination()uses PATCH system.download_restic_password()now requires account password
1.0.0
- Initial release
Metadata
Release files for py-zerobyte 1.3.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 | |
|---|---|---|---|
| py_zerobyte-1.3.0.tar.gz | 15.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| py_zerobyte-1.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 32.9 kB
Release files / py_zerobyte-1.3.0.tar.gz
| Download URL | py_zerobyte-1.3.0.tar.gz |
|---|---|
| Size | 15.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
bb1f8aaafe319bb2a778f81ccba108a55c35b73aedd9c97f6d0e4311d95ab080
|
|
BLAKE2b-256 checksum How to use checksums |
a643180d6a9b54661346a35986747c2888361143dd81685d9ec80f4a85236415
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.9.25
|
Release files / py_zerobyte-1.3.0-py3-none-any.whl
| Download URL | py_zerobyte-1.3.0-py3-none-any.whl |
|---|---|
| Size | 16.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5bec0c6c5caa7a0a2c69637f8c9e625b868c7bba0330014cb3697a24516a042f
|
|
BLAKE2b-256 checksum How to use checksums |
9ce7d40dd104bcb23bef17822ad036b78d304c2c20d2eedf844a4670ddd4fabe
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.9.25
|