# render_context

URL: /kida/api/render_context/
Section: api
Description: Kida RenderContext — per-render state isolated from user context.

This module implements ContextVar-based render state management, replacing
the internal keys (_template, _line, _include_depth, _cached_blocks,
_cached_stats) that were previously injected into the user's ctx dict.

Benefits:
    - Clean user context (no internal key pollution)
    - No key collision risk (user can use _template as variable)
    - Centralized state management
    - Thread-safe via ContextVar
    - Async-safe (ContextVars propagate to asyncio.to_thread in Python 3.14)

RFC: kida-contextvar-patterns

---

> For a complete page index, fetch /kida/llms.txt.

Open LLM text
(/kida/api/render_context/index.txt)

Share with AI

Ask Claude
(https://claude.ai/new?q=Please%20help%20me%20understand%20this%20documentation%3A%20%2Fkida%2Fapi%2Frender_context%2Findex.txt)

Ask ChatGPT
(https://chatgpt.com/?q=Please%20help%20me%20understand%20this%20documentation%3A%20%2Fkida%2Fapi%2Frender_context%2Findex.txt)

Ask Gemini
(https://gemini.google.com/app?q=Please%20help%20me%20understand%20this%20documentation%3A%20%2Fkida%2Fapi%2Frender_context%2Findex.txt)

Ask Copilot
(https://copilot.microsoft.com/?q=Please%20help%20me%20understand%20this%20documentation%3A%20%2Fkida%2Fapi%2Frender_context%2Findex.txt)

Module

#
`render_context`

Kida RenderContext — per-render state isolated from user context.

This module implements ContextVar-based render state management, replacing
the internal keys (_template, _line, _include_depth, _cached_blocks,
_cached_stats) that were previously injected into the user's ctx dict.

Benefits:

- Clean user context (no internal key pollution)

- No key collision risk (user can use _template as variable)

- Centralized state management

- Thread-safe via ContextVar

- Async-safe (ContextVars propagate to asyncio.to_thread in Python 3.14)

RFC: kida-contextvar-patterns

2Classes7Functions

## Classes

`_NullRenderContext`

1

▼

Lightweight stub used when generated code runs outside a render context.

Silently absorbs `_rc.lin…

Lightweight stub used when generated code runs outside a render context.

Silently absorbs`_rc.line = N`assignments without raising.
Provides safe no-op`component_stack` and `template_name`for
generated def code that pushes/pops component stack frames.

#### Methods

Internal Methods
1

▼

`__init__`

0

▼

`def __init__(self) -> None`

`RenderContext`

29

▼

Per-render state isolated from user context.

Replaces the _template, _line, _include_depth, _cache…

Per-render state isolated from user context.

Replaces the _template, _line, _include_depth, _cached_blocks, and
_cached_stats keys that were previously injected into the user's ctx dict.

Thread Safety:
ContextVars are thread-local by design. Each thread/async task
has its own RenderContext instance.

Async Safety:
ContextVars propagate correctly to asyncio.to_thread() in Python 3.14,
so render_async() works without special handling.

Context Contracts:

- `ctx` (render context): User-provided dict passed to `render(**ctx)`.

```
Framework keys (e.g. ``site``, ``page``) are documented by the framework.
```

- `_meta`: Framework metadata (HTMX, CSRF, etc.). See `get_meta()`.

#### Attributes

Name
Type
Description

`template_name`

`str | None`

Current template name for error messages

`filename`

`str | None`

Source file path for error messages

`source`

`str | None`

—

`line`

`int`

Current line number (updated during render by generated code)

`include_depth`

`int`

Current include/embed depth (DoS protection)

`max_include_depth`

`int`

Maximum allowed include depth

`extends_depth`

`int`

—

`max_extends_depth`

`int`

—

`template_stack`

`list[tuple[str, int]]`

Stack of (template_name, line) for error traces

`component_stack`

`list[tuple[str, int, str]]`

—

`component_call_template`

`str | None`

—

`component_call_line`

`int | None`

—

`cached_blocks`

`dict[str, str]`

Site-scoped block cache (shared across includes)

`cached_block_names`

`frozenset[str]`

Frozenset of cached block names for O(1) lookup

`cache_stats`

`dict[str, int] | None`

Optional dict for cache hit/miss tracking

`declared_definitions`

`frozenset[str]`

—

`import_stack`

`list[str]`

—

`_stacks`

`dict[str, list[str]]`

—

`_providers`

`dict[str, list[Any]]`

—

`_meta`

`dict[str, object]`

—

#### Methods

`get_meta`

2

`object`

▼

Get framework-specific metadata.

Used by frameworks (like Chirp) to pass reque…

`def get_meta(self, key: str, default: object = None) -> object`

Get framework-specific metadata.

Used by frameworks (like Chirp) to pass request context into templates.

Commonly used for:

- HTMX headers: hx_request, hx_target, hx_trigger, hx_boosted

- Security: csrf_token

- User context: current_user, permissions

##### Parameters

Name
Type
Description

`key`
`—`

Metadata key

`default`
`—`

Value to return if key not found

Default:`None`

##### Returns

`object`

Metadata value or default

`set_meta`

2

▼

Set framework-specific metadata.

`def set_meta(self, key: str, value: object) -> None`

##### Parameters

Name
Type
Description

`key`
`—`

Metadata key

`value`
`—`

Metadata value

`provide`

2

▼

Push a value onto the provider stack for *key*.

Used by ``{% provide key = exp…

`def provide(self, key: str, value: Any) -> None`

Push a value onto the provider stack for key.

Used by`{% provide key = expr %}`. Stack-based so nested
provides shadow outer ones for the same key.

##### Parameters

Name
Type
Description

`key`
`—`

`value`
`—`

`unprovide`

1

▼

Pop the most recent value for *key* from the provider stack.

Called in the ``f…

`def unprovide(self, key: str) -> None`

Pop the most recent value for key from the provider stack.

Called in the`finally` block of compiled `{% provide %}`to
guarantee cleanup even when the body raises.

##### Parameters

Name
Type
Description

`key`
`—`

`consume`

2

`Any`

▼

Read the current value for *key* from the nearest provider.

Returns *default* …

`def consume(self, key: str, default: Any = None) -> Any`

Read the current value for key from the nearest provider.

Returns default if no provider is active for key.
Used by the`consume()`template function.

##### Parameters

Name
Type
Description

`key`
`—`

`default`
`—`

Default:`None`

##### Returns

`Any`

`check_include_depth`

1

▼

Check if include depth limit exceeded.

`def check_include_depth(self, template_name: str) -> None`

##### Parameters

Name
Type
Description

`template_name`
`—`

Name of template being included

`check_extends_depth`

1

▼

Check if extends chain depth limit exceeded.

`def check_extends_depth(self, template_name: str) -> None`

##### Parameters

Name
Type
Description

`template_name`
`—`

Name of parent template being extended

`child_context`

2

`RenderContext`

▼

Create child context for include/embed with incremented depth.

Shares cached_b…

`def child_context(self, template_name: str | None = None, *, source: str | None = None) -> RenderContext`

Create child context for include/embed with incremented depth.

Shares cached_blocks, cache_stats, and _meta with parent
(they're document-wide). Child gets a copy of import_stack to avoid
shared mutable state under parallel rendering.

##### Parameters

Name
Type
Description

`template_name`
`—`

Optional override for child template name

Default:`None`

`source`
`—`

Optional template source for error snippets in child

Default:`None`

##### Returns

`RenderContext`

New RenderContext with incremented include_depth and updated stack

`child_context_for_extends`

2

`RenderContext`

▼

Create child context for extends with incremented extends_depth.

Used when ren…

`def child_context_for_extends(self, parent_name: str, *, source: str | None = None) -> RenderContext`

Create child context for extends with incremented extends_depth.

Used when rendering a parent template from {% extends %}.
Shares cached_blocks, cache_stats, etc. Does not increment include_depth.

##### Parameters

Name
Type
Description

`parent_name`
`—`

Name of parent template being extended

`source`
`—`

Optional template source for error snippets in parent

Default:`None`

##### Returns

`RenderContext`

## Functions

`get_render_context`

0

`RenderContext | None`

▼

Get current render context (None if not in render).

`def get_render_context() -> RenderContext | None`

##### Returns

`RenderContext | None`

`get_render_context_required`

0

`RenderContext`

▼

Get current render context, raise if not in render.

Used by generated code for…

`def get_render_context_required() -> RenderContext`

Get current render context, raise if not in render.

Used by generated code for line tracking.

##### Returns

`RenderContext`

`_make_render_context`

8

`RenderContext`

▼

Construct and return a RenderContext from the given parameters.

Shared by rend…

`def _make_render_context(template_name: str | None = None, filename: str | None = None, source: str | None = None, cached_blocks: dict[str, str] | None = None, cache_stats: dict[str, int] | None = None, parent_meta: dict[str, object] | None = None, max_extends_depth: int = 50, max_include_depth: int = 50) -> RenderContext`

Construct and return a RenderContext from the given parameters.

Shared by render_context() and async_render_context(). Does NOT touch
the ContextVar — callers are responsible for set/reset.

##### Parameters

Name
Type
Description

`template_name`
`str | None`

Template name for error messages

Default:`None`

`filename`
`str | None`

Source file path for error messages

Default:`None`

`source`
`str | None`

Template source for runtime error snippets

Default:`None`

`cached_blocks`
`dict[str, str] | None`

Site-scoped block cache

Default:`None`

`cache_stats`
`dict[str, int] | None`

Optional dict for cache hit/miss tracking

Default:`None`

`parent_meta`
`dict[str, object] | None`

Metadata from parent context to inherit (for framework integration)

Default:`None`

`max_extends_depth`
`int`

Maximum extends nesting depth

Default:`50`

`max_include_depth`
`int`

Maximum include nesting depth

Default:`50`

##### Returns

`RenderContext`

`render_context`

8

`Iterator[RenderContext]`

▼

Context manager for render-scoped state.

Creates a new RenderContext and sets …

`def render_context(template_name: str | None = None, filename: str | None = None, source: str | None = None, cached_blocks: dict[str, str] | None = None, cache_stats: dict[str, int] | None = None, parent_meta: dict[str, object] | None = None, max_extends_depth: int = 50, max_include_depth: int = 50) -> Iterator[RenderContext]`

Context manager for render-scoped state.

Creates a new RenderContext and sets it as the current context for
the duration of the with block. Automatically restores the previous
context when exiting.

##### Parameters

Name
Type
Description

`template_name`
`str | None`

Template name for error messages

Default:`None`

`filename`
`str | None`

Source file path for error messages

Default:`None`

`source`
`str | None`

Template source for runtime error snippets

Default:`None`

`cached_blocks`
`dict[str, str] | None`

Site-scoped block cache

Default:`None`

`cache_stats`
`dict[str, int] | None`

Optional dict for cache hit/miss tracking

Default:`None`

`parent_meta`
`dict[str, object] | None`

Metadata from parent context to inherit (for framework integration)

Default:`None`

`max_extends_depth`
`int`

Default:`50`

`max_include_depth`
`int`

Default:`50`

##### Returns

`Iterator[RenderContext]`

`async_render_context`

8

`AsyncIterator[RenderCont…`

▼

Async context manager for render-scoped state.

Identical to render_context() b…

async

`async def async_render_context(template_name: str | None = None, filename: str | None = None, source: str | None = None, cached_blocks: dict[str, str] | None = None, cache_stats: dict[str, int] | None = None, parent_meta: dict[str, object] | None = None, max_extends_depth: int = 50, max_include_depth: int = 50) -> AsyncIterator[RenderContext]`

Async context manager for render-scoped state.

Identical to render_context() but for use with`async with`.
ContextVar reset is synchronous — the async wrapper is structural only.

Part of RFC: rfc-async-rendering.

##### Parameters

Name
Type
Description

`template_name`
`str | None`

Template name for error messages

Default:`None`

`filename`
`str | None`

Source file path for error messages

Default:`None`

`source`
`str | None`

Template source for runtime error snippets

Default:`None`

`cached_blocks`
`dict[str, str] | None`

Site-scoped block cache

Default:`None`

`cache_stats`
`dict[str, int] | None`

Optional dict for cache hit/miss tracking

Default:`None`

`parent_meta`
`dict[str, object] | None`

Metadata from parent context to inherit (for framework integration)

Default:`None`

`max_extends_depth`
`int`

Default:`50`

`max_include_depth`
`int`

Default:`50`

##### Returns

`AsyncIterator[RenderContext]`

`set_render_context`

1

`Token[RenderContext | No…`

▼

Set a RenderContext and return the reset token.

Low-level function for cases w…

`def set_render_context(ctx: RenderContext) -> Token[RenderContext | None]`

Set a RenderContext and return the reset token.

Low-level function for cases where the context manager isn't suitable
(e.g., nested include/embed calls that need to restore context manually).

##### Parameters

Name
Type
Description

`ctx`
`RenderContext`

The RenderContext to set

##### Returns

`Token[RenderContext | None]`

`reset_render_context`

1

`None`

▼

Reset render context using a token from set_render_context.

`def reset_render_context(token: Token[RenderContext | None]) -> None`

##### Parameters

Name
Type
Description

`token`
`Token[RenderContext | None]`

Token returned from set_render_context()
