reportlab-json-renderer 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- reportlab_json_renderer-0.1.0/.github/workflows/ci.yml +48 -0
- reportlab_json_renderer-0.1.0/.github/workflows/publish.yml +61 -0
- reportlab_json_renderer-0.1.0/.gitignore +41 -0
- reportlab_json_renderer-0.1.0/.pre-commit-config.yaml +25 -0
- reportlab_json_renderer-0.1.0/AGENTS.md +74 -0
- reportlab_json_renderer-0.1.0/CHANGELOG.md +81 -0
- reportlab_json_renderer-0.1.0/LICENSE +21 -0
- reportlab_json_renderer-0.1.0/PKG-INFO +347 -0
- reportlab_json_renderer-0.1.0/README.md +313 -0
- reportlab_json_renderer-0.1.0/docs/custom-blocks.md +150 -0
- reportlab_json_renderer-0.1.0/docs/custom-templates.md +220 -0
- reportlab_json_renderer-0.1.0/docs/custom-themes.md +140 -0
- reportlab_json_renderer-0.1.0/docs/implementation-checklist.md +198 -0
- reportlab_json_renderer-0.1.0/docs/json-schema.md +329 -0
- reportlab_json_renderer-0.1.0/docs/release-readiness-checklist.md +47 -0
- reportlab_json_renderer-0.1.0/pdf-generator.md +1086 -0
- reportlab_json_renderer-0.1.0/pyproject.toml +102 -0
- reportlab_json_renderer-0.1.0/reportlab_json_renderer/__init__.py +56 -0
- reportlab_json_renderer-0.1.0/reportlab_json_renderer/assets/__init__.py +1 -0
- reportlab_json_renderer-0.1.0/reportlab_json_renderer/blocks/__init__.py +82 -0
- reportlab_json_renderer-0.1.0/reportlab_json_renderer/blocks/badge.py +45 -0
- reportlab_json_renderer-0.1.0/reportlab_json_renderer/blocks/base.py +61 -0
- reportlab_json_renderer-0.1.0/reportlab_json_renderer/blocks/callout.py +75 -0
- reportlab_json_renderer-0.1.0/reportlab_json_renderer/blocks/callout_group.py +56 -0
- reportlab_json_renderer-0.1.0/reportlab_json_renderer/blocks/chart.py +68 -0
- reportlab_json_renderer-0.1.0/reportlab_json_renderer/blocks/divider.py +45 -0
- reportlab_json_renderer-0.1.0/reportlab_json_renderer/blocks/image.py +58 -0
- reportlab_json_renderer-0.1.0/reportlab_json_renderer/blocks/insight_list.py +62 -0
- reportlab_json_renderer-0.1.0/reportlab_json_renderer/blocks/kpi_grid.py +120 -0
- reportlab_json_renderer-0.1.0/reportlab_json_renderer/blocks/layout.py +79 -0
- reportlab_json_renderer-0.1.0/reportlab_json_renderer/blocks/matrix_table.py +107 -0
- reportlab_json_renderer-0.1.0/reportlab_json_renderer/blocks/page_break.py +26 -0
- reportlab_json_renderer-0.1.0/reportlab_json_renderer/blocks/paragraph.py +53 -0
- reportlab_json_renderer-0.1.0/reportlab_json_renderer/blocks/recommendations.py +99 -0
- reportlab_json_renderer-0.1.0/reportlab_json_renderer/blocks/registry.py +92 -0
- reportlab_json_renderer-0.1.0/reportlab_json_renderer/blocks/rich_text.py +101 -0
- reportlab_json_renderer-0.1.0/reportlab_json_renderer/blocks/section.py +64 -0
- reportlab_json_renderer-0.1.0/reportlab_json_renderer/blocks/spacer.py +27 -0
- reportlab_json_renderer-0.1.0/reportlab_json_renderer/blocks/summary_box.py +66 -0
- reportlab_json_renderer-0.1.0/reportlab_json_renderer/blocks/table.py +133 -0
- reportlab_json_renderer-0.1.0/reportlab_json_renderer/blocks/title.py +107 -0
- reportlab_json_renderer-0.1.0/reportlab_json_renderer/cli.py +388 -0
- reportlab_json_renderer-0.1.0/reportlab_json_renderer/renderer.py +348 -0
- reportlab_json_renderer-0.1.0/reportlab_json_renderer/schema/__init__.py +19 -0
- reportlab_json_renderer-0.1.0/reportlab_json_renderer/schema/base.py +387 -0
- reportlab_json_renderer-0.1.0/reportlab_json_renderer/schema/constants.py +23 -0
- reportlab_json_renderer-0.1.0/reportlab_json_renderer/schema/validators.py +286 -0
- reportlab_json_renderer-0.1.0/reportlab_json_renderer/templates/__init__.py +31 -0
- reportlab_json_renderer-0.1.0/reportlab_json_renderer/templates/analytics_report_v1.py +19 -0
- reportlab_json_renderer-0.1.0/reportlab_json_renderer/templates/base.py +139 -0
- reportlab_json_renderer-0.1.0/reportlab_json_renderer/templates/business_report_v1.py +19 -0
- reportlab_json_renderer-0.1.0/reportlab_json_renderer/templates/compact_report_v1.py +19 -0
- reportlab_json_renderer-0.1.0/reportlab_json_renderer/templates/invoice_v1.py +19 -0
- reportlab_json_renderer-0.1.0/reportlab_json_renderer/templates/proposal_v1.py +19 -0
- reportlab_json_renderer-0.1.0/reportlab_json_renderer/templates/registry.py +79 -0
- reportlab_json_renderer-0.1.0/reportlab_json_renderer/themes/__init__.py +25 -0
- reportlab_json_renderer-0.1.0/reportlab_json_renderer/themes/base.py +145 -0
- reportlab_json_renderer-0.1.0/reportlab_json_renderer/themes/dark.py +30 -0
- reportlab_json_renderer-0.1.0/reportlab_json_renderer/themes/green.py +27 -0
- reportlab_json_renderer-0.1.0/reportlab_json_renderer/themes/neutral.py +28 -0
- reportlab_json_renderer-0.1.0/reportlab_json_renderer/themes/registry.py +77 -0
- reportlab_json_renderer-0.1.0/reportlab_json_renderer/utils/__init__.py +1 -0
- reportlab_json_renderer-0.1.0/reportlab_json_renderer/utils/charts.py +489 -0
- reportlab_json_renderer-0.1.0/reportlab_json_renderer/utils/colors.py +120 -0
- reportlab_json_renderer-0.1.0/reportlab_json_renderer/utils/errors.py +36 -0
- reportlab_json_renderer-0.1.0/reportlab_json_renderer/utils/fonts.py +77 -0
- reportlab_json_renderer-0.1.0/reportlab_json_renderer/utils/images.py +199 -0
- reportlab_json_renderer-0.1.0/reportlab_json_renderer/utils/text.py +131 -0
- reportlab_json_renderer-0.1.0/reportlab_json_renderer/utils/units.py +82 -0
- reportlab_json_renderer-0.1.0/skills/SKILLS.md +262 -0
- reportlab_json_renderer-0.1.0/tests/__init__.py +0 -0
- reportlab_json_renderer-0.1.0/tests/conftest.py +92 -0
- reportlab_json_renderer-0.1.0/tests/fixtures/business_report_spec.json +31 -0
- reportlab_json_renderer-0.1.0/tests/fixtures/compact_report_spec.json +33 -0
- reportlab_json_renderer-0.1.0/tests/fixtures/edge_all_block_types.json +70 -0
- reportlab_json_renderer-0.1.0/tests/fixtures/edge_empty_blocks.json +17 -0
- reportlab_json_renderer-0.1.0/tests/fixtures/edge_minimal_fields.json +19 -0
- reportlab_json_renderer-0.1.0/tests/fixtures/edge_page_sizes.json +20 -0
- reportlab_json_renderer-0.1.0/tests/fixtures/full_spec.json +77 -0
- reportlab_json_renderer-0.1.0/tests/fixtures/invoice_spec.json +33 -0
- reportlab_json_renderer-0.1.0/tests/fixtures/minimal_spec.json +32 -0
- reportlab_json_renderer-0.1.0/tests/fixtures/proposal_spec.json +38 -0
- reportlab_json_renderer-0.1.0/tests/test_block_renderers.py +710 -0
- reportlab_json_renderer-0.1.0/tests/test_blocks.py +193 -0
- reportlab_json_renderer-0.1.0/tests/test_charts.py +187 -0
- reportlab_json_renderer-0.1.0/tests/test_cli.py +379 -0
- reportlab_json_renderer-0.1.0/tests/test_colors.py +76 -0
- reportlab_json_renderer-0.1.0/tests/test_edge_validation.py +207 -0
- reportlab_json_renderer-0.1.0/tests/test_golden.py +271 -0
- reportlab_json_renderer-0.1.0/tests/test_images.py +154 -0
- reportlab_json_renderer-0.1.0/tests/test_renderer.py +347 -0
- reportlab_json_renderer-0.1.0/tests/test_schema.py +339 -0
- reportlab_json_renderer-0.1.0/tests/test_smoke_components.py +541 -0
- reportlab_json_renderer-0.1.0/tests/test_templates.py +138 -0
- reportlab_json_renderer-0.1.0/tests/test_text.py +120 -0
- reportlab_json_renderer-0.1.0/tests/test_themes.py +156 -0
- reportlab_json_renderer-0.1.0/tests/test_units.py +70 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
lint:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v4
|
|
14
|
+
- uses: actions/setup-python@v5
|
|
15
|
+
with:
|
|
16
|
+
python-version: "3.13"
|
|
17
|
+
- run: pip install ruff
|
|
18
|
+
- run: ruff check .
|
|
19
|
+
- run: ruff format --check .
|
|
20
|
+
|
|
21
|
+
test:
|
|
22
|
+
runs-on: ubuntu-latest
|
|
23
|
+
strategy:
|
|
24
|
+
fail-fast: false
|
|
25
|
+
matrix:
|
|
26
|
+
python-version: ["3.11", "3.12", "3.13"]
|
|
27
|
+
steps:
|
|
28
|
+
- uses: actions/checkout@v4
|
|
29
|
+
- uses: actions/setup-python@v5
|
|
30
|
+
with:
|
|
31
|
+
python-version: ${{ matrix.python-version }}
|
|
32
|
+
- run: pip install -e ".[dev]"
|
|
33
|
+
- run: pytest --tb=short -q
|
|
34
|
+
- run: pytest --cov --cov-report=term-missing --cov-fail-under=90
|
|
35
|
+
|
|
36
|
+
build:
|
|
37
|
+
runs-on: ubuntu-latest
|
|
38
|
+
steps:
|
|
39
|
+
- uses: actions/checkout@v4
|
|
40
|
+
- uses: actions/setup-python@v5
|
|
41
|
+
with:
|
|
42
|
+
python-version: "3.13"
|
|
43
|
+
- run: pip install build
|
|
44
|
+
- run: python -m build
|
|
45
|
+
- uses: actions/upload-artifact@v4
|
|
46
|
+
with:
|
|
47
|
+
name: dist
|
|
48
|
+
path: dist/
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Publishes reportlab-json-renderer to PyPI whenever a version tag (v*) is pushed,
|
|
2
|
+
# or when triggered manually via the GitHub Actions UI.
|
|
3
|
+
#
|
|
4
|
+
# Uses PyPI Trusted Publishing (OIDC) — no API token secret is required.
|
|
5
|
+
# One-time PyPI setup: see README.md § "Publishing to PyPI".
|
|
6
|
+
|
|
7
|
+
name: Publish to PyPI
|
|
8
|
+
|
|
9
|
+
on:
|
|
10
|
+
push:
|
|
11
|
+
tags:
|
|
12
|
+
- "v*" # e.g. v0.1.0, v1.2.3
|
|
13
|
+
workflow_dispatch: # allow manual runs from the Actions tab
|
|
14
|
+
|
|
15
|
+
jobs:
|
|
16
|
+
build:
|
|
17
|
+
name: Build distribution
|
|
18
|
+
runs-on: ubuntu-latest
|
|
19
|
+
|
|
20
|
+
steps:
|
|
21
|
+
- uses: actions/checkout@v4
|
|
22
|
+
|
|
23
|
+
- name: Install uv
|
|
24
|
+
uses: astral-sh/setup-uv@v5
|
|
25
|
+
|
|
26
|
+
- name: Set up Python
|
|
27
|
+
uses: actions/setup-python@v5
|
|
28
|
+
with:
|
|
29
|
+
python-version: "3.11"
|
|
30
|
+
|
|
31
|
+
- name: Build package
|
|
32
|
+
run: uv build
|
|
33
|
+
|
|
34
|
+
- name: Upload build artifacts
|
|
35
|
+
uses: actions/upload-artifact@v4
|
|
36
|
+
with:
|
|
37
|
+
name: dist
|
|
38
|
+
path: dist/
|
|
39
|
+
|
|
40
|
+
publish:
|
|
41
|
+
name: Publish to PyPI
|
|
42
|
+
needs: build
|
|
43
|
+
runs-on: ubuntu-latest
|
|
44
|
+
|
|
45
|
+
# Required for PyPI Trusted Publishing (OIDC)
|
|
46
|
+
environment:
|
|
47
|
+
name: pypi
|
|
48
|
+
url: https://pypi.org/p/reportlab-json-renderer
|
|
49
|
+
|
|
50
|
+
permissions:
|
|
51
|
+
id-token: write # OIDC token — this replaces the need for an API secret
|
|
52
|
+
|
|
53
|
+
steps:
|
|
54
|
+
- name: Download build artifacts
|
|
55
|
+
uses: actions/download-artifact@v4
|
|
56
|
+
with:
|
|
57
|
+
name: dist
|
|
58
|
+
path: dist/
|
|
59
|
+
|
|
60
|
+
- name: Publish to PyPI
|
|
61
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
|
|
7
|
+
# Distribution / packaging
|
|
8
|
+
dist/
|
|
9
|
+
build/
|
|
10
|
+
*.egg-info/
|
|
11
|
+
*.egg
|
|
12
|
+
|
|
13
|
+
# Virtual environments
|
|
14
|
+
.venv/
|
|
15
|
+
venv/
|
|
16
|
+
env/
|
|
17
|
+
|
|
18
|
+
# IDE
|
|
19
|
+
.idea/
|
|
20
|
+
.vscode/
|
|
21
|
+
*.swp
|
|
22
|
+
*.swo
|
|
23
|
+
*~
|
|
24
|
+
|
|
25
|
+
# pytest / coverage
|
|
26
|
+
.pytest_cache/
|
|
27
|
+
htmlcov/
|
|
28
|
+
.coverage
|
|
29
|
+
.coverage.*
|
|
30
|
+
coverage.xml
|
|
31
|
+
|
|
32
|
+
# Ruff
|
|
33
|
+
.ruff_cache/
|
|
34
|
+
|
|
35
|
+
# OS
|
|
36
|
+
.DS_Store
|
|
37
|
+
Thumbs.db
|
|
38
|
+
|
|
39
|
+
# Generated PDFs (don't commit test output)
|
|
40
|
+
*.pdf
|
|
41
|
+
!tests/fixtures/*.pdf
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
# ── Linting & formatting ────────────────────────────────────────────
|
|
3
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
4
|
+
rev: v0.4.8
|
|
5
|
+
hooks:
|
|
6
|
+
- id: ruff
|
|
7
|
+
args: [--fix]
|
|
8
|
+
- id: ruff-format
|
|
9
|
+
|
|
10
|
+
# ── Tests & coverage ────────────────────────────────────────────────
|
|
11
|
+
- repo: local
|
|
12
|
+
hooks:
|
|
13
|
+
- id: pytest
|
|
14
|
+
name: pytest
|
|
15
|
+
entry: pytest
|
|
16
|
+
language: system
|
|
17
|
+
pass_filenames: false
|
|
18
|
+
always_run: true
|
|
19
|
+
|
|
20
|
+
- id: coverage
|
|
21
|
+
name: coverage check
|
|
22
|
+
entry: pytest --cov --cov-report=term-missing --cov-fail-under=90
|
|
23
|
+
language: system
|
|
24
|
+
pass_filenames: false
|
|
25
|
+
always_run: true
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Agent Instructions
|
|
2
|
+
|
|
3
|
+
This file defines how coding agents must work in this repository.
|
|
4
|
+
Make sure that we are building python3 library which other python projects can easily extend and use as per their requirement.
|
|
5
|
+
|
|
6
|
+
## Working Principles
|
|
7
|
+
|
|
8
|
+
- Treat `pdf-generator.md` as the source of truth for library behavior.
|
|
9
|
+
- Do not re-open locked decisions unless the user explicitly asks to change them.
|
|
10
|
+
- Keep implementation choices boring, stable, and easy to maintain.
|
|
11
|
+
- Prefer clear bounded contexts over clever shared abstractions.
|
|
12
|
+
- Make small, reviewable changes.
|
|
13
|
+
- Preserve user changes. Do not revert unrelated work.
|
|
14
|
+
|
|
15
|
+
## Coding Standard
|
|
16
|
+
|
|
17
|
+
- Constants must be contained in a single file per package or bounded context.
|
|
18
|
+
- Each Python file must do exactly one domain task.
|
|
19
|
+
- Folders must be logically grouped by responsibility.
|
|
20
|
+
- Always prefer the most stable, reputed, security-aware third-party dependencies.
|
|
21
|
+
- Each function must do one granular task, such as:
|
|
22
|
+
- merging data
|
|
23
|
+
- fetching data
|
|
24
|
+
- validating data
|
|
25
|
+
- transforming data
|
|
26
|
+
- processing data
|
|
27
|
+
- mutating data
|
|
28
|
+
- Keep functions around 50 lines or less.
|
|
29
|
+
- Any function with control flow must have a test case.
|
|
30
|
+
- The pre-commit hook must run:
|
|
31
|
+
- linting
|
|
32
|
+
- tests
|
|
33
|
+
- coverage
|
|
34
|
+
|
|
35
|
+
## Dependency Policy
|
|
36
|
+
|
|
37
|
+
Before adding a dependency:
|
|
38
|
+
|
|
39
|
+
1. Prefer platform or framework built-ins.
|
|
40
|
+
2. Prefer existing project dependencies.
|
|
41
|
+
3. If a new dependency is needed, choose stable, reputed, actively maintained, security-aware npm packages.
|
|
42
|
+
4. Avoid niche packages for small utilities.
|
|
43
|
+
5. Avoid unmaintained packages.
|
|
44
|
+
6. Avoid packages with unnecessary runtime weight.
|
|
45
|
+
|
|
46
|
+
Security-sensitive areas such as ZIP parsing, markdown rendering, auth, and validation require conservative dependency choices.
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
## Git And Change Hygiene
|
|
51
|
+
|
|
52
|
+
- Check current files before editing.
|
|
53
|
+
- Keep changes scoped to the request.
|
|
54
|
+
- Do not reformat unrelated files.
|
|
55
|
+
- Do not rename or reorganize folders unless required by the task.
|
|
56
|
+
- Do not commit unless the user asks.
|
|
57
|
+
- Do not remove user changes.
|
|
58
|
+
|
|
59
|
+
## Pre-Commit Requirement
|
|
60
|
+
|
|
61
|
+
The repository must eventually include a pre-commit hook that runs:
|
|
62
|
+
|
|
63
|
+
- linting
|
|
64
|
+
- tests
|
|
65
|
+
- coverage
|
|
66
|
+
|
|
67
|
+
Do not bypass the hook to land changes.
|
|
68
|
+
|
|
69
|
+
If the project has not been scaffolded yet, preserve this requirement for the initial setup.
|
|
70
|
+
|
|
71
|
+
## Documentation Rules
|
|
72
|
+
|
|
73
|
+
- Update this file when coding workflow, repository conventions, or test standards change.
|
|
74
|
+
- Make sure Readme.md clearly explains what problem it solves and how to install, test and run and use the library.
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.1.0] — 2026-06-19
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
#### Core
|
|
13
|
+
- JSON-driven PDF generation over ReportLab with strict schema validation.
|
|
14
|
+
- `render_pdf` Python API and `pdf-renderer` CLI (`render`, `validate`, `schema`, `templates`).
|
|
15
|
+
- Pydantic-based schema validation with `extra="forbid"` and version compatibility checks.
|
|
16
|
+
- Validation warnings propagated into render results.
|
|
17
|
+
|
|
18
|
+
#### Block Renderers (19 types)
|
|
19
|
+
- `title` — report title with entity, subtitle, and right-aligned text.
|
|
20
|
+
- `section_header` — numbered or unnumbered section headings.
|
|
21
|
+
- `paragraph` — body, bold, and caption styles with markup escaping.
|
|
22
|
+
- `rich_text` — multi-run inline formatting with tone colours.
|
|
23
|
+
- `kpi_grid` — key performance indicator cards in a responsive grid.
|
|
24
|
+
- `callout` — single callout box with tone-based styling.
|
|
25
|
+
- `callout_group` — grouped callouts with optional title.
|
|
26
|
+
- `table` — column-keyed data table with striped and plain styles.
|
|
27
|
+
- `matrix_table` — row/column matrix for comparison tables.
|
|
28
|
+
- `insight_list` — titled insight items with body text.
|
|
29
|
+
- `recommendations` — action items with priority, owner, and impact.
|
|
30
|
+
- `summary_box` — highlighted summary with tone-based border.
|
|
31
|
+
- `image` — local image embedding with path traversal protection.
|
|
32
|
+
- `chart` — bar, pie, and grouped-bar charts via matplotlib.
|
|
33
|
+
- `two_column` — side-by-side layout with configurable widths.
|
|
34
|
+
- `spacer` — vertical spacing.
|
|
35
|
+
- `page_break` — explicit page break.
|
|
36
|
+
- `divider` — horizontal rule with tone and thickness.
|
|
37
|
+
- `badge` — inline label badge with tone colour.
|
|
38
|
+
|
|
39
|
+
#### Templates
|
|
40
|
+
- `analytics_report_v1` — default analytics report layout.
|
|
41
|
+
- `business_report_v1` — business-focused report layout.
|
|
42
|
+
- `compact_report_v1` — condensed single-page layout.
|
|
43
|
+
- `invoice_v1` — invoice document layout.
|
|
44
|
+
- `proposal_v1` — multi-page proposal layout.
|
|
45
|
+
|
|
46
|
+
#### Themes
|
|
47
|
+
- `green` — green-accented professional theme.
|
|
48
|
+
- `neutral` — grey neutral theme.
|
|
49
|
+
- `dark` — dark background theme.
|
|
50
|
+
|
|
51
|
+
#### Safety And Validation
|
|
52
|
+
- Strict schema inputs with `extra="forbid"` where appropriate.
|
|
53
|
+
- Schema version compatibility enforcement.
|
|
54
|
+
- Image path traversal protection and safe-path validation.
|
|
55
|
+
- Resource limits for large payloads, images, and oversized tables/charts.
|
|
56
|
+
- Temporary file cleanup for base64 image handling.
|
|
57
|
+
- User-controlled text escaping before ReportLab markup rendering.
|
|
58
|
+
- Fail-closed block rendering by default.
|
|
59
|
+
- Template `allowed_blocks` enforcement.
|
|
60
|
+
|
|
61
|
+
#### Determinism
|
|
62
|
+
- Reduced non-deterministic PDF output.
|
|
63
|
+
- Parsed-PDF verification with pypdf (page count, text extraction).
|
|
64
|
+
- Idempotent rendering (same spec → identical bytes).
|
|
65
|
+
|
|
66
|
+
#### Testing
|
|
67
|
+
- Comprehensive unit tests for all 19 block renderers.
|
|
68
|
+
- Golden PDF tests for all 6 templates.
|
|
69
|
+
- Edge-case fixtures (empty blocks, minimal fields, all block types, page sizes).
|
|
70
|
+
- Theme coverage tests (green, neutral, dark).
|
|
71
|
+
- Schema validation tests.
|
|
72
|
+
- CLI tests.
|
|
73
|
+
- Chart, colour, image, text, and unit utility tests.
|
|
74
|
+
|
|
75
|
+
#### Packaging
|
|
76
|
+
- MIT license.
|
|
77
|
+
- PyPI-ready metadata with classifiers and project URLs.
|
|
78
|
+
- Hatchling build system.
|
|
79
|
+
- Ruff linting and formatting.
|
|
80
|
+
- Pre-commit hook configuration.
|
|
81
|
+
- pytest with coverage (90% threshold).
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 reportlab-json-renderer contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|