esparto is a simple HTML and PDF document generator for Python. The library takes a fully Pythonic approach to defining documents, allowing iterative building and modification of the page and its contents.

Example Use Cases

  • Automated MI reporting
  • Collating and sharing data visualisations
  • ML model performance and evaluation documents
  • Designing simple web pages

Main Features

  • Lightweight API
  • Jupyter Notebook support
  • Output self-contained HTML and PDF files
  • Responsive layout from Bootstrap
  • No CSS or HTML required
  • Implicit conversion for:
    • Markdown
    • Images
    • Pandas DataFrames
    • Matplotlib
    • Bokeh
    • Plotly


esparto is available from PyPI:

pip install esparto

If PDF output is required, weasyprint must also be installed:

pip install weasyprint





Full documentation and examples are available at

Basic Usage

import esparto as es

# Instantiating a Page
page = es.Page(title="Research")

# Page layout hierarchy:
# Page -> Section -> Row -> Column -> Content

# Add or update content
# Keys are used as titles
page["Introduction"]["Part One"]["Item A"] = "./text/"
page["Introduction"]["Part One"]["Item B"] = "./pictures/image1.jpg"

# Add content without a title
page["Introduction"]["Part One"][""] = "Hello, Wolrd!"

# Replace child at index - useful if no title given
page["Introduction"]["Part One"][-1] = "Hello, World!"

# Set content and return input object
# Useful in Jupyter Notebook as it will be displayed in cell output
page["Methodology"]["Part One"]["Item A"] << "dolor sit amet"
# >>> "dolor sit amet"

# Set content and return new layout
page["Methodology"]["Part Two"]["Item B"] >> "foobar"
# >>> {'Item B': ['Markdown']}

# Show document structure
# >>> {'Research': [{'Introduction': [{'Part One': [{'Item A': ['Markdown']},
#                                                   {'Item B': ['Image']}]}]},
#                   {'Methodology': [{'Part One': [{'Item A': ['Markdown']}]},
#                                    {'Part Two': [{'Item A': ['Markdown']}]}]}]}

# Remove content
del page["Methodology"]["Part One"]["Item A"]
del page.methodology.part_two.item_b

# Access existing content as an attribute
page.introduction.part_one.item_a = "./pictures/image2.jpg"
# >>> {'Part One': [{'Item A': ['Image']},
#                   {'Item B': ['Image']},
#                   {'Column 2': ['Markdown']}]}

# Save the document

Example Output

Iris Report - HTML | PDF

Bokeh and Plotly - HTML | PDF