src/genro_asgi/plugins/openapi/plugin.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 """OpenAPIPlugin — per-handler OpenAPI configuration.16 17 Provides explicit control over OpenAPI schema generation for handlers. Use18 this plugin to override automatically guessed HTTP methods or add19 OpenAPI-specific metadata like tags, summary, description, and security.20 21 Accepted config keys (router-level or per-handler):22 - ``enabled``: gate the plugin entirely (default True)23 - ``method``: HTTP method override (e.g. "get", "post", "delete")24 - ``tags``: OpenAPI tags (string or list of strings)25 - ``summary``: summary override for the operation26 - ``description``: description override for the operation27 - ``deprecated``: mark the operation as deprecated (default False)28 - ``security_scheme``: security scheme name (default "BearerAuth")29 - ``security``: explicit security override (list, or [] for public)30 31 Cross-plugin integration (read by ``OpenAPITranslator``):32 - When the auth plugin is active, ``security`` is auto-derived from ``auth_rule``.33 - When the env plugin is active, ``x-requires`` is auto-derived from ``env_requires``.34 35 Unlike the old genro-asgi module, this file does NOT register itself against36 genro-routes at import time (the no-global-state / no-import-side-effect rule):37 registration is an explicit arming act performed by ``PluginMixin.arm_router``.38 """39 40 from __future__ import annotations41 42 from typing import Any43 44 from genro_routes.plugins._base_plugin import BasePlugin, MethodEntry45 46 __all__ = ["OpenAPIPlugin"]47 48 49 class OpenAPIPlugin(BasePlugin):50 """OpenAPI plugin for explicit schema control.51 52 By default HTTP methods are guessed from the signature (GET for scalar53 params, POST for complex types). Use this plugin to override the guessed54 method or add OpenAPI-specific metadata.55 """56 57 plugin_code = "openapi"58 plugin_description = "Provides explicit control over OpenAPI schema generation"59 60 def configure( # type: ignore[override]61 self,62 enabled: bool = True,63 method: str | None = None,64 tags: str | list[str] | None = None,65 summary: str | None = None,66 description: str | None = None,67 deprecated: bool = False,68 security_scheme: str = "BearerAuth",69 security: list | None = None,70 ) -> None:71 """Configure OpenAPI plugin options (storage handled by the wrapper)."""72 73 def entry_metadata(self, router: Any, entry: MethodEntry) -> dict[str, Any]:74 """Provide OpenAPI-specific metadata for a handler."""75 cfg = self.configuration(entry.name)76 metadata: dict[str, Any] = {}77 78 if cfg.get("method"):79 metadata["method"] = cfg["method"]80 if cfg.get("tags"):81 metadata["tags"] = cfg["tags"]82 if cfg.get("summary"):83 metadata["summary"] = cfg["summary"]84 if cfg.get("description"):85 metadata["description"] = cfg["description"]86 if cfg.get("deprecated"):87 metadata["deprecated"] = cfg["deprecated"]88 if cfg.get("security_scheme") and cfg["security_scheme"] != "BearerAuth":89 metadata["security_scheme"] = cfg["security_scheme"]90 if cfg.get("security") is not None:91 metadata["security"] = cfg["security"]92 93 return {"openapi": metadata} if metadata else {}