django-dbbackup icon indicating copy to clipboard operation
django-dbbackup copied to clipboard

dropbox docs missing required settings

Open bukowa opened this issue 3 years ago • 1 comments

Describe the bug

Dropbox docs are missleading.

To Reproduce

  1. Go to: https://django-dbbackup.readthedocs.io/en/master/storage.html#dropbox
  2. Read docs.
  3. Install pip install dropbox django-storages.
  4. Set oauth2_access_token:
DBBACKUP_STORAGE = 'storages.backends.dropbox.DropBoxStorage'
DBBACKUP_STORAGE_OPTIONS = {
    'oauth2_access_token': DROPBOX_ACCESS_TOKEN,
}
  1. Receive
dropbox.dropbox_client.BadInputException: OAuth2 access token or refresh token or app key/secret must be set
  1. Read source code https://github.com/jschneier/django-storages/blob/7914409c90f04a749e517bb39635b218d908265f/storages/backends/dropbox.py#L86

  2. Set:

DBBACKUP_STORAGE = 'storages.backends.dropbox.DropBoxStorage'
DBBACKUP_STORAGE_OPTIONS = {
    'oauth2_access_token': DROPBOX_ACCESS_TOKEN,
    'app_key': '...',
    'app_secret': '...',
}
  1. Everything works.

bukowa avatar Apr 19 '23 16:04 bukowa

"Dropbox has recently introduced short-lived access tokens only, and does not seem to allow new apps to generate access tokens that do not expire." [https://django-storages.readthedocs.io/en/latest/backends/dropbox.html]

django-dbbackup does not use correct settings for Dropbox.

OmarLajam avatar Mar 30 '24 00:03 OmarLajam

Indeed this still seems to be not fixed in docs. I confirm it worked for me with added app_key and app_secret

pawisoon avatar Feb 21 '25 01:02 pawisoon

I used this script

import os
import sqlite3
import sys
import tarfile


def database_backup(from_path, to_path):
    """
    Backup database from one path to another.
    """

    def progress(status, remaining, total):
        print(f"Copied {total - remaining} of {total} pages...")

    src = sqlite3.connect(from_path)
    dst = sqlite3.connect(to_path)
    with dst:
        src.backup(dst, pages=1, progress=None)
    dst.close()
    src.close()

    print(f"Database backup from {from_path} to {to_path} completed.")


def media_backup(from_path, to_path):
    """
    Backup media from one path to another.
    """
    tar = tarfile.open(to_path, "w:gz")
    tar.add(from_path)
    tar.close()
    print(f"Media backup from {from_path} to {to_path} completed.")


if __name__ == "__main__":
    print(f"Running backup.py with args: {sys.argv} from dir: {os.getcwd()}")

    cmd = sys.argv[1]
    match cmd:
        case "database":
            database_backup(sys.argv[2], sys.argv[3])
        case "media":
            media_backup(sys.argv[2], sys.argv[3])
#!/bin/bash
set -e

get_db_path() {
  ./manage.py shell -c 'from django.conf import settings; print(settings.DATABASES["default"]["NAME"])'
}

get_media_path() {
  ./manage.py shell -c 'from django.conf import settings; print(settings.MEDIA_ROOT)'
}

backup() {
  backup_dir="$(pwd)/data/backups"
  database_path=$(get_db_path)
  media_dir=$(get_media_path)

  database_backup_path="${backup_dir}/$GIT_BUILD_ID-$(date +%Y-%m-%d-%H-%M-%S)-db.sqlite3"
  echo "Database exists, backing up from ${database_path} to ${database_backup_path}"
  python ./backup.py database "${database_path}" "${database_backup_path}"

  media_backup_path="${backup_dir}/$GIT_BUILD_ID-$(date +%Y-%m-%d-%H-%M-%S)-media.tar.gz"
  echo "Backing up media from ${media_dir} to ${media_backup_path}"
  python ./backup.py media "${media_dir}" "${media_backup_path}"

}

if [ "$1" == "backup" ]; then
  backup
  exit 0
fi

# check if database exists
if [ -f $database_path ]; then
  backup
fi

python manage.py collectstatic --no-input --clear
python manage.py migrate
exec gunicorn -c python:conf.gunicorn

bukowa avatar Feb 21 '25 02:02 bukowa

Is there any way the django-dbbackup could handle this and refreshing the tokens? They had similar issue in django-storages https://github.com/jschneier/django-storages/pull/1159

pawisoon avatar Mar 03 '25 15:03 pawisoon