facturization
Generate high-quality PDF invoices from a YAML specification.
Background
I needed an invoice generator for my business with high quality typesetting, but I did not like any of the LaTeX templates I could find, and I wanted full control and greater flexibility compared to the projects I had seen. And so here we are.
Requirements
- A TeX distribution providing
pdflatex(e.g. TeX Live) with a few common packages:geometry,ragged2e,booktabs,tabularx,enumitem,hyperref, andbabel. These ship with a full TeX Live install.
Installation
Run it directly with uv:
uv run facturization path/to/input.yml --output-dir out/
Or install it as a standalone command-line tool:
uv tool install facturization
Pip is also supported:
pip install facturization
Usage
facturization path/to/input.yml
The only mandatory argument is the path to the input YAML file. --output-dir
(-o) defaults to the current directory. For an input named foo.yml the tool
writes foo.tex and foo.pdf (alongside pdflatex's .aux/.log) into the
output folder.
Example
Try out the example from the repo:
uv run facturization example/details.yml --output-dir example
This renders example/details.yml to example/details.pdf:
Input schema
Top-level keys
| Key | Required | Description |
|---|---|---|
invoice_number |
yes | Invoice identifier, shown in the header. |
issue_date |
yes | Date of issue. A YAML date is formatted like May 4, 2026. |
due_date |
no | Payment due date, formatted the same way. |
from |
yes | The sender party (see Party). |
to |
yes | The recipient party (see Party). |
service |
yes | The invoice line items (see Service). |
currency |
yes | Currency code shown next to the totals, e.g. EUR. |
separator |
yes | Decimal separator for amounts: dot or comma. |
payment |
no | Ordered mapping of label → value with payment instructions, rendered as a labelled list at the bottom. |
reverse_charge_note |
no | Footnote text used when any line sets reverse_charge. Default: VAT to be paid on a reverse charge basis. |
closingnote |
no | Free text printed at the very bottom; blank lines start new paragraphs. |
lang |
no | babel language for hyphenation and date/typography conventions, e.g. english. |
fontsize |
no | Base font size: 10pt (default), 11pt, or 12pt. |
geometry |
no | LaTeX geometry options for page size and margins. Default: a4paper, margin=18mm. |
Party
Used for both from and to.
| Key | Required | Description |
|---|---|---|
address |
yes | List of lines (name, street, city, country, …), printed as given. |
email |
no | Shown as e-mail. |
phone |
no | Shown as Phone. |
vat_identification_number |
no | Shown as VAT ID. |
company_registration_number |
no | Shown as Corp. reg. no. |
tax_code |
no | Shown as Tax code. |
Service
Each entry in the service list is one line item.
| Key | Required | Description |
|---|---|---|
description |
yes | Line description. |
unit_price |
yes | Price per unit. |
quantity |
no | Quantity, default 1. |
vat |
no | VAT rate in percent, default 0. |
reverse_charge |
no | If true, marks the line with a footnote and enables the shared reverse-charge note. |
details |
no | List of sub-bullets shown under the description. |
Development
Linting and type checking are handled by Ruff and
ty, configured in pyproject.toml. Both are part of the
dev dependency group, so uv sync installs them.
# Lint
uv run ruff check .
# Verify formatting (no changes written)
uv run ruff format --check .
# Apply auto-fixes and reformat
uv run ruff check --fix .
uv run ruff format .
# Type check (strict mode, all rules as errors)
uv run ty check .
Credits
Inspired by mrzool/invoice-boilerplate. This project takes the same idea of invoice typesetting from a plain data file, but replaces the heavy pandoc dependency with a small uv + Python + Jinja2 pipeline that renders a LaTeX template and compiles it with pdflatex.
License
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file facturization-0.1.0.tar.gz.
File metadata
- Download URL: facturization-0.1.0.tar.gz
- Upload date:
- Size: 130.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9b929a97fcee2efdec16346795376354f1654e1d4a2d1db0c57795baccd57950
|
|
| MD5 |
b5473bb3488a0c167ec0c5622cc7b14a
|
|
| BLAKE2b-256 |
38d0630f8550231ccd24d678ab93d8fcad8b984ae23a3708cf7ef78231bf1056
|
Provenance
The following attestation bundles were made for facturization-0.1.0.tar.gz:
Publisher:
continuous_integration.yaml on m-pilia/facturization
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
facturization-0.1.0.tar.gz -
Subject digest:
9b929a97fcee2efdec16346795376354f1654e1d4a2d1db0c57795baccd57950 - Sigstore transparency entry: 2321930165
- Sigstore integration time:
-
Permalink:
m-pilia/facturization@325341dd029686f4b67e4027137a70d95fd0d513 -
Branch / Tag:
refs/heads/master - Owner: https://github.com/m-pilia
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
continuous_integration.yaml@325341dd029686f4b67e4027137a70d95fd0d513 -
Trigger Event:
push
-
Statement type:
File details
Details for the file facturization-0.1.0-py3-none-any.whl.
File metadata
- Download URL: facturization-0.1.0-py3-none-any.whl
- Upload date:
- Size: 9.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7d2a8f09b0826ad16cca8fb87c0cf94a45d4d91fd842774208efe21d857f7ba8
|
|
| MD5 |
9e525ed068e9f8261a8a2d8d7f4ca1c5
|
|
| BLAKE2b-256 |
3648e1c49031daf22681447b32037fa7370c68c52b8897f92fe226022b10084b
|
Provenance
The following attestation bundles were made for facturization-0.1.0-py3-none-any.whl:
Publisher:
continuous_integration.yaml on m-pilia/facturization
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
facturization-0.1.0-py3-none-any.whl -
Subject digest:
7d2a8f09b0826ad16cca8fb87c0cf94a45d4d91fd842774208efe21d857f7ba8 - Sigstore transparency entry: 2321930216
- Sigstore integration time:
-
Permalink:
m-pilia/facturization@325341dd029686f4b67e4027137a70d95fd0d513 -
Branch / Tag:
refs/heads/master - Owner: https://github.com/m-pilia
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
continuous_integration.yaml@325341dd029686f4b67e4027137a70d95fd0d513 -
Trigger Event:
push
-
Statement type: