Metadata-Version: 2.5
Name: isis-report-lib
Version: 0.2.0
Summary: Biblioteca Python para geração de relatórios PDF tabulares com layouts hierárquicos (Jinja2 + Playwright). Extraída do POC isis_report.
Project-URL: Homepage, https://github.com/thepaneb/isis_report
Author: Gil Cleber Barboza
License: MIT
License-File: LICENSE
Keywords: jinja2,pdf,playwright,report,toon
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Requires-Python: >=3.11
Requires-Dist: jinja2>=3.1
Requires-Dist: playwright>=1.40
Requires-Dist: pydantic>=2.0
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest-cov>=6; extra == 'dev'
Requires-Dist: pytest-timeout>=2; extra == 'dev'
Requires-Dist: pytest>=8; extra == 'dev'
Requires-Dist: ruff>=0.4; extra == 'dev'
Description-Content-Type: text/markdown

# isis-report-lib

Python library for **tabular PDF reports** with customizable hierarchical layouts — extracted from the [isis_report](https://github.com/thepaneb/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

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

Dev:

```bash
pip install -e ".[dev]"
```

## Quickstart

```python
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:

```python
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

```bash
# 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`):

```python
generate_pdf(payload, pdf_options={"format": "A4", "margin": {"top": ".2in", "bottom": ".5in"}})
```

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

## Payload

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `meta` | object | yes | `title`, `sub_title`, `mode` (`"exact"`/`"gray"`), `company` |
| `layout` | object | no | hierarchical field definition; omit to infer from data |
| `data` | array | yes | raw records or template format (`{"fields": ..., "groups": ...}`) |

Masks: `str` · `int` (thousands `1.234`) · `float` (pt-BR `1.234,50`) · `date`.

## `.toon` syntax

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

`data[n]` holds the records (`dados[n]` still accepted as a legacy alias). 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

```bash
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`.
