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.
Files changed (97) hide show
  1. reportlab_json_renderer-0.1.0/.github/workflows/ci.yml +48 -0
  2. reportlab_json_renderer-0.1.0/.github/workflows/publish.yml +61 -0
  3. reportlab_json_renderer-0.1.0/.gitignore +41 -0
  4. reportlab_json_renderer-0.1.0/.pre-commit-config.yaml +25 -0
  5. reportlab_json_renderer-0.1.0/AGENTS.md +74 -0
  6. reportlab_json_renderer-0.1.0/CHANGELOG.md +81 -0
  7. reportlab_json_renderer-0.1.0/LICENSE +21 -0
  8. reportlab_json_renderer-0.1.0/PKG-INFO +347 -0
  9. reportlab_json_renderer-0.1.0/README.md +313 -0
  10. reportlab_json_renderer-0.1.0/docs/custom-blocks.md +150 -0
  11. reportlab_json_renderer-0.1.0/docs/custom-templates.md +220 -0
  12. reportlab_json_renderer-0.1.0/docs/custom-themes.md +140 -0
  13. reportlab_json_renderer-0.1.0/docs/implementation-checklist.md +198 -0
  14. reportlab_json_renderer-0.1.0/docs/json-schema.md +329 -0
  15. reportlab_json_renderer-0.1.0/docs/release-readiness-checklist.md +47 -0
  16. reportlab_json_renderer-0.1.0/pdf-generator.md +1086 -0
  17. reportlab_json_renderer-0.1.0/pyproject.toml +102 -0
  18. reportlab_json_renderer-0.1.0/reportlab_json_renderer/__init__.py +56 -0
  19. reportlab_json_renderer-0.1.0/reportlab_json_renderer/assets/__init__.py +1 -0
  20. reportlab_json_renderer-0.1.0/reportlab_json_renderer/blocks/__init__.py +82 -0
  21. reportlab_json_renderer-0.1.0/reportlab_json_renderer/blocks/badge.py +45 -0
  22. reportlab_json_renderer-0.1.0/reportlab_json_renderer/blocks/base.py +61 -0
  23. reportlab_json_renderer-0.1.0/reportlab_json_renderer/blocks/callout.py +75 -0
  24. reportlab_json_renderer-0.1.0/reportlab_json_renderer/blocks/callout_group.py +56 -0
  25. reportlab_json_renderer-0.1.0/reportlab_json_renderer/blocks/chart.py +68 -0
  26. reportlab_json_renderer-0.1.0/reportlab_json_renderer/blocks/divider.py +45 -0
  27. reportlab_json_renderer-0.1.0/reportlab_json_renderer/blocks/image.py +58 -0
  28. reportlab_json_renderer-0.1.0/reportlab_json_renderer/blocks/insight_list.py +62 -0
  29. reportlab_json_renderer-0.1.0/reportlab_json_renderer/blocks/kpi_grid.py +120 -0
  30. reportlab_json_renderer-0.1.0/reportlab_json_renderer/blocks/layout.py +79 -0
  31. reportlab_json_renderer-0.1.0/reportlab_json_renderer/blocks/matrix_table.py +107 -0
  32. reportlab_json_renderer-0.1.0/reportlab_json_renderer/blocks/page_break.py +26 -0
  33. reportlab_json_renderer-0.1.0/reportlab_json_renderer/blocks/paragraph.py +53 -0
  34. reportlab_json_renderer-0.1.0/reportlab_json_renderer/blocks/recommendations.py +99 -0
  35. reportlab_json_renderer-0.1.0/reportlab_json_renderer/blocks/registry.py +92 -0
  36. reportlab_json_renderer-0.1.0/reportlab_json_renderer/blocks/rich_text.py +101 -0
  37. reportlab_json_renderer-0.1.0/reportlab_json_renderer/blocks/section.py +64 -0
  38. reportlab_json_renderer-0.1.0/reportlab_json_renderer/blocks/spacer.py +27 -0
  39. reportlab_json_renderer-0.1.0/reportlab_json_renderer/blocks/summary_box.py +66 -0
  40. reportlab_json_renderer-0.1.0/reportlab_json_renderer/blocks/table.py +133 -0
  41. reportlab_json_renderer-0.1.0/reportlab_json_renderer/blocks/title.py +107 -0
  42. reportlab_json_renderer-0.1.0/reportlab_json_renderer/cli.py +388 -0
  43. reportlab_json_renderer-0.1.0/reportlab_json_renderer/renderer.py +348 -0
  44. reportlab_json_renderer-0.1.0/reportlab_json_renderer/schema/__init__.py +19 -0
  45. reportlab_json_renderer-0.1.0/reportlab_json_renderer/schema/base.py +387 -0
  46. reportlab_json_renderer-0.1.0/reportlab_json_renderer/schema/constants.py +23 -0
  47. reportlab_json_renderer-0.1.0/reportlab_json_renderer/schema/validators.py +286 -0
  48. reportlab_json_renderer-0.1.0/reportlab_json_renderer/templates/__init__.py +31 -0
  49. reportlab_json_renderer-0.1.0/reportlab_json_renderer/templates/analytics_report_v1.py +19 -0
  50. reportlab_json_renderer-0.1.0/reportlab_json_renderer/templates/base.py +139 -0
  51. reportlab_json_renderer-0.1.0/reportlab_json_renderer/templates/business_report_v1.py +19 -0
  52. reportlab_json_renderer-0.1.0/reportlab_json_renderer/templates/compact_report_v1.py +19 -0
  53. reportlab_json_renderer-0.1.0/reportlab_json_renderer/templates/invoice_v1.py +19 -0
  54. reportlab_json_renderer-0.1.0/reportlab_json_renderer/templates/proposal_v1.py +19 -0
  55. reportlab_json_renderer-0.1.0/reportlab_json_renderer/templates/registry.py +79 -0
  56. reportlab_json_renderer-0.1.0/reportlab_json_renderer/themes/__init__.py +25 -0
  57. reportlab_json_renderer-0.1.0/reportlab_json_renderer/themes/base.py +145 -0
  58. reportlab_json_renderer-0.1.0/reportlab_json_renderer/themes/dark.py +30 -0
  59. reportlab_json_renderer-0.1.0/reportlab_json_renderer/themes/green.py +27 -0
  60. reportlab_json_renderer-0.1.0/reportlab_json_renderer/themes/neutral.py +28 -0
  61. reportlab_json_renderer-0.1.0/reportlab_json_renderer/themes/registry.py +77 -0
  62. reportlab_json_renderer-0.1.0/reportlab_json_renderer/utils/__init__.py +1 -0
  63. reportlab_json_renderer-0.1.0/reportlab_json_renderer/utils/charts.py +489 -0
  64. reportlab_json_renderer-0.1.0/reportlab_json_renderer/utils/colors.py +120 -0
  65. reportlab_json_renderer-0.1.0/reportlab_json_renderer/utils/errors.py +36 -0
  66. reportlab_json_renderer-0.1.0/reportlab_json_renderer/utils/fonts.py +77 -0
  67. reportlab_json_renderer-0.1.0/reportlab_json_renderer/utils/images.py +199 -0
  68. reportlab_json_renderer-0.1.0/reportlab_json_renderer/utils/text.py +131 -0
  69. reportlab_json_renderer-0.1.0/reportlab_json_renderer/utils/units.py +82 -0
  70. reportlab_json_renderer-0.1.0/skills/SKILLS.md +262 -0
  71. reportlab_json_renderer-0.1.0/tests/__init__.py +0 -0
  72. reportlab_json_renderer-0.1.0/tests/conftest.py +92 -0
  73. reportlab_json_renderer-0.1.0/tests/fixtures/business_report_spec.json +31 -0
  74. reportlab_json_renderer-0.1.0/tests/fixtures/compact_report_spec.json +33 -0
  75. reportlab_json_renderer-0.1.0/tests/fixtures/edge_all_block_types.json +70 -0
  76. reportlab_json_renderer-0.1.0/tests/fixtures/edge_empty_blocks.json +17 -0
  77. reportlab_json_renderer-0.1.0/tests/fixtures/edge_minimal_fields.json +19 -0
  78. reportlab_json_renderer-0.1.0/tests/fixtures/edge_page_sizes.json +20 -0
  79. reportlab_json_renderer-0.1.0/tests/fixtures/full_spec.json +77 -0
  80. reportlab_json_renderer-0.1.0/tests/fixtures/invoice_spec.json +33 -0
  81. reportlab_json_renderer-0.1.0/tests/fixtures/minimal_spec.json +32 -0
  82. reportlab_json_renderer-0.1.0/tests/fixtures/proposal_spec.json +38 -0
  83. reportlab_json_renderer-0.1.0/tests/test_block_renderers.py +710 -0
  84. reportlab_json_renderer-0.1.0/tests/test_blocks.py +193 -0
  85. reportlab_json_renderer-0.1.0/tests/test_charts.py +187 -0
  86. reportlab_json_renderer-0.1.0/tests/test_cli.py +379 -0
  87. reportlab_json_renderer-0.1.0/tests/test_colors.py +76 -0
  88. reportlab_json_renderer-0.1.0/tests/test_edge_validation.py +207 -0
  89. reportlab_json_renderer-0.1.0/tests/test_golden.py +271 -0
  90. reportlab_json_renderer-0.1.0/tests/test_images.py +154 -0
  91. reportlab_json_renderer-0.1.0/tests/test_renderer.py +347 -0
  92. reportlab_json_renderer-0.1.0/tests/test_schema.py +339 -0
  93. reportlab_json_renderer-0.1.0/tests/test_smoke_components.py +541 -0
  94. reportlab_json_renderer-0.1.0/tests/test_templates.py +138 -0
  95. reportlab_json_renderer-0.1.0/tests/test_text.py +120 -0
  96. reportlab_json_renderer-0.1.0/tests/test_themes.py +156 -0
  97. 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.