Skip to main content

isis-report-lib

CI PyPI Python

Python library for tabular PDF reports with customizable hierarchical layouts — extracted from the isis_report PoC (Robyn microservice), without the server.

  • Input: dict/ReportPayload (meta + optional layout + data) or .toon text
  • Rendering: Jinja2 (templates bundled in the package)
  • PDF: Playwright (Chromium)
  • API: synchronous (generate_pdf) + asynchronous (agenerate_pdf)

Installation

pip install isis-report-lib
playwright install chromium   # required to generate PDFs

After upgrading playwright, reinstall the browser (playwright install chromium): each Playwright version pins a specific Chromium build.

Dev:

pip install -e ".[dev]"

Quickstart

from isis_report_lib import generate_pdf, generate_pdf_from_toon, render_html

payload = {
    "meta": {"title": "Sales Order", "sub_title": "2024", "mode": "exact"},
    "layout": {
        "company": {"label": "Company", "format_mask": "str", "alignment": "left"},
        "orders": {
            "order": {"label": "Code", "format_mask": "int", "alignment": "right"},
            "total": {"label": "Total", "format_mask": "float", "alignment": "right"},
        },
    },
    "data": [{"company": "ACME", "orders": [{"order": 750, "total": 4000}]}],
}

pdf_bytes = generate_pdf(payload)
open("report.pdf", "wb").write(pdf_bytes)

# Without Playwright: just the intermediate HTML
html = render_html(payload)

# From .toon
toon = open("examples/sales_order.toon", encoding="utf-8").read()
open("report_toon.pdf", "wb").write(generate_pdf_from_toon(toon))

Async:

from isis_report_lib import agenerate_pdf, agenerate_pdf_from_toon

pdf = await agenerate_pdf(payload)
pdf = await agenerate_pdf_from_toon(toon_text)

CLI

# PDF from .toon or .json (format guessed from extension)
isis-report generate examples/sales_order.toon -o report.pdf
isis-report generate payload.json --page-format Letter

# Intermediate HTML without a browser (prints to stdout unless -o is given)
isis-report render examples/sales_order.toon -o report.html

PDF options (forwarded to Playwright's page.pdf):

generate_pdf(
    payload,
    pdf_options={
        "format": "A4",
        "margin": {"top": ".2in", "bottom": ".5in"},
        "header_template": "<div>My header</div>",
        "footer_template": "<div>Page <span class='pageNumber'></span></div>",
    },
)

Via CLI: --page-format, --header-template FILE, --footer-template FILE. The report footer shows meta.printed_at, auto-filled with the current timestamp when absent.

Full example in examples/. Note: the sync API opens/closes the browser per call (no leaked processes); the async API reuses the shared pool.

Custom templates

Point template_dir at your own .jinja directory and pick a file with template_name:

generate_pdf(payload, template_dir="my_templates", template_name="invoice.jinja")
isis-report generate order.toon --template-dir my_templates --template-name invoice.jinja

The directory is layered over the bundled one, so you can also override tabular.jinja or reuse tabular_sections.jinja macros. Templates receive dataset, layout, meta, plus the fmt(value, mask) formatter and zip — see examples/custom.jinja.

Theming

Set meta.accent_color to rebrand the report header without a custom template:

payload = {"meta": {"title": "Sales Order", "accent_color": "#1B7A3D"}, ...}

It overrides the --brand-color CSS variable. More masks: str · int · float (pt-BR) · date · percent · currency (R$) · bool.

Payload

Field Type Required Description
meta object yes title, sub_title, mode ("exact"/"gray"), company, locale ("pt-BR", "en-US"…), currency (override, e.g. "EUR"), accent_color, printed_at (auto-filled)
layout object no hierarchical field definition; omit to infer from data
data array yes raw records or template format ({"fields": ..., "groups": ...})

Masks (locale-aware via Babel/CLDR): str · int · float · date (localized for date/datetime objects) · percent · currency · bool (Yes/No).

payload = {
    "meta": {"title": "Sales Order", "locale": "en-US"},  # numbers as 1,234.50, $1,234.50
    "data": [...],
}
isis-report generate order.toon --locale en-US -o out.pdf   # overrides meta.locale

Report parameters

Beyond layout and data, the payload supports declarative behavior — no rigid bands, the document adapts to the data:

payload = {
    "meta": {
        "title": "Sales Order",
        "page": {"size": "A4", "orientation": "landscape", "margins": {"top": ".4in"}},
    },
    "layout": {
        "company": {"label": "Company", "format_mask": "str", "alignment": "left"},
        "orders": {
            "order": {"label": "Code", "format_mask": "int", "alignment": "right"},
            "status": {"label": "Status", "format_mask": "str", "alignment": "left", "visible": False},
            "total": {"label": "Total", "format_mask": "float", "alignment": "right", "aggregate": "sum"},
            "$print_when": {"field": "status", "not_equals": "cancelled"},
            "$order_by": "-order",
        },
    },
    "data": [...],
}
Parameter Where Effect
meta.page meta {size, orientation: portrait|landscape, margins} → PDF page (explicit pdf_options win)
aggregate field def sum|count|avg|min|max → group footers, detail tfoot, grand summary. Flat child lists render as tables (several per item allowed); deeper nesting renders as sections
$print_when any level keep only rows matching {field, equals|not_equals|in|not_in|gt|gte|lt|lte|is_null|not_null}
$order_by any level sort rows: [{field, direction}] or "field" / "-field" (nulls last)
visible / visible_when field def hide a column; visible_when supports {..., scope: any|all}

.toon syntax

meta:
  title: Sales Order
  mode: exact
layout:
  product{Product,str,left}
  total{Total,float,right,sum}
data[1]:
  - product: Pen
    total: 5.50

data[n] holds the records (dados[n] still accepted as a legacy alias). The compact layout form accepts an optional 4th part with the aggregate: total{Total,float,right,sum}. See examples/sales_order.toon.

API

Function Description
generate_pdf(payload, pdf_options?) -> bytes sync PDF from dict/ReportPayload
agenerate_pdf(...) same, async
generate_pdf_from_toon(text, ...) / agenerate_pdf_from_toon PDF from .toon
render_html(payload) / arender_html / render_html_from_toon intermediate HTML (no browser)
ToonParser().parse(text) / parse_toon(text) .toon -> dict
TabularReportService(pdf_options?) pipeline execute(payload) (Fetch→Process→HTML→PDF)

Tests

pytest -q
pytest -q --cov=isis_report_lib   # coverage gate: 85% (enforced in the CI e2e job)
ruff check src tests

Real-PDF tests require playwright install chromium and are skipped (-m "not browser") when no browser is available.

License

MIT — see LICENSE.

Security

  • Dependencies: audited with pip-audit (no known vulnerabilities); Dependabot keeps actions and packages updated; releases are built and published by CI via OIDC trusted publishing (no stored tokens).
  • Trust boundary: templates (.jinja files, template_dir) are code — only load them from sources you trust. Report data (dict/JSON/.toon) is never executed as template code, only interpolated. Jinja autoescaping is off by design (report HTML is rendered to PDF, not served to browsers).
  • Robustness: deeply nested .toon input is rejected with ValueError instead of crashing the interpreter; the Playwright browser runs headless in its own Chromium sandbox per call (sync API) or a shared pool (async API).

Metadata

Release files for isis-report-lib 0.5.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 isis-report-lib 0.5.0
File Size Uploaded Provenance Actions
isis_report_lib-0.5.0.tar.gz 36.7 kB With provenance Details for isis_report_lib-0.5.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for isis-report-lib 0.5.0
File Interpreter ABI Platform Actions
isis_report_lib-0.5.0-py3-none-any.whl Python 3 none any Details for isis_report_lib-0.5.0-py3-none-any.whl

Total release size: 65.1 kB

Release files / isis_report_lib-0.5.0.tar.gz

Download URL isis_report_lib-0.5.0.tar.gz
Size 36.7 kB
Tags Source
SHA-256 checksum
How to use checksums
1b211ba90053949b4a09b879564a0f5b597e27fa1afa434c7ad5a321676271d3
BLAKE2b-256 checksum
How to use checksums
b5eb1e1f4ddda203862d3a9b280cd358dfbb52a312e68e8a04865c7a7074a2b6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 10, 2026.

Transparency log

Release files / isis_report_lib-0.5.0-py3-none-any.whl

Download URL isis_report_lib-0.5.0-py3-none-any.whl
Size 28.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
4d1310eca4c7aa75c062815779d7cf9260547a4e9fd8e995fb4703e074f202b7
BLAKE2b-256 checksum
How to use checksums
3a9189a45e4c510984a241aabc93c15bbc97f09c3811293027ea2757574a94aa
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 10, 2026.

Transparency log

Security for isis-report-lib 0.5.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.

Full provenance

Both files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for isis_report_lib-0.5.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 10, 2026.

Transparency log

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.

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