Warning

This document is for an old release of Galaxy. You can alternatively view this page in the latest release if it exists or view the top of the latest release's documentation.

Source code for galaxy.webapps.openapi.utils

"""
Copy of fastapi/openapi/utils.py from https://github.com/fastapi/fastapi/pull/13918
"""

from collections.abc import Sequence
from inspect import signature
from typing import (
    Any,
    Optional,
    Union,
)

from fastapi import routing

try:
    from fastapi._compat import (  # type: ignore[attr-defined]
        get_flat_models_from_fields,
        get_model_name_map,
    )
except ImportError:
    # FastAPI <0.128.4
    get_flat_models_from_fields = None
    from fastapi._compat import get_compat_model_name_map

from fastapi.encoders import jsonable_encoder
from fastapi.openapi.constants import REF_TEMPLATE
from fastapi.openapi.models import OpenAPI
from fastapi.openapi.utils import (
    get_fields_from_routes,
    get_openapi_path,
)
from pydantic.json_schema import GenerateJsonSchema
from starlette.routing import BaseRoute

from ._compat import get_definitions


[docs] def get_openapi( *, title: str, version: str, openapi_version: str = "3.1.0", summary: Optional[str] = None, description: Optional[str] = None, routes: Sequence[BaseRoute], webhooks: Optional[Sequence[BaseRoute]] = None, tags: Optional[list[dict[str, Any]]] = None, servers: Optional[list[dict[str, Union[str, Any]]]] = None, terms_of_service: Optional[str] = None, contact: Optional[dict[str, Union[str, Any]]] = None, license_info: Optional[dict[str, Union[str, Any]]] = None, separate_input_output_schemas: bool = True, external_docs: Optional[dict[str, Any]] = None, schema_generator: Optional[GenerateJsonSchema] = None, ) -> dict[str, Any]: info: dict[str, Any] = {"title": title, "version": version} if summary: info["summary"] = summary if description: info["description"] = description if terms_of_service: info["termsOfService"] = terms_of_service if contact: info["contact"] = contact if license_info: info["license"] = license_info output: dict[str, Any] = {"openapi": openapi_version, "info": info} if servers: output["servers"] = servers components: dict[str, dict[str, Any]] = {} paths: dict[str, dict[str, Any]] = {} webhook_paths: dict[str, dict[str, Any]] = {} operation_ids: set[str] = set() all_fields = get_fields_from_routes(list(routes or []) + list(webhooks or [])) if get_flat_models_from_fields: flat_models = get_flat_models_from_fields(all_fields, known_models=set()) model_name_map = get_model_name_map(flat_models) else: model_name_map = get_compat_model_name_map(all_fields) schema_generator = schema_generator or GenerateJsonSchema(ref_template=REF_TEMPLATE) field_mapping, definitions = get_definitions( fields=all_fields, schema_generator=schema_generator, model_name_map=model_name_map, separate_input_output_schemas=separate_input_output_schemas, ) get_openapi_path_args = {} if "schema_generator" in signature(get_openapi_path).parameters: # FastAPI <0.119.0 get_openapi_path_args["schema_generator"] = schema_generator for route in routes or []: if isinstance(route, routing.APIRoute): result = get_openapi_path( route=route, operation_ids=operation_ids, model_name_map=model_name_map, field_mapping=field_mapping, separate_input_output_schemas=separate_input_output_schemas, **get_openapi_path_args, ) if result: path, security_schemes, path_definitions = result if path: paths.setdefault(route.path_format, {}).update(path) if security_schemes: components.setdefault("securitySchemes", {}).update(security_schemes) if path_definitions: definitions.update(path_definitions) for webhook in webhooks or []: if isinstance(webhook, routing.APIRoute): result = get_openapi_path( route=webhook, operation_ids=operation_ids, model_name_map=model_name_map, field_mapping=field_mapping, separate_input_output_schemas=separate_input_output_schemas, **get_openapi_path_args, ) if result: path, security_schemes, path_definitions = result if path: webhook_paths.setdefault(webhook.path_format, {}).update(path) if security_schemes: components.setdefault("securitySchemes", {}).update(security_schemes) if path_definitions: definitions.update(path_definitions) if definitions: components["schemas"] = {k: definitions[k] for k in sorted(definitions)} if components: output["components"] = components output["paths"] = paths if webhook_paths: output["webhooks"] = webhook_paths if tags: output["tags"] = tags if external_docs: output["externalDocs"] = external_docs return jsonable_encoder(OpenAPI(**output), by_alias=True, exclude_none=True)