betty.project.extension.http_api_doc - Betty documentation

Hide navigation sidebar
Hide table of contents sidebar
Skip to content
Back to top
Toggle table of contents sidebar

# Source code for betty.project.extension.http_api_doc

    """Integrate Betty with `Swagger UI <https://swagger.io/tools/swagger-ui>`_."""

    from __future__ import annotations

    from asyncio import to_thread, gather
    from pathlib import Path
    from shutil import copy2
    from typing import TYPE_CHECKING, final

    from typing_extensions import override

    from betty.locale.localizable import _
    from betty.plugin import ShorthandPluginBase
    from betty.project.extension.webpack import Webpack, WebpackEntryPointProvider
    from betty.project.generate import GenerateSiteEvent

    if TYPE_CHECKING:
        from betty.project.extension import Extension
        from betty.event_dispatcher import EventHandlerRegistry
        from betty.plugin import PluginIdentifier
        from collections.abc import Sequence

    async def _generate_swagger_ui(event: GenerateSiteEvent) -> None:
        await gather(
            to_thread(
                copy2,
                event.job_context._webpack_build_directory_path.parent  # type: ignore[attr-defined]
                / "node_modules"
                / "swagger-ui-dist"
                / "swagger-ui.css",
                event.project.configuration.www_directory_path / "css" / "http-api-doc.css",
            ),
            to_thread(
                copy2,
                event.job_context._webpack_build_directory_path.parent  # type: ignore[attr-defined]
                / "node_modules"
                / "swagger-ui-dist"
                / "swagger-ui-bundle.js",
                event.project.configuration.www_directory_path / "js" / "http-api-doc.js",
            ),
        )

    @final
    class HttpApiDoc(ShorthandPluginBase, WebpackEntryPointProvider):
        """
        Provide user-friendly HTTP API documentation.
        """

        _plugin_id = "http-api-doc"
        _plugin_label = _("HTTP API Documentation")
        _plugin_description = _(
            'Display the HTTP API documentation in a user-friendly way using <a href="https://swagger.io/tools/swagger-ui">Swagger UI</a>.'
        )

        @override
        @classmethod
        def depends_on(cls) -> set[PluginIdentifier[Extension]]:
            return {Webpack}

        @override
        def register_event_handlers(self, registry: EventHandlerRegistry) -> None:
            registry.add_handler(GenerateSiteEvent, _generate_swagger_ui)

        @override
        @classmethod
        def assets_directory_path(cls) -> Path:
            return Path(__file__).parent / "assets"

        @override
        @classmethod
        def webpack_entry_point_directory_path(cls) -> Path:
            return Path(__file__).parent / "webpack"

        @override
        def webpack_entry_point_cache_keys(self) -> Sequence[str]:
            return ()