Metadata-Version: 2.4
Name: brsx-archive
Version: 0.1.0
Summary: Python client and CLI for BRSX Archive file storage
Author-email: BRSX Labs <support@brsxlabs.com>
License: MIT
Project-URL: Homepage, https://archive.brsxlabs.com
Project-URL: Documentation, https://help.brsxlabs.com
Keywords: brsx,archive,storage,upload,backup
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Topic :: System :: Archiving :: Backup
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# brsx-archive

Python client and command-line tool for [BRSX Archive](https://archive.brsxlabs.com) file storage.
No dependencies beyond the standard library.

```bash
pip install brsx-archive
```

## Get an API key

Sign in to [archive.brsxlabs.com](https://archive.brsxlabs.com), click your name at the top right,
open **API keys** and create one. The key starts with `brsxa_` and is shown only once.

```bash
export BRSX_ARCHIVE_KEY=brsxa_...
```

Files you upload go to your own account and count against your storage quota.

## Python

```python
from brsx_archive import Archive

archive = Archive()                      # reads BRSX_ARCHIVE_KEY
backups = archive.folder("backups")      # created if it doesn't exist

f = archive.upload("db.sqlite", folder=backups, overwrite=True)
print(f.id, f.size)

for item in archive.files(backups):
    print(item.name, item.size)

archive.download(f, "restored.sqlite")
archive.delete(f)

usage = archive.usage()
print(usage.used, usage.limit, usage.free)
```

Large files are uploaded in chunks (up to 2 GB per file); failed chunks are retried automatically.

### Keeping only the latest backups

```python
from datetime import date

name = f"db-{date.today()}.sqlite"
archive.upload("db.sqlite", folder=backups, name=name)
archive.keep_latest(backups, count=7, prefix="db-")   # delete older ones
```

### Errors

| Exception | When |
|---|---|
| `AuthError` | Missing, invalid or revoked API key |
| `ConflictError` | A file with the same name exists (use `overwrite=True`) |
| `QuotaError` | Storage quota exceeded or file too large |
| `ArchiveError` | Any other API error (base class) |

## Command line

```bash
brsx-archive usage
brsx-archive ls --folder backups
brsx-archive upload db.sqlite --folder backups --overwrite
brsx-archive upload db-2026-09-21.sqlite --folder backups --keep 7
brsx-archive download 42 -o restored.sqlite
brsx-archive rm 42
```

A daily backup with cron:

```cron
0 3 * * * BRSX_ARCHIVE_KEY=brsxa_... brsx-archive upload /var/backups/db-$(date +\%F).sqlite --folder backups --keep 7 --quiet
```

## HTTP API

All endpoints take `Authorization: Bearer brsxa_...`.

| Method | Path | |
|---|---|---|
| GET | `/api/v1/me` | account usage and limits |
| GET | `/api/v1/folders` | list folders |
| POST | `/api/v1/folders` | create folder `{name, parent_id?}` (returns existing if present) |
| GET | `/api/v1/files?folder_id=` | list files (omit for root) |
| POST | `/api/v1/uploads` | start upload → `{upload_id, chunk_size}` |
| PUT | `/api/v1/uploads/{id}/{index}` | send chunk as raw body, index from 0 |
| POST | `/api/v1/uploads/{id}/complete` | finish `{name, folder_id?, overwrite?}` |
| GET | `/api/v1/files/{id}/download` | download |
| DELETE | `/api/v1/files/{id}` | delete |

## License

MIT
