ODK Central Backup Script

This is a simple script that can automate backing up of ODK central using the python

import requests
from requests.auth import HTTPBasicAuth
from pprint import pprint




# 🌟 User credentials
ODK_USERNAME = "something@something.com"
ODK_PASSWORD = "passwords"  # Replace with your actual password
ODK_DOMAIN = "odk.xyz.com"  # e.g., nationalttsurvey.aiims.edu
BACKUP_PASSPHRASE = "backup-password"

# 🌟 API endpoint
BASEURL = f"https://{ODK_DOMAIN}/v1/backup"

# 🌟 Auth
auth = HTTPBasicAuth(ODK_USERNAME, ODK_PASSWORD)

# 🌟 Backup request payload
payload = {
    "passphrase": BACKUP_PASSPHRASE
}

# 🌟 Send POST request
response = requests.post(BASEURL, auth=auth, headers={"Content-Type": "application/json"}, json=payload, stream=True)


# 🌟 Print headers in a gentlemanly fashion
print("\nšŸŽ© Response Headers:")
for key, value in response.headers.items():
    print(f"{key}: {value}")


# 🌟 Check for errors
if response.status_code == 200:
    # 🌟 Determine filename
    content_disposition = response.headers.get('Content-Disposition')
    if content_disposition and "filename=" in content_disposition:
       filename = content_disposition.split("filename=")[-1].strip('"')
       filename = filename.replace(':', '-').replace('/', '-').replace('\\', '-')
    else:
        filename = "backup.zip"

    # 🌟 Save file
    chunk_size = 10 * 1024 * 1024  # 10 MB
    total_bytes = 0

    with open(filename, "wb") as f:
        for chunk in response.iter_content(chunk_size=chunk_size):
            if chunk:
                f.write(chunk)
                total_bytes += len(chunk)
                print(f"šŸŽ© Received {total_bytes / (1024 * 1024):.2f} MB so far...")
    print(f"\nāœ… Backup saved as: {filename}")

else:
    print(f"\nāŒ Failed to download backup! Status code: {response.status_code}")
    print(response.text)

Tested and used 2 days back

I had to wait almost 10 minutes before data actually started downloading. I guess during that time, the backup was getting created on the server.

Bests
Vivek

2 Likes

I would appriciate about your effort. Have a look on https://pypi.org/project/centralpy/ , it;s more fater than your code. It's python package which is doing same thing with more secure way, feel free to use this it's open source.

Best,
@iamnarendrasingh

Thank You. The central.py package is interesting, but I do not think it can do the API based Direct Backup which the script i had shared intends to do.

A slighly improved version that displays downloaded size

import requests
from requests.auth import HTTPBasicAuth
from pprint import pprint




# 🌟 User credentials
ODK_USERNAME = "cccc@ccc.com"
ODK_PASSWORD = "cccccccccccc"  # Replace with your actual password
ODK_DOMAIN = "cccc.vvvv.zzzzzzz"  #  
BACKUP_PASSPHRASE = "backup-password"

# 🌟 API endpoint
BASEURL = f"https://{ODK_DOMAIN}/v1/backup"

# 🌟 Auth
auth = HTTPBasicAuth(ODK_USERNAME, ODK_PASSWORD)

# 🌟 Backup request payload
payload = {
    "passphrase": BACKUP_PASSPHRASE
}

# 🌟 Send POST request
response = requests.post(BASEURL, auth=auth, headers={"Content-Type": "application/json"}, json=payload, stream=True)


# 🌟 Print headers in a gentlemanly fashion
print("\nšŸŽ© Response Headers:")
for key, value in response.headers.items():
    print(f"{key}: {value}")


# 🌟 Check for errors
if response.status_code == 200:
    # 🌟 Determine filename
    content_disposition = response.headers.get('Content-Disposition')
    if content_disposition and "filename=" in content_disposition:
       filename = content_disposition.split("filename=")[-1].strip('"')
       filename = filename.replace(':', '-').replace('/', '-').replace('\\', '-')
    else:
        filename = "backup.zip"

    # 🌟 Save file
    chunk_size = 10 * 1024 * 1024  # 10 MB
    total_bytes = 0

    with open(filename, "wb") as f:
        for chunk in response.iter_content(chunk_size=chunk_size):
            if chunk:
                f.write(chunk)
                total_bytes += len(chunk)
                print(f"šŸŽ© Received {total_bytes / (1024 * 1024):.2f} MB so far...")
    print(f"\nāœ… Backup saved as: {filename}")

else:
    print(f"\nāŒ Failed to download backup! Status code: {response.status_code}")
    print(response.text)

2 Likes