Skip to main content

Standalone tool to build a local, self-serving archive of SevDesk documents (invoices, credit notes, vouchers).

Project description

SevDesk Archiver

PyPI version CI Python License

Standalone Python tool that builds a self-contained local archive of your SevDesk documents (invoices, credit notes, vouchers). Each document is stored as a PDF plus a JSON sidecar with the full SevDesk metadata, and the archive ships its own standalone HTML viewer — no database, no server required.

  • Idempotent — re-running only fetches what is missing or changed
  • Self-serving — the archive directory contains a static index.html viewer and a standalone serve.py (Python stdlib only)
  • Type-aware — invoices, credit notes, and vouchers with correct status/type labels (German)
  • Resilient — exponential backoff on rate limits and transient network errors
  • Integrity-checked — SHA-256 pdf_hash per document; verify cross-checks manifest, files, sidecars, and hashes
  • No DB — plain files on disk, easy to back up, inspect, or diff

Run it

No install needed — uvx fetches and runs the latest release in an ephemeral environment:

uvx sevdesk-archiver@latest --help

Or install persistently:

uv tool install sevdesk-archiver
sevdesk-archiver --help

Configure

Two things are needed for the archive command: a SevDesk API token and a target directory. Any of the following works:

1. Command-line arguments — highest precedence:

uvx sevdesk-archiver@latest archive \
  --api-token "$SEVDESK_API_TOKEN" \
  --target /path/to/archive

2. Environment variables — export once, run anywhere:

export SEVDESK_API_TOKEN=your_sevdesk_token
export ARCHIVE_TARGET=$HOME/Documents/sevdesk-archive
uvx sevdesk-archiver@latest archive

3. .env file in the working directory — auto-loaded on startup:

# .env
SEVDESK_API_TOKEN=your_sevdesk_token
ARCHIVE_TARGET=.
cd /path/to/archive && uvx sevdesk-archiver@latest archive

Get your SevDesk API token from https://my.sevdesk.de/admin/userManagement (Benutzer → API-Token).

One-line in-place refresh

Drop a .env (with ARCHIVE_TARGET=. and your token) into an archive directory, then refresh it with a single line from inside that directory:

cd /path/to/archive && uvx sevdesk-archiver@latest archive

Or as a cron / systemd-timer job:

cd /path/to/archive && uvx sevdesk-archiver@latest archive && uvx sevdesk-archiver@latest verify

Commands

# Build / refresh the archive (default range: 1st of previous month … today)
sevdesk-archiver archive

# Limit the date range
sevdesk-archiver archive --after 2026-01-01 --end 2026-03-31

# Include vouchers (incoming invoices)
sevdesk-archiver archive --vouchers

# See what would happen — no files written
sevdesk-archiver archive --dry-run

# Serve the archive over HTTP and open the browser (index.html needs http://)
sevdesk-archiver serve

# Deep integrity check: manifest ↔ files ↔ sidecars ↔ hashes
sevdesk-archiver verify

# Add SHA-256 pdf_hash to sidecars that lack it (existing archives)
sevdesk-archiver verify --backfill-hashes

--target <dir> overrides ARCHIVE_TARGET on any command.

Archive layout

$ARCHIVE_TARGET/
├── index.html          # viewer (loads manifest.json via fetch)
├── manifest.json       # summary of all entries
├── logo.png
├── serve.py            # standalone HTTP server (stdlib only)
├── serve-archive.sh    # wrapper: ./serve-archive.sh
└── files/
    ├── inv-20260115-RE-2026_0001-Mustermann_GmbH.pdf
    ├── inv-20260115-RE-2026_0001-Mustermann_GmbH.json
    └── …

The files/ subdirectory is the authoritative store. manifest.json is regenerated on every run and is safe to delete — it'll be rebuilt from the sidecars. The index.html / serve.py helpers are copies of the shipped templates; you can re-run sevdesk-archiver archive at any time to refresh them.

Each sidecar carries the full SevDesk document, archive metadata, and a SHA-256 pdf_hash ("sha256:<hex>") so verify can catch silent corruption.

Once archived, the folder is self-contained. You can copy it anywhere (USB stick, S3, attached storage) and open it with:

cd /path/to/archive
./serve-archive.sh            # or: python3 serve.py

No pip install, no sevdesk-archiver, no SevDesk API access required to browse — just Python 3's standard library.

Library use

from sevdesk_archiver import SevDeskClient, verify_archive
from sevdesk_archiver.archive import archive

client = SevDeskClient(api_token="...")
for event in archive(client, target_dir="/path/to/archive"):
    print(event["message"])

report = verify_archive("/path/to/archive")

Development

uv sync
uv run pytest
uv run ruff check src tests
uv run mypy src

See CLAUDE.md for the release process and project conventions, and CHANGELOG.md for version history.

License

Apache-2.0 — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sevdesk_archiver-0.1.1.tar.gz (95.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

sevdesk_archiver-0.1.1-py3-none-any.whl (97.5 kB view details)

Uploaded Python 3

File details

Details for the file sevdesk_archiver-0.1.1.tar.gz.

File metadata

  • Download URL: sevdesk_archiver-0.1.1.tar.gz
  • Upload date:
  • Size: 95.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for sevdesk_archiver-0.1.1.tar.gz
Algorithm Hash digest
SHA256 ce4f0ac5a642f70a548a5926ab3a1fa39100523cac5d82fc53609a5da9b4ec34
MD5 711253eab16804b51076e03eb00f32b2
BLAKE2b-256 b37178972422f0fc06b4dcb0c5d44b44afe6b086045caec2f7fae1ab65173fe5

See more details on using hashes here.

Provenance

The following attestation bundles were made for sevdesk_archiver-0.1.1.tar.gz:

Publisher: release.yaml on arjoma/sevdesk-archiver

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file sevdesk_archiver-0.1.1-py3-none-any.whl.

File metadata

File hashes

Hashes for sevdesk_archiver-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 63d48df5798db155098a11b3636c64495630959b30569b45725867704a9a2fb5
MD5 9e999134bc2d287fa1d7fa576d5bc885
BLAKE2b-256 b914a3b2af9cd893b18d65f355753151e8ebfb61a069ef30069c26fb26a1a5d4

See more details on using hashes here.

Provenance

The following attestation bundles were made for sevdesk_archiver-0.1.1-py3-none-any.whl:

Publisher: release.yaml on arjoma/sevdesk-archiver

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page