explorica.reports.renderers

explorica.reports.renderers.html

HTML renderers for Explorica reports and blocks.

This module provides utilities to render Block and Report objects into HTML format. It defines the public rendering entry points used to generate standalone HTML documents or reusable HTML fragments, including optional CSS styling and figure scaling.

The module supports mixed visualization backends (e.g. Matplotlib and Plotly) and handles their normalization and embedding into HTML in a backend-aware manner.

Functions

render_html(data, path, font, **kwargs)

Render a Block or Report object into an HTML document. Acts as the main public entry point for HTML rendering and optionally saves the result to disk.

render_block_html(block, add_css_style, font, **kwargs)

Render a single Block into an HTML fragment. This function is primarily used internally by render_html, but may also be useful when embedding individual blocks into external HTML layouts.

Notes

  • When rendering a single Block, CSS styles are injected locally and apply only to that block.

  • When rendering a Report, CSS styles are injected once at the report level and shared across all contained blocks.

  • Internal helper functions (e.g. CSS generation, placeholder rendering) are not part of the public API and may change without notice.

  • Font handling relies on CSS font-family rules and assumes that the specified fonts are available in the target rendering environment.

Examples

>>> from explorica.reports import Block, BlockConfig
>>> from explorica.reports.renderers.html import render_html
>>> import matplotlib.pyplot as plt
>>> # Render a single block to HTML:
>>> fig, ax = plt.subplots()
>>>
>>> block = Block(BlockConfig(
...     title="Example Block",
...     visualizations=[fig]
... ))
>>>
>>> html = render_html(block)
>>> from explorica.reports import Report
>>> # Render a report with multiple blocks:
>>> report = Report(
...     blocks=[block],
...     title="Example Report",
...     description="Demonstration of HTML rendering"
... )
>>>
>>> html = render_html(report)
>>> # Close all mpl figures after usage
>>> plt.close('all')
explorica.reports.renderers.html.render_block_html(block, add_css_style: bool = False, font: str | Sequence[str] = ('Arial', 'DejaVu Serif', 'DejaVu Sans', 'sans-serif'), **kwargs) str[source]

Render a single Block object into an HTML string.

This function generates a full HTML representation of a Block, including its title, description, metrics, and visualizations. Matplotlib figures are embedded as base64-encoded PNG images, while Plotly figures are rendered as interactive HTML components. Optional CSS can be applied to style the block and its visualizations.

Parameters:
blockBlock

The Block object to render. Its block_config.visualizations should contain a list of VisualizationResult instances.

add_css_stylebool, optional

If True, embed default CSS styling for the block and its visualizations. Defaults to False.

fontstr or Sequence[str], optional

Font family or sequence of font families to be applied to textual elements (title, description, metrics) in the block. If a sequence is provided, the first available font installed on the system will be used. For reliable rendering, it is recommended that the specified fonts are pre-installed on the system where the HTML will be viewed. The final CSS font-family property is constructed from this argument.

Returns:
str

HTML content as a string representing the rendered block.

Other Parameters:
max_widthint, optional, default=800

Maximum width of the outer block in pixels. This value is applied via the max-width CSS property of the block container only if `add_css_style=True`. When disabled, this parameter has no effect on layout. Useful to constrain content width when rendering multiple blocks on the same page.

block_namestr, optional, default=’block’

CSS class name for the outer wrapper div of the block. Used both for styling and for logging purposes to identify the block in logs or debug output.

vis_container_classstr, optional, default=’explorica-visualizations’

CSS class name for the div wrapping the visualizations. This allows external CSS or higher-level wrappers to style all visualizations consistently.

tables_container_classstr, optional, default=’explorica-tables’

CSS class name for the div wrapping all tables in the block. This allows external CSS to style all tables consistently. It is passed to the internal _render_block_html_build_tables function.

mpl_fig_scalefloat, optional, default=80.0

Scaling factor for Matplotlib figures. The figure size in inches (figure.width and figure.height) is multiplied by this factor to determine pixel dimensions for the embedded PNG.

plotly_fig_scalefloat, optional, default=1.0

Scaling factor for Plotly figures. The figure size in pixels (figure.layout.width and figure.layout.height) is multiplied by this factor only if both width and height are explicitly defined. Figures with undefined dimensions are included without scaling.

Notes

  • Plotly figures retain interactivity; scaling is applied only if width and height are explicitly set.

  • Matplotlib figures are rasterized as PNG images and embedded inline.

  • The visualization div uses the vis_container_class class, allowing external styling when multiple blocks are rendered together.

  • Images and iframes are styled with object-fit: contain to maintain aspect ratio while scaling.

Examples

>>> from explorica.reports.core import Block, BlockConfig
>>> from explorica.reports.renderers import render_block_html
>>> import matplotlib.pyplot as plt
>>> import plotly.graph_objects as go
>>> fig, ax = plt.subplots()
>>> plotly_fig = go.Figure(data=go.Bar(y=[2, 3, 1]))
>>> block_config = BlockConfig(
...     title="Example Block",
...     description="Block with visualizations",
...     metrics=[{"name": "Metric A", "value": 42}],
...     visualizations=[fig, plotly_fig]
... )
>>> block = Block(block_config)
>>> html_output = render_block_html(
...     block, add_css_style=True, font=["Arial", "sans-serif"])
>>> # Preview first 200 characters
>>> print(html_output[:200])
explorica.reports.renderers.html.render_html(data, path: str = None, font: str | list[str] = ('Arial', 'DejaVu Serif', 'DejaVu Sans', 'sans-serif'), **kwargs)[source]

Render a Block or Report object into HTML format.

This function generates an HTML representation of either a single Block or a Report containing multiple blocks.

  • When rendering a Block, the output HTML is fully self-contained and includes a CSS <style> block scoped to that block only.

  • When rendering a Report, all contained blocks are rendered sequentially, wrapped in a single report-level container, and a single shared CSS <style> block is applied to the entire report.

If a Report contains no blocks, a placeholder message is inserted into the report body.

Parameters:
dataBlock or Report

The object to render. Can be either a single Block instance or a Report containing multiple blocks.

pathstr, optional

If provided, the rendered HTML will also be saved to this location. Can be either: - a directory path (the file will be saved as “{report_name}.html”), or - a full file path ending with “.html”.

fontstr or Sequence[str], optional

Font family name(s) to be used in the CSS font-family property.

This argument represents system font family names as understood by the browser (e.g. “Arial”, “DejaVu Sans”, “sans-serif”).

It can be provided either as a single font family name or as a sequence of names defining a fallback order. When a sequence is given, it is normalized into a single CSS font-family declaration.

By default, a common cross-platform fallback sequence is used: ("Arial", "DejaVu Serif", "DejaVu Sans", "sans-serif").

Font availability and final selection are handled entirely by the browser.

Returns:
str

HTML content as a string.

Other Parameters:
overwritebool, default=True

Controls whether an existing file at the target path can be overwritten. If False and the target file already exists, a FileExistsError is raised.

max_widthint, default=800

Maximum width of the outer container in pixels. Applied via the max-width CSS property.

mpl_fig_scalefloat, default=80.0

Scaling factor for Matplotlib figures. The figure size in inches (figure.width and figure.height) is multiplied by this factor to determine pixel dimensions for the embedded PNG.

plotly_fig_scalefloat, default=1.0

Scaling factor for Plotly figures. The figure size in pixels (figure.layout.width and figure.layout.height) is multiplied by this factor only if both width and height are explicitly defined. Figures with undefined dimensions are included without scaling.

verbosebool, default=False

Enables info-level logging during the function execution.

debugbool, default=False

Enables debug-level logging during the function execution. Takes precedence over the ‘verbose’ parameter.

vis_container_classstr, default=’visualizations’

CSS class name for the div wrapping the visualizations. This allows external CSS or higher-level wrappers to style all visualizations consistently.

tables_container_classstr, default=’explorica-tables’

CSS class name applied to the <div> wrapping all tables in a block or report. This allows users to apply consistent styling to tables, for example scrollable containers, max-height constraints, or custom CSS rules for all tables. Passed down to internal block rendering functions.

report_namestr, default=’report’

Base name used:

  • as the CSS class for the report container, and

  • as the output file name when path is a directory.

  • as an identifier in log messages emitted during rendering.

Raises:
TypeError

If data is not an instance of Block or Report.

Notes

  • Plotly figures are fully supported in HTML output; interactive elements are preserved.

  • It is assumed that Block().block_config.visualizations contains a list of figures wrapped as VisualizationResult instances. During Block initialization, all figures are automatically normalized into VisualizationResult objects, so downstream rendering or processing functions can safely rely on a uniform interface.

  • CSS injection behavior depends on the input type:

    • For Block, CSS is injected and scoped to that block only.

    • For Report, a single CSS block is injected and shared by all blocks within the report container.

Examples

>>> from explorica.reports.core.block import Block, BlockConfig
>>> from explorica.reports.core.report import Report
>>> from explorica.reports.renderers import render_html
>>> import matplotlib.pyplot as plt
>>> # Minimal Block with Matplotlib visualization
>>> fig, ax = plt.subplots()
>>> block_config = BlockConfig(
...     title="Sample Block",
...     description="A minimal example block",
...     metrics=[{"name": "Metric 1", "value": 42}],
...     visualizations=[fig]
... )
>>> # Single block
>>> block = Block(block_config)
>>> html_output = render_html(block)
>>> print(html_output[:100])
>>> # Report with multiple blocks
>>> report = Report(blocks=[block], title="My Report", description="Example report")
>>> html_output = render_html(report)
>>> print(html_output[:100])
>>> # Optionally save to disk
>>> render_html(block, path="./reports", report_name="my_block")

explorica.reports.renderers.pdf

PDF renderers for Explorica reports.

This module provides functionality for converting Block and Report objects into PDF format using ReportLab as the underlying rendering engine. It exposes both high-level APIs for end-to-end rendering and lower-level utilities for working with individual blocks.

Functions

render_pdf(data, path, font, doc_template_kws, **kwargs)

Render a Block or Report into a PDF byte stream, optionally saving to disk and supporting customization of fonts and page layout.

render_block_pdf(block, mpl_fig_scale, plotly_fig_scale, reportlab_styles, block_name)

Render a single Block into a sequence of ReportLab Flowables, including title, description, metrics, and visualizations.

See Also

explorica.reports.core.Block

Core block abstraction used as the primary rendering unit.

explorica.reports.utils.normalize_visualization

Utility for standardizing visualization objects across backends.

Notes

  • It is assumed that Block.block_config.visualizations contains visualizations normalized into VisualizationResult objects during Block initialization. If this invariant is violated (e.g. by manual mutation or mocking), rendering behavior is undefined.

  • High-level function render_pdf handles both single blocks and full reports.

  • Visualizations that exceed the available page frame are automatically scaled to fit while preserving aspect ratio.

  • Matplotlib figures are rendered directly; Plotly figures are replaced with placeholders to maintain layout consistency.

  • render_block_pdf returns Flowables only; it does not build or save a PDF file.

  • End users should typically use render_pdf unless they need fine-grained control over block-level Flowables.

Examples

>>> import matplotlib.pyplot as plt
>>> from explorica.reports.renderers import render_pdf, render_block_pdf
>>> from explorica.reports.core import Block, BlockConfig
>>> from explorica.reports.core import Report
>>>
>>> # Block-level rendering
>>> fig, ax = plt.subplots()
>>> block_cfg = BlockConfig(
...     title="Example Block",
...     description="A simple block with one plot",
...     metrics=[{"name": "sum", "value": 15}],
...     visualizations=[fig]
... )
>>> block = Block(block_cfg)
>>> flowables = render_block_pdf(block)
>>> isinstance(flowables, list)
True
>>> # End-to-end PDF rendering
>>> pdf_bytes = render_pdf(block)
>>> len(pdf_bytes) > 0
True
>>> # Rendering a full report
>>> blocks = [block, block, block]
>>> report = Report(blocks, title="Example Report", description="Report description")
>>> report_bytes = render_pdf(report, path="./reports")
>>> plt.close("all")
explorica.reports.renderers.pdf.render_block_pdf(block, mpl_fig_scale: float = 80.0, plotly_fig_scale: float = 1.0, reportlab_styles=None, block_name: str = 'block') list[Flowable][source]

Render a single Block object into ReportLab Flowables for PDF generation.

This function converts a Block into a sequence of ReportLab Flowable objects, representing the block’s content including title, description, metrics, and visualizations.

Parameters:
blockBlock

The block to render.

mpl_fig_scalefloat, default=80.0

Scaling factor applied to Matplotlib figure dimensions when converting to PDF. Accounts for figure size being specified in inches.

plotly_fig_scalefloat, default=1.0

Scaling factor applied to Plotly figure placeholders in the PDF.

reportlab_stylesdict or None, optional

Predefined ReportLab styles to use for rendering. If None, styles are obtained via the internal _preprocess_font() helper, which starts from ReportLab’s default StyleSheet1 and applies additional preprocessing, including font registration and the creation of extended styles (e.g. BodyText-Bold). As a result, when reportlab_styles is None, the styles used are not the raw output of getSampleStyleSheet(), but a modified and extended stylesheet expected by the PDF rendering pipeline.

block_namestr, default=’block’

Name of the block used in logging and error messages. It is not used elsewhere in the rendering.

Returns:
list[reportlab.platypus.Flowable]

Sequence of Platypus flowable elements representing the rendered block.

Notes

  • Matplotlib figures are saved directly into the PDF.

  • Plotly figures are replaced by a placeholder using get_empty_plot.

  • This is a lower-level utility function. For end users, the higher-level render_pdf function is the recommended entry point.

  • It is assumed that block.block_config.visualizations contains a list of figures wrapped as VisualizationResult instances. During Block initialization, all figures are automatically normalized into VisualizationResult objects, so downstream rendering or processing functions can safely rely on a uniform interface.

  • This function does not build or save a PDF file.

  • It returns a list of ReportLab Flowable objects intended to be consumed by higher-level rendering utilities such as render_pdf

Examples

>>> from explorica.reports.renderers import render_block_pdf
>>> from explorica.reports.core import Block, BlockConfig
>>> import matplotlib.pyplot as plt
>>> fig, ax = plt.subplots()
>>> block_cfg = BlockConfig(
...     title="Example Block",
...     description="A simple block with one plot",
...     metrics=[{"name": "sum", "value": 15}],
...     visualizations=[fig]
... )
>>> block = Block(block_cfg)
>>> flowables = render_block_pdf(block)
>>> type(flowables)
<class 'list'>
explorica.reports.renderers.pdf.render_pdf(data, path: str = None, font: str = 'DejaVuSans', boldfont: str = 'DejaVuSans-Bold', **kwargs) bytes[source]

Render a Block or Report into PDF format.

This function renders a single Block or a Report (sequence of blocks) into a PDF format. It serves as the main entry point for PDF export functionality in the reports module.

Parameters:
dataBlock or Report

The object to render. Can be a single Block or a Report (sequence of blocks).

pathstr, optional

Directory path or full file path where the PDF report should be saved.

  • If a directory is provided, the report is saved as f"{report_name}.pdf" inside that directory.

  • If a full file path ending with .pdf is provided, the report is saved to that exact location. If None, the rendered PDF is returned as bytes without saving.

fontstr, default=”DejaVuSans”

Font to use for rendering text in the PDF. Supports the following:

  • “DejaVuSans” (default)

  • “DejaVuSerif”

  • path to a custom TTF font file, which will be registered as UserProvidedFont.

boldfontstr, default=”DejaVuSans-Bold”

Font to use for rendering bold text in the PDF. Supports the following:

  • “DejaVuSans-Bold” (default)

  • “DejaVuSerif-Bold”

  • path to a custom TTF font file, which will be registered as UserProvidedBoldFont.

Returns:
bytes

PDF content as bytes.

Other Parameters:
doc_template_kwsdict, optional

Additional keyword arguments to pass to SimpleDocTemplate for customizing PDF layout (e.g., margins, page size).

report_namestr, default=”report”

The base name used when saving the PDF if path is a directory. Also serves as a placeholder name in logs or error messages.

verbosebool, default=False

Enables info-level logging during the function execution.

debugbool, default=False

Enables debug-level logging during the function execution. Takes precedence over the ‘verbose’ parameter.

mpl_fig_scalefloat, default=80.0

Scaling factor applied to Matplotlib figure dimensions when converting to PDF. Accounts for figure size being specified in inches.

plotly_fig_scalefloat, default=1.0

Scaling factor applied to Plotly figure placeholders in the PDF.

Raises:
TypeError

If data is not a Block or Report.

ValueError

If font is not a recognized alias and the specified file path does not exist.

Notes

  • This function provides a unified interface for PDF generation from both individual blocks and eventually from full report sequences.

  • The function always returns the generated PDF content as bytes, even if path is provided for saving.

  • Users can optionally save the generated PDF by providing the path parameter.

  • It is assumed that Block().block_config.visualizations contains a list of figures wrapped as VisualizationResult instances. During Block initialization, all figures are automatically normalized into VisualizationResult objects, so downstream rendering or processing functions can safely rely on a uniform interface.

  • Visualizations are rendered into the PDF within the available page frame. If a visualization exceeds the frame width (taking page size and margins into account), it will be automatically scaled down to fit the frame while preserving its aspect ratio.

  • This behavior applies to all figure-based visualizations (e.g. Matplotlib or Plotly figures) and ensures that content never overflows page boundaries. As a result, the final rendered size of a visualization in the PDF may differ from its original size.

Examples

>>> import matplotlib.pyplot as plt
>>> from explorica.reports.renderers import render_pdf
>>> from explorica.reports.core import Block, BlockConfig, Report
>>>
>>> # Block render usage
>>> fig, ax = plt.subplots()
>>> block_cfg = BlockConfig(
...     title="Example Block",
...     description="A simple block with one plot",
...     metrics=[{"name": "sum", "value": 15}],
...     visualizations=[fig]
... )
>>> block = Block(block_cfg)
>>> # Render PDF as bytes
>>> pdf_bytes = render_pdf(block)
>>> # Render and save to a directory
>>> render_pdf(block, path="./reports", report_name="my_block")
b'...'
>>> # Report render usage
>>> blocks = [Block(block_cfg), Block(block_cfg), Block(block_cfg)]
>>> report = Report(blocks, title = "Example Report",
...                 description = "Description to example report")
>>> report_bytes = render_pdf(report)
>>> # Save report to ./reports/report.pdf
>>> render_pdf(report, path = "./reports")
>>> # Usage with 'doc_template_kws'
>>> from reportlab.lib.pagesizes import A3
>>> report_bytes = render_pdf(report,
...     doc_template_kws = {
...         "pagesize": A3,
...         "rightMargin": 35,
...         "leftMargin": 35,
...         "topMargin": 40,
...         "bottomMargin": 0,
...     }
... )
>>> # Close all mpl figures after usage
>>> plt.close('all')