Why: Practice clean layering and pragmatic trade-offs while caching filesystem metadata and small file bytes into SQLite. Per-asset TTL. One process. Zero drama.
pip install -r requirements.txt
export SCAN_ALLOWLIST="/home/you"
export DEFAULT_TTL_SECONDS=86400
export MAX_BLOB_BYTES=$((32*1024*1024))
gunicorn -w 2 -b 0.0.0.0:8000 'app.app:create_app()'POST /refresh { path, ttl_seconds?, force? }— scan & upsert. Prunes missing under path.GET /files?dir=&ext=&q=&stale=(true|false)&page=&per_page=&sort=&order=— list.GET /files/:id/download— download stored bytes if present.
- Storing BLOBs in SQLite is deliberate for the drill; production usually separates concerns.
- Sorting uses a whitelist to avoid SQL injection in
ORDER BY. - HTTP-triggered scans are restricted by
SCAN_ALLOWLIST.
# Run tests
python -m pytest tests/unit/ -v
# Initialize database
python -m app.db_init
# Run development server
FLASK_APP=app.app:create_app flask run --port 8000