pdfblox 1.0.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 (39) hide show
  1. pdfblox-1.0.0/LICENSE +21 -0
  2. pdfblox-1.0.0/PKG-INFO +220 -0
  3. pdfblox-1.0.0/README.md +205 -0
  4. pdfblox-1.0.0/pyproject.toml +25 -0
  5. pdfblox-1.0.0/setup.cfg +4 -0
  6. pdfblox-1.0.0/src/pdfblox/__init__.py +127 -0
  7. pdfblox-1.0.0/src/pdfblox/charts.py +381 -0
  8. pdfblox-1.0.0/src/pdfblox/document.py +611 -0
  9. pdfblox-1.0.0/src/pdfblox/fonts.py +101 -0
  10. pdfblox-1.0.0/src/pdfblox/footer.py +73 -0
  11. pdfblox-1.0.0/src/pdfblox/header.py +207 -0
  12. pdfblox-1.0.0/src/pdfblox/images.py +77 -0
  13. pdfblox-1.0.0/src/pdfblox/layout.py +143 -0
  14. pdfblox-1.0.0/src/pdfblox/lists.py +111 -0
  15. pdfblox-1.0.0/src/pdfblox/report.py +222 -0
  16. pdfblox-1.0.0/src/pdfblox/tables.py +317 -0
  17. pdfblox-1.0.0/src/pdfblox/text.py +107 -0
  18. pdfblox-1.0.0/src/pdfblox/theme.py +222 -0
  19. pdfblox-1.0.0/src/pdfblox/themes.py +166 -0
  20. pdfblox-1.0.0/src/pdfblox/utils.py +105 -0
  21. pdfblox-1.0.0/src/pdfblox.egg-info/PKG-INFO +220 -0
  22. pdfblox-1.0.0/src/pdfblox.egg-info/SOURCES.txt +37 -0
  23. pdfblox-1.0.0/src/pdfblox.egg-info/dependency_links.txt +1 -0
  24. pdfblox-1.0.0/src/pdfblox.egg-info/requires.txt +4 -0
  25. pdfblox-1.0.0/src/pdfblox.egg-info/top_level.txt +1 -0
  26. pdfblox-1.0.0/tests/test_charts.py +140 -0
  27. pdfblox-1.0.0/tests/test_document.py +100 -0
  28. pdfblox-1.0.0/tests/test_fonts.py +57 -0
  29. pdfblox-1.0.0/tests/test_header_footer.py +87 -0
  30. pdfblox-1.0.0/tests/test_images.py +51 -0
  31. pdfblox-1.0.0/tests/test_keyvalue.py +28 -0
  32. pdfblox-1.0.0/tests/test_layout.py +36 -0
  33. pdfblox-1.0.0/tests/test_lists.py +50 -0
  34. pdfblox-1.0.0/tests/test_report.py +82 -0
  35. pdfblox-1.0.0/tests/test_tables.py +63 -0
  36. pdfblox-1.0.0/tests/test_text.py +33 -0
  37. pdfblox-1.0.0/tests/test_theme.py +92 -0
  38. pdfblox-1.0.0/tests/test_themes.py +90 -0
  39. pdfblox-1.0.0/tests/test_utils.py +40 -0
pdfblox-1.0.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Aleksey Suvorov.
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.
pdfblox-1.0.0/PKG-INFO ADDED
@@ -0,0 +1,220 @@
1
+ Metadata-Version: 2.4
2
+ Name: pdfblox
3
+ Version: 1.0.0
4
+ Summary: Composable PDF building blocks (tables, headers, footers, title pages, tile grids) built on ReportLab.
5
+ Author-email: Aleksey Suvorov <cranesoft@protonmail.com>
6
+ License: MIT
7
+ Keywords: pdf,reportlab,report,building-blocks
8
+ Requires-Python: >=3.9
9
+ Description-Content-Type: text/markdown
10
+ License-File: LICENSE
11
+ Requires-Dist: reportlab>=4.0
12
+ Provides-Extra: test
13
+ Requires-Dist: pytest>=7.0; extra == "test"
14
+ Dynamic: license-file
15
+
16
+ # pdfblox
17
+
18
+ Composable **PDF building blocks** for report generation, built on
19
+ [ReportLab](https://www.reportlab.com/). pdfblox turns structured data and
20
+ images into finished PDF reports — styled tables, page headers/footers,
21
+ title pages, and tile grids.
22
+
23
+ ## Design
24
+
25
+ pdfblox is the **PDF-generation half** of a larger report-writing system. It
26
+ deliberately knows nothing about where data comes from:
27
+
28
+ ```
29
+ ┌──────────────────────────────────────────────────────────────┐
30
+ │ Integration wrapper (owns .env / parameter injection) │
31
+ │ │
32
+ │ ┌─────────────────────┐ ┌────────────────────────┐ │
33
+ │ │ Data-source library │ data │ pdfblox │ │
34
+ │ │ (e.g. Some REST) │ ──────▶ │ (this library) │ │
35
+ │ │ fetch + render │ images │ build the PDF │ │
36
+ │ └─────────────────────┘ └────────────────────────┘ │
37
+ └──────────────────────────────────────────────────────────────┘
38
+ ```
39
+
40
+ Consequences of this boundary:
41
+
42
+ - **One dependency: `reportlab`.** No `plotly`, no `kaleido`, no networking.
43
+ - **No `dotenv`, no `os.getenv`.** All configuration enters through explicit
44
+ function arguments and `*Config` dataclasses. Environment/credential
45
+ loading belongs to the integration layer above.
46
+ - **Images come in as bytes or flowables.** A logo is `logo_data: bytes` or a
47
+ `logo_path`; a chart is a ready-made ReportLab `Image`. pdfblox never
48
+ fetches or renders them.
49
+
50
+ ## Documentation
51
+
52
+ - **[AI_REPORT_AUTHORING.md](AI_REPORT_AUTHORING.md)** — how to *author a report*
53
+ with pdfblox (block reference, recipes, pitfalls, a full template). The guide
54
+ to read when generating report scripts.
55
+ - **[CLAUDE.md](CLAUDE.md)** — how to *develop the library itself* (boundary
56
+ rules, conventions, how to add a block).
57
+
58
+ ## Installation
59
+
60
+ ```bash
61
+ pip install -e .
62
+ ```
63
+
64
+ ## Building Blocks
65
+
66
+ | Block | Module | Key API |
67
+ |-------|--------|---------|
68
+ | Styled table | `pdfblox.tables` | `ColumnConfig`, `TableConfig`, `create_table` |
69
+ | Key/value table | `pdfblox.tables` | `KeyValueConfig`, `create_keyvalue_table` |
70
+ | Text & headings | `pdfblox.text` | `TextConfig`, `paragraph`, `heading` |
71
+ | Lists | `pdfblox.lists` | `ListConfig`, `bullet_list`, `numbered_list` |
72
+ | Image | `pdfblox.images` | `make_image` |
73
+ | Charts (native vector) | `pdfblox.charts` | `ChartConfig`, `bar_chart`, `line_chart`, `pie_chart`, `scatter_chart` |
74
+ | Layout primitives | `pdfblox.layout` | `spacer`, `divider`, `CalloutConfig`, `kpi_callout` |
75
+ | Page header | `pdfblox.header` | `HeaderConfig`, `draw_page_header` |
76
+ | Page footer | `pdfblox.footer` | `FooterConfig`, `draw_page_footer` |
77
+ | Title / cover page | `pdfblox.document` | `TitlePageConfig` |
78
+ | Tile grid | `pdfblox.document` | `TileGridConfig`, `build_tile_grid` |
79
+ | Document assembly | `pdfblox.document` | `PdfConfig`, `build_pdf`, `build_paginated_pdf` |
80
+ | Fluent builder | `pdfblox.report` | `Report` |
81
+ | Theme | `pdfblox.theme` | `Theme` |
82
+ | Theme presets | `pdfblox.themes` | `get_theme`, `available_themes`, `corporate_blue`, `slate_gray`, `forest_green`, `burgundy`, `teal`, `graphite` |
83
+ | Unicode fonts | `pdfblox.fonts` | `use_unicode_fonts`, `register_font` |
84
+ | Date / OS helpers | `pdfblox.utils` | `parse_timestamp`, `normalize_date`, `blank_to_none`, `open_file_in_windows` |
85
+
86
+ ### One palette for the whole report: `Theme`
87
+
88
+ A `Theme` bundles fonts and colours and produces every block's config from
89
+ them. Pass it to `Report` and blocks are styled automatically; explicit
90
+ configs and per-call overrides still win.
91
+
92
+ ```python
93
+ from reportlab.lib import colors
94
+ from pdfblox import Report, Theme
95
+
96
+ theme = Theme(primary_color=colors.HexColor("#7A0019")) # brand colour
97
+
98
+ (
99
+ Report("out.pdf",
100
+ theme=theme,
101
+ header_config=theme.header_config("Quarterly Report"),
102
+ footer_config=theme.footer_config())
103
+ .add_heading("Summary") # styled from theme
104
+ .add_paragraph("Body text.") # styled from theme
105
+ .add_callout("42", "Sensors") # styled from theme
106
+ .build()
107
+ )
108
+ ```
109
+
110
+ ### Charts
111
+
112
+ pdfblox draws **native vector charts** with ReportLab's own graphics engine —
113
+ no Plotly, kaleido, or matplotlib, and no extra dependency. Good for the
114
+ standard reporting charts; series colours come from the active `Theme`.
115
+
116
+ ```python
117
+ from pdfblox import Report, get_theme
118
+
119
+ (
120
+ Report("out.pdf", theme=get_theme("forest_green"))
121
+ .add_bar_chart([[3, 5, 2], [4, 1, 6]], categories=["A", "B", "C"],
122
+ series_names=["Plan", "Actual"])
123
+ .add_line_chart([1, 3, 2, 5], categories=["Q1", "Q2", "Q3", "Q4"])
124
+ .add_pie_chart([30, 50, 20], labels=["North", "South", "East"], donut=True)
125
+ .add_scatter_chart([(1, 2), (3, 4), (5, 3)])
126
+ .build()
127
+ )
128
+ ```
129
+
130
+ To embed a chart rendered elsewhere (e.g. a Plotly/server figure), render it to
131
+ PNG/SVG bytes in the data-source layer and place it with `make_image` instead —
132
+ pdfblox stays rendering-engine-free either way.
133
+
134
+ #### Built-in presets
135
+
136
+ Six ready-made palettes popular for reporting — `corporate_blue`,
137
+ `slate_gray`, `forest_green`, `burgundy`, `teal`, `graphite`. Look one up by
138
+ name (with optional overrides) or call its factory:
139
+
140
+ ```python
141
+ from pdfblox import Report, get_theme, available_themes
142
+
143
+ print(available_themes()) # list preset names
144
+ theme = get_theme("slate_gray", base_font_size=11)
145
+
146
+ Report("out.pdf", theme=theme,
147
+ header_config=theme.header_config("Status Report"),
148
+ footer_config=theme.footer_config()).add_heading("Summary").build()
149
+ ```
150
+
151
+ ### Recommended entry point: the `Report` builder
152
+
153
+ ```python
154
+ from pdfblox import Report, HeaderConfig, FooterConfig
155
+
156
+ (
157
+ Report("out.pdf",
158
+ header_config=HeaderConfig(title="Status"),
159
+ footer_config=FooterConfig())
160
+ .add_heading("Summary")
161
+ .add_paragraph("All systems nominal.")
162
+ .add_divider()
163
+ .add_callout("42", "Active Sensors")
164
+ .add_keyvalue_table([("Site", "North"), ("Status", "OK")])
165
+ .build()
166
+ )
167
+ ```
168
+
169
+ ## Quick start
170
+
171
+ A paginated table report with a header and footer — no data source, just
172
+ inline data:
173
+
174
+ ```python
175
+ from reportlab.lib.pagesizes import letter, landscape
176
+ from reportlab.lib.units import inch
177
+ from pdfblox import (
178
+ ColumnConfig, PdfConfig, HeaderConfig, FooterConfig,
179
+ build_paginated_pdf,
180
+ )
181
+
182
+ data = [
183
+ {"name": "Sensor A", "value": 12.4, "status": "OK"},
184
+ {"name": "Sensor B", "value": 99.1, "status": "ALERT"},
185
+ ]
186
+
187
+ columns = [
188
+ ColumnConfig("Instrument", 3 * inch, "name", alignment="LEFT"),
189
+ ColumnConfig("Reading", 2 * inch, "value", formatter=lambda v: f"{v:.1f}"),
190
+ ColumnConfig("Status", 2 * inch, "status"),
191
+ ]
192
+
193
+ build_paginated_pdf(
194
+ data,
195
+ columns,
196
+ "report.pdf",
197
+ pdf_config=PdfConfig(page_size=landscape(letter)),
198
+ header_config=HeaderConfig(title="Instrument Status", company_info=["Acme Co."]),
199
+ footer_config=FooterConfig(),
200
+ )
201
+ ```
202
+
203
+ For mixed content (charts, paragraphs, custom flowables) use `build_pdf`; for
204
+ a grid of chart tiles use `build_tile_grid` to produce per-page `Table`
205
+ flowables, then pass them to `build_pdf`. Add a cover page by passing a
206
+ `TitlePageConfig`.
207
+
208
+ ## Tests
209
+
210
+ ```bash
211
+ pip install -e ".[test]"
212
+ pytest
213
+ ```
214
+
215
+ Each building block has a focused test under `tests/` that exercises it and,
216
+ where relevant, renders a real PDF into a temp directory.
217
+
218
+ ## License
219
+
220
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,205 @@
1
+ # pdfblox
2
+
3
+ Composable **PDF building blocks** for report generation, built on
4
+ [ReportLab](https://www.reportlab.com/). pdfblox turns structured data and
5
+ images into finished PDF reports — styled tables, page headers/footers,
6
+ title pages, and tile grids.
7
+
8
+ ## Design
9
+
10
+ pdfblox is the **PDF-generation half** of a larger report-writing system. It
11
+ deliberately knows nothing about where data comes from:
12
+
13
+ ```
14
+ ┌──────────────────────────────────────────────────────────────┐
15
+ │ Integration wrapper (owns .env / parameter injection) │
16
+ │ │
17
+ │ ┌─────────────────────┐ ┌────────────────────────┐ │
18
+ │ │ Data-source library │ data │ pdfblox │ │
19
+ │ │ (e.g. Some REST) │ ──────▶ │ (this library) │ │
20
+ │ │ fetch + render │ images │ build the PDF │ │
21
+ │ └─────────────────────┘ └────────────────────────┘ │
22
+ └──────────────────────────────────────────────────────────────┘
23
+ ```
24
+
25
+ Consequences of this boundary:
26
+
27
+ - **One dependency: `reportlab`.** No `plotly`, no `kaleido`, no networking.
28
+ - **No `dotenv`, no `os.getenv`.** All configuration enters through explicit
29
+ function arguments and `*Config` dataclasses. Environment/credential
30
+ loading belongs to the integration layer above.
31
+ - **Images come in as bytes or flowables.** A logo is `logo_data: bytes` or a
32
+ `logo_path`; a chart is a ready-made ReportLab `Image`. pdfblox never
33
+ fetches or renders them.
34
+
35
+ ## Documentation
36
+
37
+ - **[AI_REPORT_AUTHORING.md](AI_REPORT_AUTHORING.md)** — how to *author a report*
38
+ with pdfblox (block reference, recipes, pitfalls, a full template). The guide
39
+ to read when generating report scripts.
40
+ - **[CLAUDE.md](CLAUDE.md)** — how to *develop the library itself* (boundary
41
+ rules, conventions, how to add a block).
42
+
43
+ ## Installation
44
+
45
+ ```bash
46
+ pip install -e .
47
+ ```
48
+
49
+ ## Building Blocks
50
+
51
+ | Block | Module | Key API |
52
+ |-------|--------|---------|
53
+ | Styled table | `pdfblox.tables` | `ColumnConfig`, `TableConfig`, `create_table` |
54
+ | Key/value table | `pdfblox.tables` | `KeyValueConfig`, `create_keyvalue_table` |
55
+ | Text & headings | `pdfblox.text` | `TextConfig`, `paragraph`, `heading` |
56
+ | Lists | `pdfblox.lists` | `ListConfig`, `bullet_list`, `numbered_list` |
57
+ | Image | `pdfblox.images` | `make_image` |
58
+ | Charts (native vector) | `pdfblox.charts` | `ChartConfig`, `bar_chart`, `line_chart`, `pie_chart`, `scatter_chart` |
59
+ | Layout primitives | `pdfblox.layout` | `spacer`, `divider`, `CalloutConfig`, `kpi_callout` |
60
+ | Page header | `pdfblox.header` | `HeaderConfig`, `draw_page_header` |
61
+ | Page footer | `pdfblox.footer` | `FooterConfig`, `draw_page_footer` |
62
+ | Title / cover page | `pdfblox.document` | `TitlePageConfig` |
63
+ | Tile grid | `pdfblox.document` | `TileGridConfig`, `build_tile_grid` |
64
+ | Document assembly | `pdfblox.document` | `PdfConfig`, `build_pdf`, `build_paginated_pdf` |
65
+ | Fluent builder | `pdfblox.report` | `Report` |
66
+ | Theme | `pdfblox.theme` | `Theme` |
67
+ | Theme presets | `pdfblox.themes` | `get_theme`, `available_themes`, `corporate_blue`, `slate_gray`, `forest_green`, `burgundy`, `teal`, `graphite` |
68
+ | Unicode fonts | `pdfblox.fonts` | `use_unicode_fonts`, `register_font` |
69
+ | Date / OS helpers | `pdfblox.utils` | `parse_timestamp`, `normalize_date`, `blank_to_none`, `open_file_in_windows` |
70
+
71
+ ### One palette for the whole report: `Theme`
72
+
73
+ A `Theme` bundles fonts and colours and produces every block's config from
74
+ them. Pass it to `Report` and blocks are styled automatically; explicit
75
+ configs and per-call overrides still win.
76
+
77
+ ```python
78
+ from reportlab.lib import colors
79
+ from pdfblox import Report, Theme
80
+
81
+ theme = Theme(primary_color=colors.HexColor("#7A0019")) # brand colour
82
+
83
+ (
84
+ Report("out.pdf",
85
+ theme=theme,
86
+ header_config=theme.header_config("Quarterly Report"),
87
+ footer_config=theme.footer_config())
88
+ .add_heading("Summary") # styled from theme
89
+ .add_paragraph("Body text.") # styled from theme
90
+ .add_callout("42", "Sensors") # styled from theme
91
+ .build()
92
+ )
93
+ ```
94
+
95
+ ### Charts
96
+
97
+ pdfblox draws **native vector charts** with ReportLab's own graphics engine —
98
+ no Plotly, kaleido, or matplotlib, and no extra dependency. Good for the
99
+ standard reporting charts; series colours come from the active `Theme`.
100
+
101
+ ```python
102
+ from pdfblox import Report, get_theme
103
+
104
+ (
105
+ Report("out.pdf", theme=get_theme("forest_green"))
106
+ .add_bar_chart([[3, 5, 2], [4, 1, 6]], categories=["A", "B", "C"],
107
+ series_names=["Plan", "Actual"])
108
+ .add_line_chart([1, 3, 2, 5], categories=["Q1", "Q2", "Q3", "Q4"])
109
+ .add_pie_chart([30, 50, 20], labels=["North", "South", "East"], donut=True)
110
+ .add_scatter_chart([(1, 2), (3, 4), (5, 3)])
111
+ .build()
112
+ )
113
+ ```
114
+
115
+ To embed a chart rendered elsewhere (e.g. a Plotly/server figure), render it to
116
+ PNG/SVG bytes in the data-source layer and place it with `make_image` instead —
117
+ pdfblox stays rendering-engine-free either way.
118
+
119
+ #### Built-in presets
120
+
121
+ Six ready-made palettes popular for reporting — `corporate_blue`,
122
+ `slate_gray`, `forest_green`, `burgundy`, `teal`, `graphite`. Look one up by
123
+ name (with optional overrides) or call its factory:
124
+
125
+ ```python
126
+ from pdfblox import Report, get_theme, available_themes
127
+
128
+ print(available_themes()) # list preset names
129
+ theme = get_theme("slate_gray", base_font_size=11)
130
+
131
+ Report("out.pdf", theme=theme,
132
+ header_config=theme.header_config("Status Report"),
133
+ footer_config=theme.footer_config()).add_heading("Summary").build()
134
+ ```
135
+
136
+ ### Recommended entry point: the `Report` builder
137
+
138
+ ```python
139
+ from pdfblox import Report, HeaderConfig, FooterConfig
140
+
141
+ (
142
+ Report("out.pdf",
143
+ header_config=HeaderConfig(title="Status"),
144
+ footer_config=FooterConfig())
145
+ .add_heading("Summary")
146
+ .add_paragraph("All systems nominal.")
147
+ .add_divider()
148
+ .add_callout("42", "Active Sensors")
149
+ .add_keyvalue_table([("Site", "North"), ("Status", "OK")])
150
+ .build()
151
+ )
152
+ ```
153
+
154
+ ## Quick start
155
+
156
+ A paginated table report with a header and footer — no data source, just
157
+ inline data:
158
+
159
+ ```python
160
+ from reportlab.lib.pagesizes import letter, landscape
161
+ from reportlab.lib.units import inch
162
+ from pdfblox import (
163
+ ColumnConfig, PdfConfig, HeaderConfig, FooterConfig,
164
+ build_paginated_pdf,
165
+ )
166
+
167
+ data = [
168
+ {"name": "Sensor A", "value": 12.4, "status": "OK"},
169
+ {"name": "Sensor B", "value": 99.1, "status": "ALERT"},
170
+ ]
171
+
172
+ columns = [
173
+ ColumnConfig("Instrument", 3 * inch, "name", alignment="LEFT"),
174
+ ColumnConfig("Reading", 2 * inch, "value", formatter=lambda v: f"{v:.1f}"),
175
+ ColumnConfig("Status", 2 * inch, "status"),
176
+ ]
177
+
178
+ build_paginated_pdf(
179
+ data,
180
+ columns,
181
+ "report.pdf",
182
+ pdf_config=PdfConfig(page_size=landscape(letter)),
183
+ header_config=HeaderConfig(title="Instrument Status", company_info=["Acme Co."]),
184
+ footer_config=FooterConfig(),
185
+ )
186
+ ```
187
+
188
+ For mixed content (charts, paragraphs, custom flowables) use `build_pdf`; for
189
+ a grid of chart tiles use `build_tile_grid` to produce per-page `Table`
190
+ flowables, then pass them to `build_pdf`. Add a cover page by passing a
191
+ `TitlePageConfig`.
192
+
193
+ ## Tests
194
+
195
+ ```bash
196
+ pip install -e ".[test]"
197
+ pytest
198
+ ```
199
+
200
+ Each building block has a focused test under `tests/` that exercises it and,
201
+ where relevant, renders a real PDF into a temp directory.
202
+
203
+ ## License
204
+
205
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,25 @@
1
+ [build-system]
2
+ requires = ["setuptools>=64", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "pdfblox"
7
+ version = "1.0.0"
8
+ description = "Composable PDF building blocks (tables, headers, footers, title pages, tile grids) built on ReportLab."
9
+ readme = "README.md"
10
+ requires-python = ">=3.9"
11
+ license = { text = "MIT" }
12
+ authors = [
13
+ { name = "Aleksey Suvorov", email = "cranesoft@protonmail.com" },
14
+ ]
15
+ keywords = ["pdf", "reportlab", "report", "building-blocks"]
16
+ dependencies = [
17
+ "reportlab>=4.0",
18
+ ]
19
+
20
+ [project.optional-dependencies]
21
+ test = ["pytest>=7.0"]
22
+
23
+ [tool.setuptools.packages.find]
24
+ where = ["src"]
25
+ include = ["pdfblox*"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,127 @@
1
+ # Copyright (c) 2026 Aleksey Suvorov
2
+ # SPDX-License-Identifier: MIT
3
+ """
4
+ pdfblox — composable PDF building blocks.
5
+
6
+ A dependency-light library (ReportLab only) for assembling PDF reports from
7
+ declarative building blocks: styled tables, key/value tables, text and
8
+ headings, images, layout primitives (spacers, dividers, KPI callouts), page
9
+ headers/footers, title pages, and tile grids — composed via a fluent
10
+ ``Report`` builder.
11
+
12
+ pdfblox knows nothing about where data or images come from. Callers pass in
13
+ plain Python data (``list[dict]`` rows), image *bytes* or ready-made
14
+ ReportLab flowables, and configuration objects. Fetching data, rendering
15
+ charts, and loading environment/credentials are the responsibility of the
16
+ integration layer that sits above this library.
17
+ """
18
+
19
+ from .tables import (
20
+ ColumnConfig,
21
+ TableConfig,
22
+ create_table,
23
+ KeyValueConfig,
24
+ create_keyvalue_table,
25
+ )
26
+ from .text import TextConfig, paragraph, heading
27
+ from .lists import ListConfig, bullet_list, numbered_list
28
+ from .images import make_image
29
+ from .layout import CalloutConfig, spacer, divider, kpi_callout
30
+ from .charts import (
31
+ ChartConfig, bar_chart, line_chart, pie_chart, scatter_chart,
32
+ )
33
+ from .header import HeaderConfig, draw_page_header
34
+ from .footer import FooterConfig, draw_page_footer
35
+ from .document import (
36
+ PdfConfig,
37
+ TitlePageConfig,
38
+ TileGridConfig,
39
+ build_pdf,
40
+ build_paginated_pdf,
41
+ build_tile_grid,
42
+ )
43
+ from .report import Report
44
+ from .theme import Theme
45
+ from .fonts import register_font, use_unicode_fonts
46
+ from .themes import (
47
+ corporate_blue,
48
+ slate_gray,
49
+ forest_green,
50
+ burgundy,
51
+ teal,
52
+ graphite,
53
+ get_theme,
54
+ available_themes,
55
+ )
56
+ from .utils import (
57
+ parse_timestamp,
58
+ normalize_date,
59
+ blank_to_none,
60
+ open_file_in_windows,
61
+ )
62
+
63
+ __version__ = "1.0.0"
64
+
65
+ __all__ = [
66
+ # Tables
67
+ "ColumnConfig",
68
+ "TableConfig",
69
+ "create_table",
70
+ "KeyValueConfig",
71
+ "create_keyvalue_table",
72
+ # Text
73
+ "TextConfig",
74
+ "paragraph",
75
+ "heading",
76
+ # Lists
77
+ "ListConfig",
78
+ "bullet_list",
79
+ "numbered_list",
80
+ # Images
81
+ "make_image",
82
+ # Layout primitives
83
+ "CalloutConfig",
84
+ "spacer",
85
+ "divider",
86
+ "kpi_callout",
87
+ # Charts (native vector)
88
+ "ChartConfig",
89
+ "bar_chart",
90
+ "line_chart",
91
+ "pie_chart",
92
+ "scatter_chart",
93
+ # Header
94
+ "HeaderConfig",
95
+ "draw_page_header",
96
+ # Footer
97
+ "FooterConfig",
98
+ "draw_page_footer",
99
+ # Document assembly
100
+ "PdfConfig",
101
+ "TitlePageConfig",
102
+ "TileGridConfig",
103
+ "build_pdf",
104
+ "build_paginated_pdf",
105
+ "build_tile_grid",
106
+ # Fluent builder
107
+ "Report",
108
+ # Theme
109
+ "Theme",
110
+ # Fonts (Unicode support)
111
+ "register_font",
112
+ "use_unicode_fonts",
113
+ # Theme presets
114
+ "corporate_blue",
115
+ "slate_gray",
116
+ "forest_green",
117
+ "burgundy",
118
+ "teal",
119
+ "graphite",
120
+ "get_theme",
121
+ "available_themes",
122
+ # Utilities
123
+ "parse_timestamp",
124
+ "normalize_date",
125
+ "blank_to_none",
126
+ "open_file_in_windows",
127
+ ]