Skip to content

feat(event_handler): add support for externalDocs attribute in OpenAPI schema #6945

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions aws_lambda_powertools/event_handler/api_gateway.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
)
from aws_lambda_powertools.event_handler.openapi.models import (
Contact,
ExternalDocumentation,
License,
OpenAPI,
SecurityScheme,
Expand Down Expand Up @@ -1714,6 +1715,7 @@ def get_openapi_schema(
license_info: License | None = None,
security_schemes: dict[str, SecurityScheme] | None = None,
security: list[dict[str, list[str]]] | None = None,
external_documentation: ExternalDocumentation | None = None,
openapi_extensions: dict[str, Any] | None = None,
) -> OpenAPI:
"""
Expand Down Expand Up @@ -1745,6 +1747,8 @@ def get_openapi_schema(
A declaration of the security schemes available to be used in the specification.
security: list[dict[str, list[str]]], optional
A declaration of which security mechanisms are applied globally across the API.
external_documentation: ExternalDocumentation, optional
Additional external documentation for the API.
openapi_extensions: Dict[str, Any], optional
Additional OpenAPI extensions as a dictionary.

Expand Down Expand Up @@ -1775,6 +1779,7 @@ def get_openapi_schema(
license_info = license_info or self.openapi_config.license_info
security_schemes = security_schemes or self.openapi_config.security_schemes
security = security or self.openapi_config.security
external_documentation = external_documentation or self.openapi_config.external_documentation
openapi_extensions = openapi_extensions or self.openapi_config.openapi_extensions

from pydantic.json_schema import GenerateJsonSchema
Expand Down Expand Up @@ -1814,6 +1819,9 @@ def get_openapi_schema(
**openapi_extensions,
}

if external_documentation:
output["externalDocs"] = external_documentation

components: dict[str, dict[str, Any]] = {}
paths: dict[str, dict[str, Any]] = {}
operation_ids: set[str] = set()
Expand Down Expand Up @@ -1921,6 +1929,7 @@ def get_openapi_json_schema(
license_info: License | None = None,
security_schemes: dict[str, SecurityScheme] | None = None,
security: list[dict[str, list[str]]] | None = None,
external_documentation: ExternalDocumentation | None = None,
openapi_extensions: dict[str, Any] | None = None,
) -> str:
"""
Expand Down Expand Up @@ -1952,6 +1961,8 @@ def get_openapi_json_schema(
A declaration of the security schemes available to be used in the specification.
security: list[dict[str, list[str]]], optional
A declaration of which security mechanisms are applied globally across the API.
external_documentation: ExternalDocumentation, optional
Additional external documentation for the API.
openapi_extensions: Dict[str, Any], optional
Additional OpenAPI extensions as a dictionary.

Expand All @@ -1977,6 +1988,7 @@ def get_openapi_json_schema(
license_info=license_info,
security_schemes=security_schemes,
security=security,
external_documentation=external_documentation,
openapi_extensions=openapi_extensions,
),
by_alias=True,
Expand All @@ -1998,6 +2010,7 @@ def configure_openapi(
license_info: License | None = None,
security_schemes: dict[str, SecurityScheme] | None = None,
security: list[dict[str, list[str]]] | None = None,
external_documentation: ExternalDocumentation | None = None,
openapi_extensions: dict[str, Any] | None = None,
):
"""Configure OpenAPI specification settings for the API.
Expand Down Expand Up @@ -2031,6 +2044,8 @@ def configure_openapi(
A declaration of the security schemes available to be used in the specification.
security: list[dict[str, list[str]]], optional
A declaration of which security mechanisms are applied globally across the API.
external_documentation: ExternalDocumentation, optional
A link to external documentation for the API.
openapi_extensions: Dict[str, Any], optional
Additional OpenAPI extensions as a dictionary.

Expand Down Expand Up @@ -2064,6 +2079,7 @@ def configure_openapi(
license_info=license_info,
security_schemes=security_schemes,
security=security,
external_documentation=external_documentation,
openapi_extensions=openapi_extensions,
)

Expand All @@ -2088,6 +2104,7 @@ def enable_swagger(
security: list[dict[str, list[str]]] | None = None,
oauth2_config: OAuth2Config | None = None,
persist_authorization: bool = False,
external_documentation: ExternalDocumentation | None = None,
openapi_extensions: dict[str, Any] | None = None,
):
"""
Expand Down Expand Up @@ -2131,6 +2148,8 @@ def enable_swagger(
The OAuth2 configuration for the Swagger UI.
persist_authorization: bool, optional
Whether to persist authorization data on browser close/refresh.
external_documentation: ExternalDocumentation, optional
A link to external documentation for the API.
openapi_extensions: dict[str, Any], optional
Additional OpenAPI extensions as a dictionary.
"""
Expand Down Expand Up @@ -2183,6 +2202,7 @@ def swagger_handler():
license_info=license_info,
security_schemes=security_schemes,
security=security,
external_documentation=external_documentation,
openapi_extensions=openapi_extensions,
)

Expand Down
4 changes: 4 additions & 0 deletions aws_lambda_powertools/event_handler/openapi/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
if TYPE_CHECKING:
from aws_lambda_powertools.event_handler.openapi.models import (
Contact,
ExternalDocumentation,
License,
SecurityScheme,
Server,
Expand Down Expand Up @@ -51,6 +52,8 @@ class OpenAPIConfig:
A declaration of the security schemes available to be used in the specification.
security: list[dict[str, list[str]]], optional
A declaration of which security mechanisms are applied globally across the API.
external_documentation: ExternalDocumentation, optional
A link to external documentation for the API.
openapi_extensions: Dict[str, Any], optional
Additional OpenAPI extensions as a dictionary.

Expand All @@ -77,4 +80,5 @@ class OpenAPIConfig:
license_info: License | None = None
security_schemes: dict[str, SecurityScheme] | None = None
security: list[dict[str, list[str]]] | None = None
external_documentation: ExternalDocumentation | None = None
openapi_extensions: dict[str, Any] | None = None
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from __future__ import annotations

from aws_lambda_powertools.event_handler.api_gateway import APIGatewayRestResolver
from aws_lambda_powertools.event_handler.openapi.models import ExternalDocumentation


def test_openapi_schema_no_external_documentation():
app = APIGatewayRestResolver()

schema = app.get_openapi_schema(title="Hello API", version="1.0.0")
assert not schema.externalDocs


def test_openapi_schema_external_documentation():
app = APIGatewayRestResolver()

schema = app.get_openapi_schema(
title="Hello API",
version="1.0.0",
external_documentation=ExternalDocumentation(
description="Find out more about this API",
url="https://example.org/docs",
),
)

assert schema.externalDocs
assert schema.externalDocs.description == "Find out more about this API"
assert str(schema.externalDocs.url) == "https://example.org/docs"
Loading