Module

render_accumulator

Kida RenderAccumulator — opt-in profiling for template rendering.

This module provides accumulated metrics during template rendering:

  • Block render times
  • Macro call counts
  • Include/embed counts
  • Filter usage

Zero overhead when disabled (get_accumulator() returns None).

RFC: kida-contextvar-patterns

Example:

from kida import Environment
from kida.render_accumulator import profiled_render

env = Environment(loader=FileSystemLoader("templates/"))
template = env.get_template("page.html")

# Normal render (no overhead)
html = template.render(page=page)

# Profiled render (opt-in)
with profiled_render() as metrics:
    html = template.render(page=page)

print(metrics.summary())
# {
#   "total_ms": 12.5,
#   "blocks": {
#     "content": {"ms": 8.2, "calls": 1},
#     "nav": {"ms": 2.1, "calls": 1},
#   },
#   "macros": {"render_card": 15, "format_date": 8},
#   "includes": {"partials/sidebar.html": 1},
#   "filters": {"escape": 45, "truncate": 12},
# }

Classes

BlockTiming 3
Timing data for a single block render.

Timing data for a single block render.

Attributes

Name Type Description
name str

Block name

duration_ms float

Total render time in milliseconds

call_count int

Number of times the block was rendered

RenderAccumulator 11
Accumulated metrics during template rendering. Opt-in profiling for debugging slow templates. Zero…

Accumulated metrics during template rendering.

Opt-in profiling for debugging slow templates. Zero overhead when disabled (get_accumulator() returns None).

Attributes

Name Type Description
block_timings dict[str, BlockTiming]

Block name → timing data

macro_calls dict[str, int]

Macro name → call count

include_counts dict[str, int]

Template name → include count

filter_calls dict[str, int]

Filter name → call count

start_time float

Render start timestamp

Methods

total_duration_ms 0 float
Total render duration in milliseconds.
property
def total_duration_ms(self) -> float
Returns
float
record_block 2
Record a block render. If block was already recorded, adds to existing duratio…
def record_block(self, name: str, duration_ms: float) -> None

Record a block render.

If block was already recorded, adds to existing duration and increments call count.

Parameters
Name Type Description
name

Block name

duration_ms

Render duration in milliseconds

record_macro 1
Record a macro invocation.
def record_macro(self, name: str) -> None
Parameters
Name Type Description
name

Macro name (may include template prefix for imports)

record_include 1
Record an include/embed.
def record_include(self, template_name: str) -> None
Parameters
Name Type Description
template_name

Name of included template

record_filter 1
Record a filter usage.
def record_filter(self, name: str) -> None
Parameters
Name Type Description
name

Filter name

summary 0 dict[str, Any]
Get summary of render metrics.
def summary(self) -> dict[str, Any]
Returns
dict[str, Any] Dict with total_ms, blocks, macros, includes, filters

Functions

get_accumulator 0 RenderAccumulator | None
Get current accumulator (None if profiling disabled).
def get_accumulator() -> RenderAccumulator | None
Returns
RenderAccumulator | None
profiled_render 0 Iterator[RenderAccumulat…
Context manager for profiled rendering. Creates a RenderAccumulator and makes …
def profiled_render() -> Iterator[RenderAccumulator]

Context manager for profiled rendering.

Creates a RenderAccumulator and makes it available via get_accumulator() for the duration of the with block. Template code can check for the accumulator and record metrics.

Returns
Iterator[RenderAccumulator]
timed_block 1 Iterator[None]
Time a block render (no-op if profiling disabled). Use this to wrap block rend…
def timed_block(name: str) -> Iterator[None]

Time a block render (no-op if profiling disabled).

Use this to wrap block rendering code. If profiling is not enabled, this is a no-op with minimal overhead.

Parameters
Name Type Description
name str

Block name for recording

Returns
Iterator[None]