tungsten-backups
Back up your database from your Tungsten panel and download it as a zip. Press Back up now, wait a moment, press Download. Like Spatie Backup for Filament, made for Tungsten.
Backups hold all your data, so they are kept in a private folder on the server and only signed-in admins can download them. There is never a public link.
What it does
- Back up now: the database alone, or the database and uploaded files (images, documents).
- Works with your database: SQLite (an exact copy, safe while the app keeps writing), PostgreSQL (
pg_dump), MySQL / MariaDB (mysqldump). No dump tool installed, or another database? Every table is saved as JSON instead. - Runs in the background: the page doesn't wait; the list updates itself when the backup is ready.
- Download, Check, Delete: Check reads the whole zip back and compares every part with its SHA-256.
- Keeps the last 10 (you choose), deletes older ones, and never deletes the newest good one.
- Automatic backups every few hours while your app runs, or from cron with
python -m tungsten_backups. - Safe on failure: a backup that fails (disk full, database down) leaves no half file, shows the error on its row and in the bell.
- Checks disk space first, and only one backup runs at a time, even with many workers.
- Dashboard card: when the last backup was made, how many you keep, free disk space.
- Works with other plugins: with
tungsten-security-auditthe audit gets a "Recent backup" check. Other plugins can add their folders to full backups.
Install
pip install tungsten-backups
from tungsten_backups import BackupsPlugin
panel.plugin(BackupsPlugin(folder="storage/backups"))
panel.create_tables(engine)
panel.mount(app)
This adds Backups under Settings and a card on the dashboard. It needs tungsten-admin 0.1.4 or newer.
Options
BackupsPlugin(
folder="storage/backups", # private folder for the zips (never inside a folder your web server serves)
keep=10, # good backups to keep (0 keeps all)
keep_days=0, # also delete backups older than this (0: never)
every_hours=None, # e.g. 24 for a daily backup while the app runs
schedule_kind="database", # or "full" for automatic backups
folders={}, # more folders for full backups: {"invoices": "data/invoices"}
include_storage=True, # save the panel's upload folder in full backups
use_tools=True, # use pg_dump / mysqldump when installed
timeout=3600, # seconds a dump tool may run
min_free_mb=100, # don't start when the disk would drop below this
max_age_days=7, # warn when the newest backup is older
allow=None, # fn(ctx) -> bool, an extra rule for who may use backups
dashboard_widget=True,
)
Who can use it
With roles on, users need the backups.manage permission to see the screen and Download backups (backups.download) to download. Super admins have both. Without roles every signed-in user is an admin, so use allow= to narrow it:
BackupsPlugin(allow=lambda ctx: ctx.user.email == "owner@example.com")
On a panel with no login, downloads are off (anyone reaching the panel could take your data). Turn them on with allow_without_login=True only on a panel that is already protected another way.
Every download and delete is written to the activity log when activity_log=True.
From the command line (cron)
python -m tungsten_backups myapp:panel # back up the database
python -m tungsten_backups myapp:panel --full # database and uploaded files
python -m tungsten_backups myapp:panel --list # list backups
python -m tungsten_backups myapp:panel --verify # check the newest backup
A daily cron line: 0 2 * * * cd /srv/app && .venv/bin/python -m tungsten_backups myapp:panel.
From your code
backups = panel.get_plugin("backups")
backup = backups.backup("full", note="Before the import") # waits and returns the row
@backups.on_backup
def copy_off_server(backup, plugin):
if backup.status == "done":
upload_to_s3(plugin.folder / backup.name)
Another plugin can add its own folder to full backups by having a backup_folders() method:
class MediaLibraryPlugin(Plugin):
id = "media-library"
def backup_folders(self):
return {"media": self.root}
What is in the zip
manifest.json what is inside, row counts, versions, and a SHA-256 for every part
database.sqlite SQLite copy (open it with any SQLite tool)
database.sql pg_dump / mysqldump output
tables/<name>.jsonl every row as JSON, one per line (when no dump tool was used)
files/storage/... uploaded files (full backups)
Restoring
Restoring is done outside the panel on purpose, so a wrong click can't wipe your data. Stop the app first, then:
- SQLite: unzip and put
database.sqlitein place of your database file. - PostgreSQL:
psql -d mydb -f database.sqlon an empty database. - MySQL:
mysql mydb < database.sql. - Files: copy
files/storage/back into your upload folder.
Docs
Full guide: https://tungsten.prisminfoways.com/docs/backups
Metadata
Release files for tungsten-backups 0.1.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 | |
|---|---|---|---|
| tungsten_backups-0.1.0.tar.gz | 30.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| tungsten_backups-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 57.2 kB
Release files / tungsten_backups-0.1.0.tar.gz
| Download URL | tungsten_backups-0.1.0.tar.gz |
|---|---|
| Size | 30.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
0628b95f6009070ff07a1bba6d843b7efb27a06ced65fea19ba96c583da14c7c
|
|
BLAKE2b-256 checksum How to use checksums |
b015e2e8ec9706c2e8d1d63e6976fbd2484d105cca8826c5d718dcc59d2cebc4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Release files / tungsten_backups-0.1.0-py3-none-any.whl
| Download URL | tungsten_backups-0.1.0-py3-none-any.whl |
|---|---|
| Size | 27.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0faf5df3085acc8a68f7375b2be7e24b0bb34cc51c8ce08c65829ec41d07faaf
|
|
BLAKE2b-256 checksum How to use checksums |
e10c0e7e12ddfe63aac127920c8d0edbbd2d40f42757088dfe011775644e5bc2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|