# core URL: /api/environment/core/ Section: environment -------------------------------------------------------------------------------- core - Kida window.BENGAL_THEME_DEFAULTS = { appearance: 'light', palette: 'brown-bengal' }; window.Bengal = window.Bengal || {}; window.Bengal.enhanceBaseUrl = '/kida/assets/js/enhancements'; window.Bengal.watchDom = true; window.Bengal.debug = false; window.Bengal.enhanceUrls = { 'toc': '/kida/assets/js/enhancements/toc.632a9783.js', 'docs-nav': '/kida/assets/js/enhancements/docs-nav.57e4b129.js', 'tabs': '/kida/assets/js/enhancements/tabs.aac9e817.js', 'lightbox': '/kida/assets/js/enhancements/lightbox.1ca22aa1.js', 'interactive': '/kida/assets/js/enhancements/interactive.fc077855.js', 'mobile-nav': '/kida/assets/js/enhancements/mobile-nav.d991657f.js', 'action-bar': '/kida/assets/js/enhancements/action-bar.d62417f4.js', 'copy-link': '/kida/assets/js/enhancements/copy-link.7d9a5c29.js', 'data-table': '/kida/assets/js/enhancements/data-table.1f5bc1eb.js', 'lazy-loaders': '/kida/assets/js/enhancements/lazy-loaders.a5c38245.js', 'holo': '/kida/assets/js/enhancements/holo.ee13c841.js', 'link-previews': '/kida/assets/js/enhancements/link-previews.8d906535.js' }; (function () { try { var defaults = window.BENGAL_THEME_DEFAULTS || { appearance: 'system', palette: '' }; var defaultAppearance = defaults.appearance; if (defaultAppearance === 'system') { defaultAppearance = (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) ? 'dark' : 'light'; } var storedTheme = localStorage.getItem('bengal-theme'); var storedPalette = localStorage.getItem('bengal-palette'); var theme = storedTheme ? (storedTheme === 'system' ? defaultAppearance : storedTheme) : defaultAppearance; var palette = storedPalette ?? defaults.palette; document.documentElement.setAttribute('data-theme', theme); if (palette) { document.documentElement.setAttribute('data-palette', palette); } } catch (e) { document.documentElement.setAttribute('data-theme', 'light'); } })(); { "prerender": [ { "where": { "and": [ { "href_matches": "/docs/*" }, { "not": { "selector_matches": "[data-external], [target=_blank], .external" } } ] }, "eagerness": "conservative" } ], "prefetch": [ { "where": { "and": [ { "href_matches": "/*" }, { "not": { "selector_matches": "[data-external], [target=_blank], .external" } } ] }, "eagerness": "conservative" } ] } Skip to main content Magnifying Glass ESC Recent Clear Magnifying Glass No results for "" Start typing to search... ↑↓ Navigate ↵ Open ESC Close Powered by Lunr )彡 DocumentationInfoAboutArrow ClockwiseGet StartedCodeSyntaxTerminalUsageNoteTutorialsStarburstExtendingBookmarkReferenceTroubleshootingReleasesDevGitHubKida API Reference Magnifying Glass Search ⌘K Palette Appearance Chevron Down Mode Monitor System Sun Light Moon Dark Palette Snow Lynx Brown Bengal Silver Bengal Charcoal Bengal Blue Bengal List )彡 Magnifying Glass Search X Close Documentation Caret Down Info About Arrow Clockwise Get Started Code Syntax Terminal Usage Note Tutorials Starburst Extending Bookmark Reference Troubleshooting Releases Dev Caret Down GitHub Kida API Reference Palette Appearance Chevron Down Mode Monitor System Sun Light Moon Dark Palette Snow Lynx Brown Bengal Silver Bengal Charcoal Bengal Blue Bengal Kida API Reference Caret Right Analysis analyzer cache config dependencies landmarks metadata purity roles Caret Right Compiler Caret Right Statements basic control_flow functions special_blocks template_structure variables _protocols coalescing core expressions utils Caret Right Environment core exceptions filters loaders protocols registry tests Caret Right Parser Caret Right Blocks control_flow core functions special_blocks template_structure variables _protocols core errors expressions statements tokens Caret Right Utils html lru_cache workers _types bytecode_cache kida lexer nodes template tstring Kida API ReferenceEnvironment ᗢ Caret Down Link Copy URL External Open LLM text Copy Copy LLM text Share with AI Ask Claude Ask ChatGPT Ask Gemini Ask Copilot Module environment.core Core Environment class for Kida template system. The Environment is the central hub for template configuration, compilation, and caching. It manages loaders, filters, tests, and global variables. Thread-Safety: Immutable configuration after construction Copy-on-write for filters/tests/globals (no locking) LRU caches use atomic pointer swaps Safe for concurrent get_template() and render() calls Example: >>> from kida import Environment, FileSystemLoader >>> env = Environment( ... loader=FileSystemLoader("templates/"), ... autoescape=True, ... ) >>> env.get_template("page.html").render(page=page) 1Class Classes Environment 50 ▼ Central configuration and template management hub. The Environment holds all template engine setti… Central configuration and template management hub. The Environment holds all template engine settings and provides the primary API for loading and rendering templates. It manages three key concerns: Template Loading: Via configurable loaders (filesystem, dict, etc.) Compilation Settings: Autoescape, strict undefined handling Runtime Context: Filters, tests, and global variables Strict Mode: Undefined variables raise UndefinedError instead of returning empty string. Catches typos and missing context variables at render time. >>> env = Environment() >>> env.from_string("{{ typo_var }}").render() UndefinedError: Undefined variable 'typo_var' in <template>:1 >>> env.from_string("{{ optional | default('N/A') }}").render() 'N/A' Caching: Three cache layers for optimal performance: Bytecode cache (disk): Persistent compiled bytecode via marshal. Auto-enabled for FileSystemLoader in `__pycache__/kida/`. Current cold-start gain is modest (~7-8% median in `benchmarks/benchmark_cold_start.py`); most startup time is import cost, so lazy imports or pre-compilation are required for larger improvements. Template cache (memory): Compiled Template objects (keyed by name) Fragment cache (memory): {% cache key %} block outputs >> env.cache_info() {'template': {'size': 5, 'max_size': 400, 'hits': 100, 'misses': 5}, 'fragment': {'size': 12, 'max_size': 1000, 'hits': 50, 'misses': 12}, 'bytecode': {'file_count': 10, 'total_bytes': 45000}} Attributes Name Type Description loader Loader | None Template source provider (FileSystemLoader, DictLoader, etc.) autoescape bool | Callable[[str | None], bool] HTML auto-escaping. True, False, or callable(name) → bool auto_reload bool Check template modification times (default: True) strict_none bool Fail early on None comparisons during sorting (default: False) preserve_ast bool — cache_size int Maximum compiled templates to cache (default: 400) fragment_cache_size int Maximum {% cache %} fragment entries (default: 1000) fragment_ttl float Fragment cache TTL in seconds (default: 300.0) bytecode_cache BytecodeCache | bool | None Persistent bytecode cache configuration: - None (default): Auto-enabled for FileSystemLoader - False: Explicitly disabled - BytecodeCache instance: Custom cache directory _bytecode_cache BytecodeCache | None — block_start str — block_end str — variable_start str — variable_end str — comment_start str — comment_end str — trim_blocks bool — lstrip_blocks bool — fstring_coalescing bool — pure_filters set[str] — globals dict[str, Any] Variables available in all templates (includes Python builtins) Thread-Safety: All operations are safe for concurrent use: - Configuration is immutable after __post_init__ - add_filter(), add_test(), add_global() use copy-on-write - get_template() uses lock-free LRU cache with atomic operations - render() uses only local state (StringBuilder pattern) _filters dict[str, Callable[..., Any]] — _tests dict[str, Callable[..., Any]] — _cache LRUCache[str, Template] — _fragment_cache LRUCache[str, str] — _template_hashes dict[str, str] — _analysis_cache dict[str, Any] — Methods filters 0 FilterRegistry ▼ Get filters as dict-like registry. property def filters(self) -> FilterRegistry Returns FilterRegistry tests 0 FilterRegistry ▼ Get tests as dict-like registry. property def tests(self) -> FilterRegistry Returns FilterRegistry add_filter 2 ▼ Add a filter (copy-on-write). def add_filter(self, name: str, func: Callable[..., Any]) -> None Parameters Name Type Description name — Filter name (used in templates as {{ x | name }}) func — Filter function add_test 2 ▼ Add a test (copy-on-write). def add_test(self, name: str, func: Callable[..., Any]) -> None Parameters Name Type Description name — Test name (used in templates as {% if x is name %}) func — Test function returning bool add_global 2 ▼ Add a global variable (copy-on-write). def add_global(self, name: str, value: Any) -> None Parameters Name Type Description name — Global name (used in templates as {{ name }}) value — Any value (variable, function, etc.) update_filters 1 ▼ Add multiple filters at once (copy-on-write). def update_filters(self, filters: dict[str, Callable[..., Any]]) -> None Parameters Name Type Description filters — Dict mapping filter names to functions update_tests 1 ▼ Add multiple tests at once (copy-on-write). def update_tests(self, tests: dict[str, Callable[..., Any]]) -> None Parameters Name Type Description tests — Dict mapping test names to functions get_template 1 Template ▼ Load and cache a template by name. def get_template(self, name: str) -> Template Parameters Name Type Description name — Template identifier (e.g., "index.html") Returns Template Compiled Template object from_string 2 Template ▼ Compile a template from a string. def from_string(self, source: str, name: str | None = None) -> Template Parameters Name Type Description source — Template source code name — Optional template name for error messages Default: None Returns Template Compiled Template object clear_template_cache 1 ▼ Clear template cache (optional, for external invalidation). Useful when an ext… def clear_template_cache(self, names: list[str] | None = None) -> None Clear template cache (optional, for external invalidation). Useful when an external system (e.g., Bengal) detects template changes and wants to force cache invalidation without waiting for hash check. Parameters Name Type Description names — Specific template names to clear, or None to clear all Default: None render 1 str ▼ Render a template by name with context. Convenience method combining get_templ… def render(self, template_name: str, *args: Any, **kwargs: Any) -> str Render a template by name with context. Convenience method combining get_template() and render(). Parameters Name Type Description template_name — Template identifier (e.g., "index.html") *args: Single dict of context variables (optional) **kwargs: Context variables as keyword arguments Returns str Rendered template as string render_string 1 str ▼ Compile and render a template string. Convenience method combining from_string… def render_string(self, source: str, *args: Any, **kwargs: Any) -> str Compile and render a template string. Convenience method combining from_string() and render(). Parameters Name Type Description source — Template source code *args: Single dict of context variables (optional) **kwargs: Context variables as keyword arguments Returns str Rendered template as string filter 1 Callable[[Callable[..., … ▼ Decorator to register a filter function. def filter(self, name: str | None = None) -> Callable[[Callable[..., Any]], Callable[..., Any]] Parameters Name Type Description name — Filter name (defaults to function name) Default: None Returns Callable[[Callable[..., Any]], Callable[..., Any]] Decorator function test 1 Callable[[Callable[..., … ▼ Decorator to register a test function. def test(self, name: str | None = None) -> Callable[[Callable[..., Any]], Callable[..., Any]] Parameters Name Type Description name — Test name (defaults to function name) Default: None Returns Callable[[Callable[..., Any]], Callable[..., Any]] Decorator function select_autoescape 1 bool ▼ Determine if autoescape should be enabled for a template. def select_autoescape(self, name: str | None) -> bool Parameters Name Type Description name — Template name (may be None for string templates) Returns bool True if autoescape should be enabled clear_cache 1 ▼ Clear all cached templates and fragments. Call this to release memory when tem… def clear_cache(self, include_bytecode: bool = False) -> None Clear all cached templates and fragments. Call this to release memory when templates are no longer needed, or when template files have been modified and need reloading. Parameters Name Type Description include_bytecode — Also clear persistent bytecode cache (default: False) Default: False clear_fragment_cache 0 ▼ Clear only the fragment cache (keep template cache). def clear_fragment_cache(self) -> None clear_bytecode_cache 0 int ▼ Clear persistent bytecode cache. def clear_bytecode_cache(self) -> int Returns int Number of cache files removed. cache_info 0 dict[str, Any] ▼ Return cache statistics. Returns cache statistics for template and fragment ca… def cache_info(self) -> dict[str, Any] Return cache statistics. Returns cache statistics for template and fragment caches. Returns dict[str, Any] Dict with cache statistics including hit/miss rates. Internal Methods 4 ▼ __post_init__ 0 ▼ Initialize derived configuration. def __post_init__(self) -> None _resolve_bytecode_cache 0 BytecodeCache | None ▼ Resolve bytecode cache from configuration. Auto-detection logic: - If byte… def _resolve_bytecode_cache(self) -> BytecodeCache | None Resolve bytecode cache from configuration. Auto-detection logic: If bytecode_cache is False: disabled If bytecode_cache is BytecodeCache: use it If bytecode_cache is None and loader is FileSystemLoader: auto-create cache in first search path's __pycache__/kida/ Returns BytecodeCache | None Resolved BytecodeCache or None if disabled/unavailable. _compile 3 Template ▼ Compile template source to Template object. Uses bytecode cache when configure… def _compile(self, source: str, name: str | None, filename: str | None) -> Template Compile template source to Template object. Uses bytecode cache when configured for fast cold-start. Preserves AST for introspection when self.preserve_ast=True (default). Parameters Name Type Description source — name — filename — Returns Template _is_template_stale 1 bool ▼ Check if a cached template is stale (source changed). Compares current source … def _is_template_stale(self, name: str) -> bool Check if a cached template is stale (source changed). Compares current source hash with cached hash. Returns True if: No cached hash exists (first load) Current source hash differs from cached hash Parameters Name Type Description name — Template identifier Returns bool True if template source changed, False if unchanged Next → environment List © 2026 Kida built in ᓚᘏᗢ { "linkPreviews": { "enabled": true, "hoverDelay": 200, "hideDelay": 150, "showSection": true, "showReadingTime": true, "showWordCount": true, "showDate": true, "showTags": true, "maxTags": 3, "includeSelectors": [".prose"], "excludeSelectors": ["nav", ".toc", ".breadcrumb", ".pagination", ".card", "[class*='-card']", ".tab-nav", "[class*='-widget']", ".child-items", ".content-tiles"], "allowedHosts": [], "allowedSchemes": ["https"], "hostFailureThreshold": 3 } } window.BENGAL_LAZY_ASSETS = { tabulator: '/kida/assets/js/tabulator.min.js', dataTable: '/kida/assets/js/data-table.js', mermaidToolbar: '/kida/assets/js/mermaid-toolbar.9de5abba.js', mermaidTheme: '/kida/assets/js/mermaid-theme.344822c5.js', graphMinimap: '/kida/assets/js/graph-minimap.ff04e939.js', graphContextual: '/kida/assets/js/graph-contextual.355458ba.js' }; window.BENGAL_ICONS = { close: '/kida/assets/icons/close.911d4fe1.svg', enlarge: '/kida/assets/icons/enlarge.652035e5.svg', copy: '/kida/assets/icons/copy.3d56e945.svg', 'download-svg': '/kida/assets/icons/download.04f07e1b.svg', 'download-png': '/kida/assets/icons/image.c34dfd40.svg', 'zoom-in': '/kida/assets/icons/zoom-in.237b4a83.svg', 'zoom-out': '/kida/assets/icons/zoom-out.38857c77.svg', reset: '/kida/assets/icons/reset.d26dba29.svg' }; Arrow Up -------------------------------------------------------------------------------- Metadata: - Word Count: 1949 - Reading Time: 10 minutes