1818
1919from aws_lambda_powertools .event_handler import content_types
2020from aws_lambda_powertools .event_handler .exceptions import NotFoundError , ServiceError
21- from aws_lambda_powertools .event_handler .openapi .constants import DEFAULT_API_VERSION , DEFAULT_OPENAPI_VERSION
21+ from aws_lambda_powertools .event_handler .openapi .config import OpenAPIConfig
22+ from aws_lambda_powertools .event_handler .openapi .constants import (
23+ DEFAULT_API_VERSION ,
24+ DEFAULT_OPENAPI_TITLE ,
25+ DEFAULT_OPENAPI_VERSION ,
26+ )
2227from aws_lambda_powertools .event_handler .openapi .exceptions import (
2328 RequestValidationError ,
2429 ResponseValidationError ,
@@ -1537,6 +1542,7 @@ def __init__(
15371542 self .context : dict = {} # early init as customers might add context before event resolution
15381543 self .processed_stack_frames = []
15391544 self ._response_builder_class = ResponseBuilder [BaseProxyEvent ]
1545+ self .openapi_config = OpenAPIConfig () # starting an empty dataclass
15401546 self ._has_response_validation_error = response_validation_error_http_code is not None
15411547 self ._response_validation_error_http_code = self ._validate_response_validation_error_http_code (
15421548 response_validation_error_http_code ,
@@ -1580,16 +1586,12 @@ def _validate_response_validation_error_http_code(
15801586 msg = f"'{ response_validation_error_http_code } ' must be an integer representing an HTTP status code."
15811587 raise ValueError (msg ) from None
15821588
1583- return (
1584- response_validation_error_http_code
1585- if response_validation_error_http_code
1586- else HTTPStatus .UNPROCESSABLE_ENTITY
1587- )
1589+ return response_validation_error_http_code or HTTPStatus .UNPROCESSABLE_ENTITY
15881590
15891591 def get_openapi_schema (
15901592 self ,
15911593 * ,
1592- title : str = "Powertools API" ,
1594+ title : str = DEFAULT_OPENAPI_TITLE ,
15931595 version : str = DEFAULT_API_VERSION ,
15941596 openapi_version : str = DEFAULT_OPENAPI_VERSION ,
15951597 summary : str | None = None ,
@@ -1641,6 +1643,29 @@ def get_openapi_schema(
16411643 The OpenAPI schema as a pydantic model.
16421644 """
16431645
1646+ # DEPRECATION: Will be removed in v4.0.0. Use configure_api() instead.
1647+ # Maintained for backwards compatibility.
1648+ # See: https://github.com/aws-powertools/powertools-lambda-python/issues/6122
1649+ if title == DEFAULT_OPENAPI_TITLE and self .openapi_config .title :
1650+ title = self .openapi_config .title
1651+
1652+ if version == DEFAULT_API_VERSION and self .openapi_config .version :
1653+ version = self .openapi_config .version
1654+
1655+ if openapi_version == DEFAULT_OPENAPI_VERSION and self .openapi_config .openapi_version :
1656+ openapi_version = self .openapi_config .openapi_version
1657+
1658+ summary = summary or self .openapi_config .summary
1659+ description = description or self .openapi_config .description
1660+ tags = tags or self .openapi_config .tags
1661+ servers = servers or self .openapi_config .servers
1662+ terms_of_service = terms_of_service or self .openapi_config .terms_of_service
1663+ contact = contact or self .openapi_config .contact
1664+ license_info = license_info or self .openapi_config .license_info
1665+ security_schemes = security_schemes or self .openapi_config .security_schemes
1666+ security = security or self .openapi_config .security
1667+ openapi_extensions = openapi_extensions or self .openapi_config .openapi_extensions
1668+
16441669 from aws_lambda_powertools .event_handler .openapi .compat import (
16451670 GenerateJsonSchema ,
16461671 get_compat_model_name_map ,
@@ -1739,7 +1764,7 @@ def _get_openapi_servers(servers: list[Server] | None) -> list[Server]:
17391764
17401765 # If the 'servers' property is not provided or is an empty array,
17411766 # the default behavior is to return a Server Object with a URL value of "/".
1742- return servers if servers else [Server (url = "/" )]
1767+ return servers or [Server (url = "/" )]
17431768
17441769 @staticmethod
17451770 def _get_openapi_security (
@@ -1771,7 +1796,7 @@ def _determine_openapi_version(openapi_version: str):
17711796 def get_openapi_json_schema (
17721797 self ,
17731798 * ,
1774- title : str = "Powertools API" ,
1799+ title : str = DEFAULT_OPENAPI_TITLE ,
17751800 version : str = DEFAULT_API_VERSION ,
17761801 openapi_version : str = DEFAULT_OPENAPI_VERSION ,
17771802 summary : str | None = None ,
@@ -1822,6 +1847,7 @@ def get_openapi_json_schema(
18221847 str
18231848 The OpenAPI schema as a JSON serializable dict.
18241849 """
1850+
18251851 from aws_lambda_powertools .event_handler .openapi .compat import model_json
18261852
18271853 return model_json (
@@ -1845,11 +1871,94 @@ def get_openapi_json_schema(
18451871 indent = 2 ,
18461872 )
18471873
1874+ def configure_openapi (
1875+ self ,
1876+ title : str = DEFAULT_OPENAPI_TITLE ,
1877+ version : str = DEFAULT_API_VERSION ,
1878+ openapi_version : str = DEFAULT_OPENAPI_VERSION ,
1879+ summary : str | None = None ,
1880+ description : str | None = None ,
1881+ tags : list [Tag | str ] | None = None ,
1882+ servers : list [Server ] | None = None ,
1883+ terms_of_service : str | None = None ,
1884+ contact : Contact | None = None ,
1885+ license_info : License | None = None ,
1886+ security_schemes : dict [str , SecurityScheme ] | None = None ,
1887+ security : list [dict [str , list [str ]]] | None = None ,
1888+ openapi_extensions : dict [str , Any ] | None = None ,
1889+ ):
1890+ """Configure OpenAPI specification settings for the API.
1891+
1892+ Sets up the OpenAPI documentation configuration that can be later used
1893+ when enabling Swagger UI or generating OpenAPI specifications.
1894+
1895+ Parameters
1896+ ----------
1897+ title: str
1898+ The title of the application.
1899+ version: str
1900+ The version of the OpenAPI document (which is distinct from the OpenAPI Specification version or the API
1901+ openapi_version: str, default = "3.0.0"
1902+ The version of the OpenAPI Specification (which the document uses).
1903+ summary: str, optional
1904+ A short summary of what the application does.
1905+ description: str, optional
1906+ A verbose explanation of the application behavior.
1907+ tags: list[Tag, str], optional
1908+ A list of tags used by the specification with additional metadata.
1909+ servers: list[Server], optional
1910+ An array of Server Objects, which provide connectivity information to a target server.
1911+ terms_of_service: str, optional
1912+ A URL to the Terms of Service for the API. MUST be in the format of a URL.
1913+ contact: Contact, optional
1914+ The contact information for the exposed API.
1915+ license_info: License, optional
1916+ The license information for the exposed API.
1917+ security_schemes: dict[str, SecurityScheme]], optional
1918+ A declaration of the security schemes available to be used in the specification.
1919+ security: list[dict[str, list[str]]], optional
1920+ A declaration of which security mechanisms are applied globally across the API.
1921+ openapi_extensions: Dict[str, Any], optional
1922+ Additional OpenAPI extensions as a dictionary.
1923+
1924+ Example
1925+ --------
1926+ >>> api.configure_openapi(
1927+ ... title="My API",
1928+ ... version="1.0.0",
1929+ ... description="API for managing resources",
1930+ ... contact=Contact(
1931+ ... name="API Support",
1932+ ... email="support@example.com"
1933+ ... )
1934+ ... )
1935+
1936+ See Also
1937+ --------
1938+ enable_swagger : Method to enable Swagger UI using these configurations
1939+ OpenAPIConfig : Data class containing all OpenAPI configuration options
1940+ """
1941+ self .openapi_config = OpenAPIConfig (
1942+ title = title ,
1943+ version = version ,
1944+ openapi_version = openapi_version ,
1945+ summary = summary ,
1946+ description = description ,
1947+ tags = tags ,
1948+ servers = servers ,
1949+ terms_of_service = terms_of_service ,
1950+ contact = contact ,
1951+ license_info = license_info ,
1952+ security_schemes = security_schemes ,
1953+ security = security ,
1954+ openapi_extensions = openapi_extensions ,
1955+ )
1956+
18481957 def enable_swagger (
18491958 self ,
18501959 * ,
18511960 path : str = "/swagger" ,
1852- title : str = "Powertools for AWS Lambda (Python) API" ,
1961+ title : str = DEFAULT_OPENAPI_TITLE ,
18531962 version : str = DEFAULT_API_VERSION ,
18541963 openapi_version : str = DEFAULT_OPENAPI_VERSION ,
18551964 summary : str | None = None ,
@@ -1912,6 +2021,7 @@ def enable_swagger(
19122021 openapi_extensions: dict[str, Any], optional
19132022 Additional OpenAPI extensions as a dictionary.
19142023 """
2024+
19152025 from aws_lambda_powertools .event_handler .openapi .compat import model_json
19162026 from aws_lambda_powertools .event_handler .openapi .models import Server
19172027 from aws_lambda_powertools .event_handler .openapi .swagger_ui import (
@@ -2156,10 +2266,7 @@ def _get_base_path(self) -> str:
21562266 @staticmethod
21572267 def _has_debug (debug : bool | None = None ) -> bool :
21582268 # It might have been explicitly switched off (debug=False)
2159- if debug is not None :
2160- return debug
2161-
2162- return powertools_dev_is_set ()
2269+ return debug if debug is not None else powertools_dev_is_set ()
21632270
21642271 @staticmethod
21652272 def _compile_regex (rule : str , base_regex : str = _ROUTE_REGEX ):
@@ -2272,7 +2379,7 @@ def _path_starts_with(path: str, prefix: str):
22722379 if not isinstance (prefix , str ) or prefix == "" :
22732380 return False
22742381
2275- return path .startswith (prefix + " /" )
2382+ return path .startswith (f" { prefix } /" )
22762383
22772384 def _handle_not_found (self , method : str , path : str ) -> ResponseBuilder :
22782385 """Called when no matching route was found and includes support for the cors preflight response"""
@@ -2543,8 +2650,9 @@ def _get_fields_from_routes(routes: Sequence[Route]) -> list[ModelField]:
25432650 if route .dependant .response_extra_models :
25442651 responses_from_routes .extend (route .dependant .response_extra_models )
25452652
2546- flat_models = list (responses_from_routes + request_fields_from_routes + body_fields_from_routes )
2547- return flat_models
2653+ return list (
2654+ responses_from_routes + request_fields_from_routes + body_fields_from_routes ,
2655+ )
25482656
25492657
25502658class Router (BaseRouter ):
0 commit comments