# Copyright 2025 Softwell S.r.l.
# Licensed under the Apache License, Version 2.0
"""AsgiConfigBuilder — builder dialect for genro-asgi server configuration.
The user subclasses AsgiConfigBuilder in a ``config.py`` and overrides
``main(self, root)`` (the recipe) and optionally ``setup(self, data)`` (the
values behind ``^pointers``). The server mounts the builder on a
ConfigurationHandler and renders it: rendering applies the configuration to
the live server (see AsgiConfigRenderer).
Example ``config.py``::
from genro_asgi.config import AsgiConfigBuilder
from myshop.app import Application as Shop
class ServerConfiguration(AsgiConfigBuilder):
def main(self, root):
root.server(host="127.0.0.1", port=8000, reload=True)
root.middleware(cors=True)
apps = root.applications(default="shop")
apps.application(code="shop", app_class=Shop)
root.openapi(title="Demo Shop API", version="1.0.0")
"""
from __future__ import annotations
from typing import Any
from genro_builders.builder import BuilderBase
from .asgi_elements import AsgiConfigElements
from .asgi_config_renderer import AsgiConfigRenderer
[docs]
class AsgiConfigBuilder(BuilderBase, AsgiConfigElements):
"""Server-configuration dialect. Grammar from AsgiConfigElements,
application to the live server from AsgiConfigRenderer."""
_name = "asgiconfig"
_default_render_mode = "asgi"
@property
def renderer_asgi(self) -> AsgiConfigRenderer:
"""Fresh AsgiConfigRenderer bound to this builder."""
return AsgiConfigRenderer(builder=self)
if __name__ == "__main__":
from genro_builders.builder import BuilderHandler
from genro_asgi import OpenApiApplication
class _Demo(AsgiConfigBuilder):
def main(self, root: Any) -> None:
root.server(host="127.0.0.1", port=8000, reload=True)
root.middleware(cors=True)
apps = root.applications()
apps.application(code="api", mount="api", app_class=OpenApiApplication)
root.openapi(title="Demo", version="1.0.0")
builder = _Demo(name="config")
handler = BuilderHandler()
handler.add_builder(builder)
print(builder.render(mode="xml"))