Skip to main content

forktex-documents

A framework for generating documents from structured data. It ships the vocabulary and the machinery — not document types: an invoice, a contract, a delivery note are things a consumer defines, because what they must contain is a fact about a business and a jurisdiction, not about a renderer.

data (JSON)  →  canonical (Pydantic)  →  block tree  →  HTML → PDF
                        ↘  read directly for a machine projection (XML, JSON…)

A PDF here is a view over an object, never a source of truth. The canonical record is the document; the page is one projection of it. A machine projection reads the canonical directly rather than the block tree — you cannot recover "19% VAT on this line" from a table cell that says 19%, which is why the two representations both exist.

Install

pip install forktex-documents          # canonical, blocks, HTML
pip install "forktex-documents[pdf]"   # + PDF, via WeasyPrint

PDF is an extra because WeasyPrint pulls native libraries (cairo, pango) that a consumer producing only HTML or a machine projection should not have to install.

What it does

A consumer declares its own canonical, and gets validation, composition and rendering from the framework:

from forktex_documents import FamilyCanonical, Mandate, ParagraphBlock, known

@known
class DeliveryNote(FamilyCanonical):
    family = "logistics"
    mandates = (
        Mandate(
            path="carrier",
            authority="acme-logistics",
            reference="ops:carrier-is-named",
            reason="A note with no carrier cannot be chased when the goods do not arrive.",
        ),
    )
    reference: str
    carrier: str

    def blocks(self, profile):
        return (ParagraphBlock(text=f"Carried by {self.carrier}."),)

note = DeliveryNote(reference="DN-1", carrier="Speedy")
note.check()                      # raises if a mandate is unsatisfied
note.blocks(profile)              # a typed block tree, ready to project

See examples/showcase.py for a document exercising every block kind.

The ideas worth knowing

Derived values are never stored. A consumer's totals, VAT subtotals and expiry dates are computed_fields on its own canonical — and this package is what makes that hold. Every model sets extra="forbid", so a record carrying a hand-written total is a validation error rather than a silent disagreement, and a stored total that was tampered with is dropped and recomputed on load. A structural guarantee rather than a review rule.

Mandates are cited and conditional. What a jurisdiction requires is data: a path, the authority, the legal reference, and why. Conditions read computed flags, so a retail stock-reception note demands a selling price while a cost-method one does not, and a delivery showing quantity differences demands a three-member committee and a third copy — because those are the rules the form actually carries.

Fiscal facts are time-versioned. VAT rates resolve against the document's own date, so re-rendering a July 2025 Romanian invoice reproduces 19% rather than silently restating it at the current 21%. A date no schedule covers raises instead of guessing.

Blocks render themselves. Twenty-five typed block kinds form a closed discriminated union, each emitting its own HTML. There is no template language deciding layout — the only templating is sandboxed text substitution for locale fragments, where a clause has placeholders to resolve.

Identifiers are validated, not merely shaped. CUI and CNP check digits, IBAN mod-97 across every country's length rule, per-member-state VAT formats. A transposed digit in a national id files a real document against the wrong person; the checksum is what catches it.

What is not here

No invoice, no contract, no delivery note, and no jurisdiction. There is no RO_VAT_RATES, no CUI or CNP check digit, and no default country, language or currency anywhere — a default jurisdiction is a wrong jurisdiction for everyone else, quietly. A consumer supplies its own:

  • a LegislationProfile with its date format, separators, currency and mandates
  • a VatSchedule with its rates and their validity windows
  • national identifier validators, registered into NATIONAL_TAX_ID_VALIDATORS
  • the numbers already spent, passed to a register as BURNED

Layout

domain/     blocks, canonical, mandates, entities, fiscal, localization, theme,
            registry, series  ↑ no I/O — `grep Path domain/` is empty, by test
render/     the HTML projector, inline SVG charts, the asset port

Imports run one way: domain → render → facade.

Development

make install     # poetry install --with dev
make ci          # format, lint, licences, docs, types, audit, tests, build, smoke
make reference   # rewrite committed reference renders — then read the diff
make docs        # render the design records in sources/ into docs/

make ci re-renders every reference document and diffs it byte-for-byte against the committed HTML. A generated artefact that was hand-edited, or a change that altered output nobody intended, fails the build.

The design notes in docs/ are generated the same way, from JSON records in sources/ via forktex-knowledge — the library eats its own principle, so a hand-edited page fails the gate rather than becoming a second author. Start with everything-is-a-document for why a page is never a source of truth, then mandates-are-cited-data for why a legal requirement travels with its citation.

Licence

Dual-licensed: AGPL-3.0-or-later, or a commercial licence from FORKTEX S.R.L. for use in proprietary products, SaaS deployments, or any context where the AGPL's obligations cannot be met. See LICENSE and NOTICE, or contact info@forktex.com.

Metadata

Release files for forktex-documents 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for forktex-documents 0.1.0
File Size Uploaded Provenance Actions
forktex_documents-0.1.0.tar.gz 83.0 kB Without provenance Details for forktex_documents-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for forktex-documents 0.1.0
File Interpreter ABI Platform Actions
forktex_documents-0.1.0-py3-none-any.whl Python 3 none any Details for forktex_documents-0.1.0-py3-none-any.whl

Total release size: 189.7 kB

Release files / forktex_documents-0.1.0.tar.gz

Download URL forktex_documents-0.1.0.tar.gz
Size 83.0 kB
Tags Source
SHA-256 checksum
How to use checksums
acd9daa597c7fd367280ee1930bc88734bad6e0aa2502e08b3762d42d74d649c
BLAKE2b-256 checksum
How to use checksums
669a2843724af0e94e719b284160327f91a180b25edfc9f3b54a04996f7946ec
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.6

Release files / forktex_documents-0.1.0-py3-none-any.whl

Download URL forktex_documents-0.1.0-py3-none-any.whl
Size 106.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9bafca8eb2739cf723e901d68cc4b871c48c454173a8af5f96d7de219a289593
BLAKE2b-256 checksum
How to use checksums
fddf8f2cb6295f2db5fc18872d0940ef427482dcf59faead4704932fb94769ee
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.6

Security for forktex-documents 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page