Self-hosted filament inventory for 3D printing. Track spools, purchases and shop prices — get notified when a filament hits your target price.
Quick Start · Features · Configuration · Price Monitoring · Troubleshooting
| Inventory | Filaments by manufacturer, material, color and diameter — including dual-color/co-extruded filaments. Spools track remaining weight, fill %, storage location and status. |
| Manufacturers | Dedicated manufacturer pages listing every product from that brand. |
| Purchase history | Price per spool, lot number, currency — spools are auto-created on purchase. |
| Price monitoring | Shop links with manual prices and automated scraping via ShopRules or built-in adapters. |
| Price alerts | Alert when price ≤ target (absolute or per kg) — Discord and SMTP notifications. |
| Spool labels | Printable QR-code labels per spool for physical tagging. |
| Backup & restore | Full JSON export/import — additive, safe to re-run. |
| Dashboard | Overview, low-stock list, material/color breakdown, active alerts, scheduler status. |
| User management | Admin / Member / Viewer roles — Viewer is fully read-only. |
- Docker + Docker Compose
For local development: Python 3.12+
cp .env.example .envEdit .env — choose strong passwords:
SECRET_KEY= # generate: python -c "import secrets; print(secrets.token_hex(32))"
DB_PASSWORD=changeme
QUART_AUTH_COOKIE_SECURE=trueStart everything:
docker compose up --build -dMariaDB starts automatically, migrations run on container start. The app is exposed on APP_PORT (default 8080) — only that port is mapped to the host, MariaDB stays internal to the compose network.
Open http://your-host:8080/setup — only available when no users exist yet.
docker compose pull
docker compose up --build -dMigrations run automatically on restart.
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
playwright install --with-deps chromium
cp .env.example .env # fill in DB credentials
python migration.py upgrade head
python main.py # runs on http://localhost:8080Seed sample data:
python seed.py # manufacturers, products, purchases, links, rules (idempotent)
python seed.py --reset # wipe all tables (except users/settings) and re-seed
python seed_shops.py # ShopRules only, no inventory dataAll runtime settings are managed on the Settings page (/settings, admin only) — not via .env.
| Section | What you can configure |
|---|---|
| Scheduler | Enable automatic price checks, set interval in minutes |
| Fetch engine | playwright (default, JS-capable) or httpx (faster, no JS) |
| Discord | Webhook URL, enable/disable, test message |
| Email (SMTP) | Host, port, credentials, TLS, from/to address, test email |
| Spool code template | Pattern for auto-generated spool codes |
| Backup & Restore | Export full inventory as JSON, import additively (admin only) |
These shops work out of the box without any manual configuration:
| Shop | Method |
|---|---|
3djake.de |
CSS selector |
prusa3d.com |
JSON-LD |
anycubic.com |
Shopify JSON-LD |
eu.store.bambulab.com |
JSON-LD (cloudscraper) |
esun3dstore.com |
Shopify JSON-LD (cloudscraper) |
esun3dstoreeu.com |
Shopify JSON-LD (cloudscraper) |
elegoo.com |
Shopify og:price:amount |
To add a new adapter: subclass BaseAdapter in app/shop_adapters/, implement extract(html, url) -> AdapterResult, register in registry.py via _reg(YourAdapter()).
For any other shop: create a rule at /shop-rules with domain, CSS price selector, and optional regex — or use the visual point-and-click picker to build one without touching CSS. German (1.299,00 €) and English (1,299.00) price formats are detected automatically.
- Amazon / eBay not supported — Amazon requires an authenticated session or the Product Advertising API; eBay blocks scraping via Cloudflare
- Heavy WAFs (Cloudflare Enterprise) block even cloudscraper — a proxy or official API is needed
- No printer / slicer integration — no Klipper, OrcaSlicer or print job tracking; inventory only
- No mobile app — web only, but responsive layout
App won't start — Database not initialized
Check DB credentials in .env. MariaDB must be reachable and the database must exist.
Migrations fail — Table already exists
Run python migration.py stamp head to mark the current state, then migrate.
Playwright checks time out
Increase playwright.timeout_ms in Settings (default: 30 000 ms).
Price not found
The shop's HTML structure changed. Use the Test button on /shop-rules and update the selector/regex.
Setup page unavailable
/setup is locked once a user exists. Add users via /users (admin only).
Pre-built images are published to Docker Hub on every push to master and on version tags:
docker pull sytxlabs/spoolbeacon:latestMIT — see the LICENSE file for details.