Skip to main content
Version: 10.0

Create and Download an rWeb Backup File

This example script creates a config only backup file and downloads it to the script's directory.

#!/usr/bin/env -S uv run --script
# /// script
# requires-python = ">=3.12"
# dependencies = [
# "requests",
# ]
# ///
"""Create a full or configuration backup of rWeb, optionally downloading it locally."""

import json
import requests
import urllib.parse
import time


class rweb_base:
HEADERS = {'Content-Type':'application/json',
'Accept': 'application/json'}

def __init__(self, url, user=None, password=None):
self.base_url = url
self.user = user
self.password = password
self.credentials = {'login': self.user, 'password': self.password}

def wrap(self,data):
"""Convert an object to an rWeb suitable json string
Wraps the data in the standard rweb {'data': } object """
return json.dumps({'data': data})

def url(self, resource, params=None):
"""Turn a resource into a url.
Uses base_url and optionally encodes a hash of parameters"""
querystring = ""
if params != None:
querystring = "?"+urllib.parse.urlencode(params)
return self.base_url + resource + querystring

def logout(self, session):
"""Close a session"""
session.delete(self.url('/authentication'))

def login(self):
"""Creates a login and returns the session """
with requests.session() as session:
session.headers = rweb_base.HEADERS
# This is insecure but may be needed if you haven't set up an SSL certificate for rWeb yet
session.verify = False
result = session.post(self.url('/authentication'),
self.wrap(self.credentials),
allow_redirects=False)
try:
assert(result.status_code == requests.codes.created)
except:
if result.status_code == 301:
self.base_url = self.base_url.replace('http:', 'https:')
session = self.login()
else:
print(result)
print(result.content)
raise RuntimeError("Failed to login to rWeb")
return session


class rweb(rweb_base):

def __init__(self, url, login, password):
"""Constructor method, gets login information and login session is created and saved"""
rweb_base.__init__(self, url, login, password)
self.session = rweb_base.login(self)

def rweb_backup(self, backup_type='full'):
"""Perform an rweb backup
Options for backup_type- "full" or "config"
"""

# Check if rWeb is running a backup already
backup = self.session.get(self.url("/backup"))
if backup.status_code == 200 :
raise RuntimeError("rWeb is performing a backup")
elif backup.status_code == 400 :
raise RuntimeError("rWeb is unable to perform a backup, running another command. Try again later")

# Perform the backup and wait for it to complete.
elif backup.status_code == 204:
backup_start = self.session.post(self.url('/backup'), self.wrap({'backup_type': backup_type}))
if backup_start.status_code == 202:
# Check if backup has completed sucessfully
backup = self.session.get(self.url("/backup"))
while backup.status_code == 200 :
print("Waiting for backup to finish...")
time.sleep(30)
backup = self.session.get(self.url("/backup"))
if backup.status_code != 204:
raise RuntimeError("Something went wrong-\n%s\n%s"%(backup,backup.content))
print("Backup generated.")
else :
raise RuntimeError("Something went wrong-\n%s\n%s"%(backup,backup.content))

def download_backup(self):
"""Downloads any existing backup into the current script directory."""
file_info = self.session.get(self.url('/backup/file_info'))
file_info = json.loads(file_info.content)
timestamp = file_info[0]['config']['subkeys']['file_timestamp'].replace(':','_').replace(' ','_').replace('/','_')
file_name = f"rweb_backup_{timestamp}.tgz"
# Temporarily change headers to download backup file
self.headers = {'Content-Type': 'application/octet-stream',
'Accept': 'application/json'}
backup_file = self.session.get(self.url('/backup/backup_file'), stream=True)
with open(file_name, 'wb') as f:
for chunk in backup_file.iter_content(chunk_size=1024):
if chunk:
f.write(chunk)
print(f"Backup saved as {file_name}")
# Change headers back
self.headers = {'Content-Type': 'application/json',
'Accept': 'application/json'}
return

def main():
# Enter your rWeb and user credentials here
my_rweb = rweb('https://rweb.local.com', 'admin', 'admin123')
my_rweb.rweb_backup('config')
my_rweb.download_backup()
return

if __name__ == '__main__':
main()