Composable, styled report components on top of python-docx
Project description
docxkit
Composable, styled report components on top of python-docx.
python-docx exposes a low-level API: runs, paragraphs, and raw OOXML for anything visual (cell shading, table borders, letter spacing). docxkit wraps that in reusable, themed building blocks for generated documents: KPI bands, gradient-shaded heatmap tables, styled data tables, embedded figures, typography presets, and score cards.
- Single dependency:
python-docx. - No plotting dependency.
image_figureembeds pre-rendered image files (PNG, JPEG, ...) produced by any tool (matplotlib, plotly, etc.). - Everything returns the underlying python-docx object, and the raw document
is always reachable via
doc.docx, so you can drop down to the low-level API at any point.
Install
pip install docxkit
Requires Python 3.10+.
Quick start
from docxkit import Document, Theme
doc = Document(theme=Theme(primary="4472C4", font="Calibri"))
doc.title("Q2 Test Report", subtitle="2026-06-11")
doc.kpi_band([("Runs", "42"), ("Pass rate", "93%"), ("P50 latency", "1.2s")])
doc.section("Results by category")
doc.heatmap_table(
headers=["Suite", "Correctness", "Robustness"],
rows=[["parser", 9.1, 8.4], ["cli", 5.2, 4.1]],
value_range=(0, 10),
colormap="red_green",
)
doc.save("report.docx")
Component catalog
Title and typography
doc.title("Report Title", subtitle="muted subtitle line")
doc.section("Section heading") # Heading 1, theme color
doc.section("Subsection", level=2)
doc.eyebrow("category label") # small, bold, upper-cased accent line
doc.paragraph("Body text", bold=False, italic=True, size=9.5,
color="5A6472", align="left")
doc.bullet("List item")
doc.code_block("step 1 12ms\nstep 2 30ms") # indented monospace block
doc.horizontal_rule()
doc.page_break()
KPI band
A borderless single-row strip of metric cards. Each item is
(label, value) or (label, value, caption).
doc.kpi_band([
("Runs", "42", "last 30 days"),
("Pass rate", "93%", "+4 pts vs prior"),
("P50 latency", "1.2s"),
])
Cards split the usable page width evenly. The label renders upper-cased in
theme.primary, the value large and bold, the caption small and muted.
Override the card background with fill="EEF2FA".
Data table
Bordered table with a themed header row and optional zebra striping.
doc.data_table(
headers=["Case", "Suite", "Duration", "Status"],
rows=[
["case-0041", "renderer", "4.21s", "pass"],
["case-0107", "parser", "3.90s", "pass"],
],
zebra=True,
mono_columns=(0,), # render column 0 in the mono font
align=[None, None, "right", "center"],
column_widths_in=[1.2, 1.5, 1.0, 1.0], # optional fixed widths
)
Heatmap table
Numeric cells are filled with a gradient color for their value and get
auto-contrast text (white on dark fills, dark on light fills). String cells
(row labels) render plain; None cells render as a neutral placeholder.
doc.heatmap_table(
headers=["Suite", "Correctness", "Robustness", "Docs"],
rows=[
["parser", 9.1, 8.4, 6.0],
["cli", 5.2, 4.1, None],
],
value_range=(0, 10), # omit to infer from the data
colormap="red_green", # name or custom hex stops
number_format="{:.1f}",
)
Built-in colormaps: red_green, green_red, blue, heat, grey.
A custom colormap is any sequence of two or more hex stops, low to high:
colormap=("EAF1FB", "4472C4", "1F2A44").
Score card
A titled metric table with gradient-shaded values and an optional
pass/fail column (value >= threshold passes).
doc.score_card(
"Release readiness — build 2026.06",
{"Correctness": 8.6, "Robustness": 7.1, "Performance": 6.4},
value_range=(0, 10),
threshold=7.0,
)
Image figure
Embeds a pre-rendered image with an optional caption. docxkit does not render charts itself; pass a file produced by any plotting tool.
doc.image_figure("chart.png", caption="Daily volume", width_in=6.0)
Accepts a path or a binary file-like object. Height scales to preserve the aspect ratio.
Theming reference
Theme is a frozen dataclass shared by every component. All colors are hex
strings ("RRGGBB", "#RRGGBB", or 3-digit shorthand), normalized on
construction.
| Field | Default | Used for |
|---|---|---|
primary |
4472C4 |
Eyebrows, KPI labels, accents |
dark |
1F2A44 |
Title and heading text |
muted |
5A6472 |
Subtitles, captions, secondary text |
good |
2E8540 |
PASS marks |
bad |
C0392B |
FAIL marks |
font |
Calibri |
Body and heading font |
mono_font |
Consolas |
Code blocks, mono_columns |
body_size |
10.5 |
Base body size (pt) |
border |
D5DAE2 |
Table borders, horizontal rules |
header_fill |
= dark |
Table header row fill |
header_text |
FFFFFF |
Table header row text |
zebra_fill |
F2F5FA |
Alternate row fill in zebra tables |
card_fill |
F5F8FD |
KPI card background |
theme = Theme(primary="0E7C5A", font="Georgia", mono_font="Menlo")
doc = Document(theme=theme, margins_in=(0.7, 0.7, 0.7, 0.7))
Color helpers used by the components are public:
from docxkit import gradient_color, lerp_color, contrast_text, COLORMAPS
gradient_color(7.5, 0, 10, "red_green") # -> "8CB938" (interpolated hex)
contrast_text("1F2A44") # -> "FFFFFF"
Full example
examples/build_sample_report.py builds a complete document exercising
every component with demo data:
python examples/build_sample_report.py
# wrote .../examples/sample_report.docx
Development
pip install -e ".[test]"
pytest
Tests render each component, re-open the result with python-docx, and assert the document structure (table dimensions, shading XML, text content, embedded images).
License
Apache-2.0. See LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file docxkit-0.1.0.tar.gz.
File metadata
- Download URL: docxkit-0.1.0.tar.gz
- Upload date:
- Size: 25.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9e5d69f76a0a46af82a587ca344cecb572eea057a26c536ed5a37241ba36ec7e
|
|
| MD5 |
961d55afa7fa46d7e59e2267865d7a58
|
|
| BLAKE2b-256 |
5584d81b5f1ec0049449189cf3e23dc11b07659a8c06d1e55347ac5583080c62
|
Provenance
The following attestation bundles were made for docxkit-0.1.0.tar.gz:
Publisher:
publish.yml on blockhaven-ai/docxkit
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
docxkit-0.1.0.tar.gz -
Subject digest:
9e5d69f76a0a46af82a587ca344cecb572eea057a26c536ed5a37241ba36ec7e - Sigstore transparency entry: 1807521331
- Sigstore integration time:
-
Permalink:
blockhaven-ai/docxkit@880c76b1c72ab1426614082438c32f1fc8c71cef -
Branch / Tag:
refs/heads/main - Owner: https://github.com/blockhaven-ai
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@880c76b1c72ab1426614082438c32f1fc8c71cef -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file docxkit-0.1.0-py3-none-any.whl.
File metadata
- Download URL: docxkit-0.1.0-py3-none-any.whl
- Upload date:
- Size: 25.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
57c339ef1077fe498f10502d44b02e873573fb476855e960364a4eebc35c249e
|
|
| MD5 |
3c3c35a320b323264d6b8e9bc1433b32
|
|
| BLAKE2b-256 |
865ff32658c3756be1f7326730268a290d895541ca4ad8cb66ec99b95451cb90
|
Provenance
The following attestation bundles were made for docxkit-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on blockhaven-ai/docxkit
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
docxkit-0.1.0-py3-none-any.whl -
Subject digest:
57c339ef1077fe498f10502d44b02e873573fb476855e960364a4eebc35c249e - Sigstore transparency entry: 1807521353
- Sigstore integration time:
-
Permalink:
blockhaven-ai/docxkit@880c76b1c72ab1426614082438c32f1fc8c71cef -
Branch / Tag:
refs/heads/main - Owner: https://github.com/blockhaven-ai
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@880c76b1c72ab1426614082438c32f1fc8c71cef -
Trigger Event:
workflow_dispatch
-
Statement type: