Skip to content

src/genro_asgi/plugins/openapi/__init__.py

Source from this local checkout, regenerated when the reader rebuilds. Line links use #L<number>; a GitHub line range opens its first line.

1 # Copyright 2025 Softwell S.r.l.2 #3 # Licensed under the Apache License, Version 2.0 (the "License");4 # you may not use this file except in compliance with the License.5 # You may obtain a copy of the License at6 #7 #     https://www.apache.org/licenses/LICENSE-2.08 #9 # Unless required by applicable law or agreed to in writing, software10 # distributed under the License is distributed on an "AS IS" BASIS,11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.12 # See the License for the specific language governing permissions and13 # limitations under the License.14 15 """OpenAPI dialect for genro-asgi.16 17 genro-routes exposes a dialect-neutral description of each endpoint via18 ``router.nodes()`` — including a per-entry ``result`` block ``{schema,19 media_type}``. This package is the OpenAPI *reader* of that description: it20 owns the ``OpenAPIPlugin`` (per-handler OpenAPI config: method/tags/summary/21 security) and the ``OpenAPITranslator`` (turning ``nodes()`` output into22 OpenAPI paths). It lives here, not in the routing core, because OpenAPI is one23 transport dialect among peers (alongside MCP), not a routing concern.24 25 Importing this package has NO side effect on genro-routes: the plugin is26 registered only when a server arms a router (``PluginMixin.arm_router``).27 """28 29 from __future__ import annotations30 31 from typing import Any32 33 from .plugin import OpenAPIPlugin34 from .translator import OpenAPITranslator35 36 __all__ = ["OpenAPIPlugin", "OpenAPITranslator", "router_openapi"]37 38 39 def router_openapi(40     router: Any,41     *,42     basepath: str | None = None,43     hierarchical: bool = False,44     lazy: bool = False,45     **kwargs: Any,46 ) -> dict[str, Any]:47     """Build the OpenAPI view of a router from its neutral ``nodes()`` output.48 49     genro-routes ships no OpenAPI dialect; this composes the neutral50     description with the local translator.51 52     Args:53         router: A router (anything with ``nodes()``).54         basepath: Optional subtree to start from; paths are made absolute.55         hierarchical: If True, use the ``h_openapi`` (tree-preserving) format.56         lazy: If True, child routers stay as references.57         **kwargs: Filters forwarded to ``nodes()`` (auth_tags, env_capabilities,58             channel_channel, forbidden, pattern, ...).59 60     Returns:61         OpenAPI dict with ``paths`` (and ``$defs`` when nested types exist).62     """63     translate = (64         OpenAPITranslator.translate_h_openapi65         if hierarchical66         else OpenAPITranslator.translate_openapi67     )68     nodes_data = router.nodes(basepath=basepath, lazy=lazy, **kwargs)69     if not nodes_data:70         return {"paths": {}}71     if basepath:72         prefix = "/" + basepath.strip("/")73         return translate(nodes_data, lazy=lazy, path_prefix=prefix)74     return translate(nodes_data, lazy=lazy)