Backup your snapshots to Dropbox

I have created a small hassio addon for uploading snapshots to Dropbox.

After having problems with hassio-dropbox-sync (which otherwise I hear works for many people and seem great), I created a pure Python version to solve my problems. However, I wanted to share it and see if it would be useful for anyone else.

You can find the code here: https://github.com/d0ugal/hassio-dropbox-upload

Add the above address in Hassio addon repos. and install. Then configuration is very simple…

{
  "access_token": "DROPBOX TOKEN",
  "dropbox_dir": "/snapshots",
  "keep": 10,  # keeps the 10 most recent snapshots
  "mins_between_backups": 60  # Checks for new snapshots every hour
}

Contributions, feedback and ideas are very welcome! I have been using it for a couple of months now and it has gotten to a point of being fairly stable.

14 Likes

I really like this add-on! I’ve been looking to move my Dropbox add-on to Python for awhile, but haven’t had the time. I’m working on a more full-featured snapshot manager and may borrow some of this if you don’t mind.

1 Like

Sure thing. I have had similar plans/ideas, we could team up. https://github.com/d0ugal/hassio-dropbox-upload/issues/6

Hi !

First of all, thanks for making this addon ! It seems I’ve pretty much configured everything, but the same error appears again an again:

2018-11-19 19:20:27,320 - INFO - Created: 2018-11-19T18:13:08.457844+00:00
2018-11-19 19:20:27,750 - INFO - No existing snapshot in dropox with this name
Caught exception when calling dropbox_upload.dropbox.upload_file

Followed by a bunch of stuff:

Traceback (most recent call last):
File “/usr/lib/python3.6/site-packages/retrace.py”, line 289, in call
result = fn(*args, **kwargs)
File “/app/dropbox_upload/dropbox.py”, line 18, in upload_file
return dbx.files_upload(f, dest_path)
File “/usr/lib/python3.6/site-packages/dropbox/base.py”, line 2207, in files_upload
f,
File “/usr/lib/python3.6/site-packages/dropbox/dropbox.py”, line 274, in request
timeout=timeout)
File “/usr/lib/python3.6/site-packages/dropbox/dropbox.py”, line 365, in request_json_string_with_retry
timeout=timeout)
File “/usr/lib/python3.6/site-packages/dropbox/dropbox.py”, line 409, in request_json_string
type(request_binary))

Usually, I get around by reading the logs and figuring everything by myself, but I’m a bit stuck here :confused:.

App is created and I can access its folder, I chose the “App folder” type.

Would you have any idea about what causes the issue, and how to solve it ?

1 Like

Does it looks like this error? You may have DNS problems… If so, my comment might be a solution.

Hi @d0ugal and thanks for your answer.

To me, the issue I’m facing doesn’t look like the one you mentionned. When I look at the log, it seems to be related to files_upload whereas in your example, the connection to dropbox is not even initiated (it seems).

Here’s what happens before it breaks down:

2018-11-20 09:26:07,063 - INFO - Starting Snapshot backup
2018-11-20 09:26:07,184 - INFO - Found 2 snapshots
2018-11-20 09:26:07,185 - INFO - Backing up to Dropbox directory: [My app directory]
2018-11-20 09:26:07,186 - INFO - Snapshot: (1/2)
2018-11-20 09:26:07,189 - WARNING - Snapshot ‘’ is not password protected. Always try to use passwords, particulary when uploading all your data to a snapshot to a third party.
2018-11-20 09:26:07,191 - INFO - Size: 910 KB
2018-11-20 09:26:07,192 - INFO - Created: 2018-11-19T18:24:06.500222+00:00
2018-11-20 09:26:07,515 - INFO - No existing snapshot in dropox with this name

Question about dropbox_dir: My app is stored in the folder Applications, located at the root of my dropbox folder. Do I have to enter the full path, i.e /Applications/MyAppName, or only /MyAppName ? I’m not so sure about that.

I tried both but the issue remains the same, so it might not be related but I’d rather make sure about that.

Thanks for any help you can provide !

Cheers

Try just “/” for the dropbox_dir. Toy don’t need to include /Applications/Appname/. I also use an app directory dropbox app. Here is my full config, with only my token removed

{
“access_token”: “TOKEN”,
“dropbox_dir”: “/”,
“keep”: 10,
“mins_between_backups”: 60,
“filename”: “snapshot_name”,
“debug”: false
}

Hi @d0ugal,

Thanks for the suggestion. I used the same settings as you did, and even change my app type from folder to full access. Well it did not solve the issue :confused:, and the error log is the same as before.

From what I understand, dropbox connection is established but for some reason, it can’t upload anything. I use hassio on a pi that doesn’t run duckdns or anything of the sort … I really can’t figure what’s happening here.

2018-11-21 10:32:47,020 - INFO - Starting Snapshot backup
2018-11-21 10:32:47,145 - INFO - Found 2 snapshots
2018-11-21 10:32:47,147 - INFO - Backing up to Dropbox directory: /
2018-11-21 10:32:47,148 - INFO - Snapshot: (1/2)
2018-11-21 10:32:47,154 - WARNING - Snapshot ‘’ is not password protected. Always try to use passwords, particulary when uploading all your data to a snapshot to a third party.
2018-11-21 10:32:47,157 - INFO - Size: 910 KB
2018-11-21 10:32:47,158 - INFO - Created: 2018-11-19T18:24:06.500222+00:00
2018-11-21 10:32:47,483 - INFO - No existing snapshot in dropox with this name
Caught exception when calling dropbox_upload.dropbox.upload_file
Traceback (most recent call last):
File “/usr/lib/python3.6/site-packages/retrace.py”, line 289, in call
result = fn(*args, **kwargs)
File “/app/dropbox_upload/dropbox.py”, line 18, in upload_file
return dbx.files_upload(f, dest_path)
File “/usr/lib/python3.6/site-packages/dropbox/base.py”, line 2207, in files_upload
f,
File “/usr/lib/python3.6/site-packages/dropbox/dropbox.py”, line 274, in request
timeout=timeout)
File “/usr/lib/python3.6/site-packages/dropbox/dropbox.py”, line 365, in request_json_string_with_retry
timeout=timeout)
File “/usr/lib/python3.6/site-packages/dropbox/dropbox.py”, line 409, in request_json_string
type(request_binary))
TypeError: expected request_binary as binary type, got <class ‘_io.BufferedReader’>
Caught exception when calling dropbox_upload.dropbox.upload_file
Traceback (most recent call last):
File “/usr/lib/python3.6/site-packages/retrace.py”, line 289, in call
result = fn(*args, **kwargs)
File “/app/dropbox_upload/dropbox.py”, line 18, in upload_file
return dbx.files_upload(f, dest_path)
File “/usr/lib/python3.6/site-packages/dropbox/base.py”, line 2207, in files_upload
f,
File “/usr/lib/python3.6/site-packages/dropbox/dropbox.py”, line 274, in request
timeout=timeout)
File “/usr/lib/python3.6/site-packages/dropbox/dropbox.py”, line 365, in request_json_string_with_retry
timeout=timeout)
File “/usr/lib/python3.6/site-packages/dropbox/dropbox.py”, line 409, in request_json_string
type(request_binary))
TypeError: expected request_binary as binary type, got <class ‘_io.BufferedReader’>
2018-11-21 10:32:47,525 - ERROR - Unhandled error
Traceback (most recent call last):
File “/app/dropbox_upload/main.py”, line 35, in main
stats = backup.backup(dbx, cfg, snapshots)
File “/app/dropbox_upload/backup.py”, line 50, in backup
stats = process_snapshot(config, dbx, snapshot)
File “/app/dropbox_upload/backup.py”, line 86, in process_snapshot
dropbox.upload_file(dbx, path, target)
File “/usr/lib/python3.6/site-packages/retrace.py”, line 203, in wrapped_f
Caught exception when calling dropbox_upload.dropbox.upload_file
return Retry(*dargs, **dkwargs)(f, *args, **kw)
Traceback (most recent call last):
File “/usr/lib/python3.6/site-packages/retrace.py”, line 301, in call
self._limit.attempt(self.attempts)
File “/usr/lib/python3.6/site-packages/retrace.py”, line 289, in call
result = fn(*args, **kwargs)
File “/usr/lib/python3.6/site-packages/retrace.py”, line 142, in attempt
raise LimitReached()
File “/app/dropbox_upload/dropbox.py”, line 18, in upload_file
retrace.LimitReached
return dbx.files_upload(f, dest_path)
2018-11-21 10:32:47,531 - INFO - Sleeping for 60 minutes
File “/usr/lib/python3.6/site-packages/dropbox/base.py”, line 2207, in files_upload
f,
File “/usr/lib/python3.6/site-packages/dropbox/dropbox.py”, line 274, in request
timeout=timeout)
File “/usr/lib/python3.6/site-packages/dropbox/dropbox.py”, line 365, in request_json_string_with_retry
timeout=timeout)
File “/usr/lib/python3.6/site-packages/dropbox/dropbox.py”, line 409, in request_json_string
type(request_binary))
TypeError: expected request_binary as binary type, got <class ‘_io.BufferedReader’>
Caught exception when calling dropbox_upload.dropbox.upload_file
Traceback (most recent call last):
File “/usr/lib/python3.6/site-packages/retrace.py”, line 289, in call
result = fn(*args, **kwargs)
File “/app/dropbox_upload/dropbox.py”, line 18, in upload_file
return dbx.files_upload(f, dest_path)
File “/usr/lib/python3.6/site-packages/dropbox/base.py”, line 2207, in files_upload
f,
File “/usr/lib/python3.6/site-packages/dropbox/dropbox.py”, line 274, in request
timeout=timeout)
File “/usr/lib/python3.6/site-packages/dropbox/dropbox.py”, line 365, in request_json_string_with_retry
timeout=timeout)
File “/usr/lib/python3.6/site-packages/dropbox/dropbox.py”, line 409, in request_json_string
type(request_binary))
TypeError: expected request_binary as binary type, got <class ‘_io.BufferedReader’>

Two important lines in the log…

and

Does your snapshot have no name? i.e. a blank name? I would expect the name to be included in both of those lines and suspect that might be the issue!

If you change the filename config option to “snapshot_slug” then it might work.

Otherwise, I think you have found a new bug. Can you open a github issue copying the logs from above and I’ll dig into it and see if I can figure it out? Issues · d0ugal/hassio-dropbox-upload · GitHub

In my backup folder, I have those two files:
image

Each have a name, so I don’t know why it doesn’t appear in the log. As for the password, I did not take the warning into consideration until you mentionned it. I’ll see what I can do to fix that.

Anyway, I’ll open a github issue as you requested, thanks for your help :slight_smile: !

Hi @d0ugal thanks for this plugin! Just to clarify, if “mins_between_backups”: 60, is set, it checks automatically every hour, I don’t need an automation to trigger it, do I?

I do have the strange issue that out of 8 snapshots, only 4 were synched to dropbox and I have no idea why…

Maybe this excerpt of the error log helps:

2018-11-29 10:21:52,077 - INFO - 99 %
2018-11-29 10:21:54,055 - INFO - 100 %
2018-11-29 10:21:54,057 - INFO - Snapshot: (8/8)
2018-11-29 10:21:54,062 - WARNING - Snapshot ‘’ is not password protected. Always try to use passwords, particulary when uploading all your data to a snapshot to a third party.
2018-11-29 10:21:54,064 - INFO - Size: 112.18 MB
2018-11-29 10:21:54,066 - INFO - Created: 2018-11-22T02:00:00.045340+00:00
2018-11-29 10:22:07,023 - WARNING - The snapshot conflicts with a file name in dropbox, the contents are different. The dropbox file will be deleted and replaced. Local hash: febfb30a4463920540b382e722c07b6e6952f30c3d67e3e01e35188e4892fe3d, Dropbox hash: 9218115203adb5db973b63ec14ac83bc79dd1a09a7d900b70bb9405ce4be23b2

Same here:
“No existing snapshot in dropox with this name”

2018-11-29 14:46:57,889 - INFO - Found 2 snapshots
2018-11-29 14:46:57,890 - INFO - Backing up to Dropbox directory: /
2018-11-29 14:46:57,890 - INFO - Snapshot: Automated Backup 2018-11-29 (1/2)
2018-11-29 14:46:57,893 - DEBUG - Slug: e6013c0c
2018-11-29 14:46:57,894 - INFO - Size: 3.62 MB
2018-11-29 14:46:57,894 - INFO - Created: 2018-11-29T01:00:00.196876+00:00
2018-11-29 14:46:57,895 - DEBUG - Uploading to: /e6013c0c.tar
2018-11-29 14:46:58,208 - INFO - No existing snapshot in dropox with this name
Caught exception when calling dropbox_upload.dropbox.upload_file
Traceback (most recent call last):
File “/usr/lib/python3.6/site-packages/retrace.py”, line 289, in call
result = fn(*args, **kwargs)
File “/app/dropbox_upload/dropbox.py”, line 18, in upload_file
return dbx.files_upload(f, dest_path)
File “/usr/lib/python3.6/site-packages/dropbox/base.py”, line 2207, in files_upload
f,
File “/usr/lib/python3.6/site-packages/dropbox/dropbox.py”, line 274, in request
timeout=timeout)
File “/usr/lib/python3.6/site-packages/dropbox/dropbox.py”, line 365, in request_json_string_with_retry
timeout=timeout)
File “/usr/lib/python3.6/site-packages/dropbox/dropbox.py”, line 409, in request_json_string
type(request_binary))
TypeError: expected request_binary as binary type, got <class ‘_io.BufferedReader’>
Caught exception when calling dropbox_upload.dropbox.upload_file
Traceback (most recent call last):
File “/usr/lib/python3.6/site-packages/retrace.py”, line 289, in call
result = fn(*args, **kwargs)
File “/app/dropbox_upload/dropbox.py”, line 18, in upload_file
return dbx.files_upload(f, dest_path)
File “/usr/lib/python3.6/site-packages/dropbox/base.py”, line 2207, in files_upload
f,
File “/usr/lib/python3.6/site-packages/dropbox/dropbox.py”, line 274, in request
timeout=timeout)
File “/usr/lib/python3.6/site-packages/dropbox/dropbox.py”, line 365, in request_json_string_with_retry
timeout=timeout)
File “/usr/lib/python3.6/site-packages/dropbox/dropbox.py”, line 409, in request_json_string
type(request_binary))
TypeError: expected request_binary as binary type, got <class ‘_io.BufferedReader’>
Caught exception when calling dropbox_upload.dropbox.upload_file
Traceback (most recent call last):
File “/usr/lib/python3.6/site-packages/retrace.py”, line 289, in call
result = fn(*args, **kwargs)
File “/app/dropbox_upload/dropbox.py”, line 18, in upload_file
return dbx.files_upload(f, dest_path)
File “/usr/lib/python3.6/site-packages/dropbox/base.py”, line 2207, in files_upload
f,
File “/usr/lib/python3.6/site-packages/dropbox/dropbox.py”, line 274, in request
timeout=timeout)
File “/usr/lib/python3.6/site-packages/dropbox/dropbox.py”, line 365, in request_json_string_with_retry
timeout=timeout)
File “/usr/lib/python3.6/site-packages/dropbox/dropbox.py”, line 409, in request_json_string
type(request_binary))
TypeError: expected request_binary as binary type, got <class ‘_io.BufferedReader’>
Caught exception when calling dropbox_upload.dropbox.upload_file
Traceback (most recent call last):
File “/usr/lib/python3.6/site-packages/retrace.py”, line 289, in call
result = fn(*args, **kwargs)
File “/app/dropbox_upload/dropbox.py”, line 18, in upload_file
return dbx.files_upload(f, dest_path)
File “/usr/lib/python3.6/site-packages/dropbox/base.py”, line 2207, in files_upload
f,
File “/usr/lib/python3.6/site-packages/dropbox/dropbox.py”, line 274, in request
timeout=timeout)
File “/usr/lib/python3.6/site-packages/dropbox/dropbox.py”, line 365, in request_json_string_with_retry
timeout=timeout)
File “/usr/lib/python3.6/site-packages/dropbox/dropbox.py”, line 409, in request_json_string
type(request_binary))
TypeError: expected request_binary as binary type, got <class ‘_io.BufferedReader’>
2018-11-29 14:46:58,235 - ERROR - Unhandled error
Traceback (most recent call last):
File “/app/dropbox_upload/main.py”, line 35, in main
stats = backup.backup(dbx, cfg, snapshots)
File “/app/dropbox_upload/backup.py”, line 50, in backup
stats = process_snapshot(config, dbx, snapshot)
File “/app/dropbox_upload/backup.py”, line 86, in process_snapshot
dropbox.upload_file(dbx, path, target)
File “/usr/lib/python3.6/site-packages/retrace.py”, line 203, in wrapped_f
return Retry(*dargs, **dkwargs)(f, *args, **kw)
File “/usr/lib/python3.6/site-packages/retrace.py”, line 301, in call
self._limit.attempt(self.attempts)
File “/usr/lib/python3.6/site-packages/retrace.py”, line 142, in attempt
raise LimitReached()
retrace.LimitReached
2018-11-29 14:46:58,238 - INFO - Sleeping for 60 minutes

Hey there
I started using this xmas week and as (bad) luck would have it my rpi died, so this has been really useful to me.
However, when i extracted my back up from 29/12, the home assistant configuration folder is missing. My backup from 26/12 however includes it so i’ve restored from that point.
If i do a manual snapshot it includes it and runs without errors, if i trigger the automation on your git hub page i get the following error. Any ideas??
19-01-03 15:04:11 WARNING (SyncWorker_6) [hassio.snapshots.snapshot] Can't snapshot folder homeassistant: [Errno 2] No such file or directory: '/data/homeassistant/home-assistant_v2.db-shm'

Hello, i was thinking, if able to receive a notification when the file was created on the Dropbox. Maybe taking advantage of the access with the API. (see https://www.dropbox.com/developers-v1/core/docs#delta)
I currently use IFTTT, but it is always one more step that needs to be done.
Thanks.

Started using Dropbox Downloader about a week ago on two HA systems.

Uploading fails for .tar files made by HA script, manually made backups (from the HA-Snapshots page), upload fine.

However, some files only show on the Dropbox www ui, they do not sync to Dropbox clients. Also, pruning of files in excess of the keep limit fails. I have used Dropbox a lot during the last few years, never seen files on the www not sync to clients.

Can you open a github issue and include the logs from hassio? I’ve never seen a issue like this reported before.

@d0ugal False alarm: I had a “:” in the backup file name, fixed.

Cleared out files, will keep an eye on the issue re keep limit the next few days.

Is there a way to get the version of HA in the backup filename?

Thank you for your prompt reply !

No way to include the version in the file name that I know of. Why would you want this? I suspect you can get the version from the backup itself.

OK.
I did figure out the logic of the files kept logic: If you remove the files from HA, they are not counted in DropBox. Works for me.