ff-iii-luciferin
ff-iii-luciferin is a Python enrichment engine for
Firefly III transactions.
It provides a clean, async-first API for post-processing financial data: descriptions, notes, tags, and categories — without polluting your domain logic.
✨ Key Features
- 🔌 Async client for Firefly III API (built on
httpx) - 📝 Update transaction descriptions and notes
- 🏷️ Add or manage tags
- 🗂️ Assign or change categories
- 🏦 Preserve simplified source/destination account references
- 🚫 Filter unwanted transactions (e.g. uncategorized, split-only)
- ⚠️ Explicit handling of API, network, and data errors
- 🧱 Generated OpenAPI client kept internal (not public API)
📦 Installation
From PyPI:
pip install ff-iii-luciferin
Python 3.12+ required.
⚙️ Configuration
The client requires access to your Firefly III instance and a personal access token.
Provide them via environment variables:
FIREFLY_URL=https://your-firefly-instance
FIREFLY_TOKEN=your_access_token
Using python-dotenv is optional but recommended for local development.
The URL is the instance root; the client adds /api/v1 to its requests.
The Firefly III E2E workflow starts a disposable Firefly III with SQLite,
creates a test user and personal access token, and runs
tests/test_firefly_e2e.py against its real HTTP API. The test creates its own
accounts, categories, and transactions. For a manual run, set
FIREFLY_E2E_URL to the root URL and FIREFLY_E2E_TOKEN to a token for an
isolated test instance, then run uv run pytest tests/test_firefly_e2e.py.
Without those variables, the test is skipped.
Local Firefly III demo
With Docker and Python 3 installed, run from the repository root:
bash scripts/demo/start.sh
set -a; source .firefly-demo/env; set +a
uv run python examples/min_usage_search.py
The script starts Firefly III on http://127.0.0.1:18080, creates an isolated
SQLite database and API token, and seeds categories, accounts, withdrawals, a
deposit, and a transfer. It leaves the container running. Rerunning the script
reuses its data without duplicating seed records. Your existing examples/.env
is not changed; shell variables from .firefly-demo/env take precedence.
New instances use fireflyiii/core:latest, so CI checks the current Firefly III
API. To reproduce a specific version, set for example
FIREFLY_DEMO_IMAGE=fireflyiii/core:version-6.7.4 when starting. Existing
containers keep their original image. To upgrade one while retaining its SQLite
database, run bash scripts/demo/stop.sh, then
docker rm ff-iii-luciferin-demo, then bash scripts/demo/start.sh.
Run bash scripts/demo/stop.sh to stop the container while keeping its data.
The local .firefly-demo/ directory contains the token and app key, so keep it
private. The examples that modify a transaction have hardcoded IDs: use an ID
shown by min_usage_search.py before running those examples.
🚀 Quick Start
Minimal async example:
import asyncio
import os
from ff_iii_luciferin.api import FireflyClient
async def main() -> None:
client = FireflyClient(
base_url=os.environ["FIREFLY_URL"],
token=os.environ["FIREFLY_TOKEN"],
)
try:
transactions = await client.fetch_transactions()
categories = await client.fetch_categories()
about = await client.get_about()
print(f"Firefly III: {about.version}")
await client.update_transaction_description(
transaction_id=123,
description="Updated description",
)
await client.update_transaction_notes(
transaction_id=123,
notes="Additional notes",
)
await client.add_tag_to_transaction(
transaction_id=123,
tag="processed",
)
await client.assign_transaction_category(
transaction_id=123,
new_category_id=1,
)
finally:
await client.close()
asyncio.run(main())
The examples/min_usage_search.py script shows the current transaction search
output with a rich table, including category and account columns.
📄 License
MIT License.
MIT License — see LICENSE for details.
Metadata
Release files for ff-iii-luciferin 1.2.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| ff_iii_luciferin-1.2.1.tar.gz | 99.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| ff_iii_luciferin-1.2.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 541.7 kB
Release files / ff_iii_luciferin-1.2.1.tar.gz
| Download URL | ff_iii_luciferin-1.2.1.tar.gz |
|---|---|
| Size | 99.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
bf521459a38f355b0369792ef28ad56475f1d29e8aa51fd264953ab670c594e1
|
|
BLAKE2b-256 checksum How to use checksums |
4216294ecb57b905c0751abb83e66e21bb8afdcca27657e11b0802c6b983c0a1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.19 {"installer":{"name":"uv","version":"0.12.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / ff_iii_luciferin-1.2.1-py3-none-any.whl
| Download URL | ff_iii_luciferin-1.2.1-py3-none-any.whl |
|---|---|
| Size | 442.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
acaed603c732c995c78895aa66f981ca8c185cf305baa136561bfdab78c16a23
|
|
BLAKE2b-256 checksum How to use checksums |
2ee9377827888c7585596de4809c776ce912ecc24765e2a7435824fcb60693e6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.19 {"installer":{"name":"uv","version":"0.12.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|