Source code for genro_asgi.config.asgi_config_renderer

# Copyright 2025 Softwell S.r.l.
# Licensed under the Apache License, Version 2.0

"""AsgiConfigRenderer — object renderer for the server configuration dialect.

Unlike the markup dialects (HTML, SVG) whose render emits a string, this is an
``object`` renderer: a node renders to a ConfigNode carrying its tag, its
already-resolved attributes (the walk resolves ``^pointers`` and data logic)
and its rendered children. The render result is the list of top-level
ConfigNodes, delivered to the server, which configures itself from them.
"""

from __future__ import annotations

from typing import Any

from genro_builders.renderer import RendererBase


[docs] class ConfigNode: """A rendered configuration node: tag, label, resolved attrs, children.""" __slots__ = ("tag", "label", "attrs", "children") def __init__( self, tag: str, label: str, attrs: dict[str, Any], children: list[ConfigNode] ) -> None: self.tag = tag self.label = label self.attrs = attrs self.children = children
[docs] class AsgiConfigRenderer(RendererBase): """Object renderer: a node renders to a ConfigNode with resolved attrs.""" render_type = "object" mode = "asgi"
[docs] def rendered_item( self, node: Any, item: Any, runtime_attrs: dict[str, Any], *, tag: str, **opts: Any, ) -> Any: """Build a ConfigNode from the resolved tag/attrs and the children. ``runtime_attrs`` are resolved by the walk (pointers, data logic); ``item`` is the list of child ConfigNodes when the node has children. """ children = [c for c in item if isinstance(c, ConfigNode)] if isinstance(item, list) else [] attrs = {k: v for k, v in runtime_attrs.items() if not k.startswith("_")} return ConfigNode(tag, node.label, attrs, children)
[docs] def finalize(self, result: Any, target: Any, **_opts: Any) -> Any: """Deliver the list of top-level ConfigNodes to the target. An object dialect does not join fragments into text. ``target`` is the server: it receives the ConfigNodes via ``apply_configuration`` and configures itself. ``target=None`` returns the list as-is. """ nodes = result if isinstance(result, list) else [result] if target is None: return nodes target.apply_configuration(nodes) return None
if __name__ == "__main__": pass