reportsmith
A small, dependency-free Python library for building reports programmatically and exporting them to Markdown, a standalone styled HTML document, or (optionally) PDF.
Features
- Fluent builder API with chainable methods and nested sections (
with report.section(...)) - Elements: headings, paragraphs, tables (with alignment and captions), bullet/numbered lists (nestable), code blocks, block quotes, images, horizontal rules, and format-specific raw passthrough
- Inline formatting helpers:
bold(),italic(),code(),link()— render correctly in both formats - Correct escaping everywhere: HTML entities, Markdown table pipes, code fences that widen when the source contains
``` - HTML export ships with a clean embedded stylesheet (light/dark aware) that you can replace with your own CSS
- Optional PDF export (
pip install reportsmith[pdf], via fpdf2): matching styling, PDF bookmarks from sections, clickable links, auto-detected Unicode system fonts - No required dependencies; Python 3.9+
Installation
pip install -e .
Or just copy the reportsmith/ package into your project — it has no dependencies.
Quick start
from reportsmith import Report, bold, link
report = Report("Q3 Sales Report", author="Jane Doe", subtitle="Quarterly summary")
with report.section("Overview") as s:
s.paragraph(["Revenue was ", bold("up 12%"), " quarter over quarter."])
s.table(
["Region", "Revenue"],
[["EMEA", "$1.2M"], ["APAC", "$0.9M"]],
caption="Revenue by region",
align=["left", "right"],
)
with report.section("Next steps") as s:
s.numbered_list([
"Expand APAC sales team",
["Review ", link("pricing proposal", "https://example.com/pricing")],
])
print(report.to_markdown()) # Markdown string
print(report.to_html()) # standalone HTML page
report.save_markdown("report.md")
report.save_html("report.html")
Run python example.py for a fuller demo that writes example_report.md and example_report.html.
Documentation
- User Guide — a walkthrough of every feature with examples: sections, inline formatting, tables, lists, raw passthrough, HTML customization, and escaping behavior.
- API Reference — signatures, parameters, and exceptions for every public class and function (reStructuredText, Sphinx-ready).
The docs are also a buildable Sphinx site:
pip install -e .[docs]
python -m sphinx -b html docs docs/_build/html
Then open docs/_build/html/index.html.
API overview
Report(title, author="", date=None, subtitle="")
date accepts a string, datetime.date, or datetime.datetime; it defaults to today.
Builder methods (all chainable, also available on sections):
| Method | Adds |
|---|---|
section(title) |
Nested section; heading level tracks nesting depth. Usable as a context manager. |
heading(text, level=None) |
Explicit heading (level defaults to the container's depth + 1) |
paragraph(content) |
Paragraph |
quote(content) |
Block quote |
code(source, language="") |
Fenced/<pre> code block |
bullet_list(items) / numbered_list(items) |
List; items may be text or a nested ListElement |
table(headers, rows, caption="", align=None) |
Table; align entries are "left", "center", "right" |
image(src, alt="", title="") |
Image |
horizontal_rule() |
Rule |
raw(content, format="both") |
Verbatim content for "markdown", "html", or "both" |
add(element) |
Any pre-built element |
Anywhere text is accepted you may pass a plain string or a list mixing strings with bold(), italic(), code(), and link(text, href) spans.
Export
report.to_markdown()→ GitHub-flavored Markdown stringreport.to_html(full_document=True, css=None)→ HTML string;full_document=Falsereturns just the body fragment,css=replaces the default stylesheetreport.to_pdf(fonts=None, mono_fonts=None)→ PDF bytes (requires thepdfextra); pass TTF path quadruples to control typefacesreport.save_markdown(path)/report.save_html(path, ...)/report.save_pdf(path, ...)→ write to a file, return thePath
Running tests
The test suite (93 tests, 100% line coverage) lives in tests/:
python -m pytest
With a coverage report (requires pytest-cov):
python -m pytest --cov=reportsmith --cov-report=term-missing
Changelog
See CHANGELOG.md — the format follows Keep a Changelog.
License
MIT
Metadata
Release files for reportsmith 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| reportsmith-0.1.0.tar.gz | 23.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| reportsmith-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 41.1 kB
Release files / reportsmith-0.1.0.tar.gz
| Download URL | reportsmith-0.1.0.tar.gz |
|---|---|
| Size | 23.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c80ea1f0f0520193122a753420747a38064f1237f1caa5de7135797b95002590
|
|
BLAKE2b-256 checksum How to use checksums |
5f6584efcbf479d4be7325d6b9f1daaa268f0b7570eb18168b4557e799d6f921
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.4
|
Release files / reportsmith-0.1.0-py3-none-any.whl
| Download URL | reportsmith-0.1.0-py3-none-any.whl |
|---|---|
| Size | 17.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
4c7e30c14caec088a7c55a2927f11f77e3bedd42a915a41027741635ef583561
|
|
BLAKE2b-256 checksum How to use checksums |
74985b3c35899781773f7158fa5fea3fae44266cd300fc291ed5d05942e2bac8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.4
|