Skip to main content

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_figure embeds 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

docxkit-0.1.0.tar.gz (25.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

docxkit-0.1.0-py3-none-any.whl (25.1 kB view details)

Uploaded Python 3

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

Hashes for docxkit-0.1.0.tar.gz
Algorithm Hash digest
SHA256 9e5d69f76a0a46af82a587ca344cecb572eea057a26c536ed5a37241ba36ec7e
MD5 961d55afa7fa46d7e59e2267865d7a58
BLAKE2b-256 5584d81b5f1ec0049449189cf3e23dc11b07659a8c06d1e55347ac5583080c62

See more details on using hashes here.

Provenance

The following attestation bundles were made for docxkit-0.1.0.tar.gz:

Publisher: publish.yml on blockhaven-ai/docxkit

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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

Hashes for docxkit-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 57c339ef1077fe498f10502d44b02e873573fb476855e960364a4eebc35c249e
MD5 3c3c35a320b323264d6b8e9bc1433b32
BLAKE2b-256 865ff32658c3756be1f7326730268a290d895541ca4ad8cb66ec99b95451cb90

See more details on using hashes here.

Provenance

The following attestation bundles were made for docxkit-0.1.0-py3-none-any.whl:

Publisher: publish.yml on blockhaven-ai/docxkit

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page