18
18
19
19
from aws_lambda_powertools .event_handler import content_types
20
20
from 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
+ )
22
27
from aws_lambda_powertools .event_handler .openapi .exceptions import (
23
28
RequestValidationError ,
24
29
ResponseValidationError ,
@@ -1537,6 +1542,7 @@ def __init__(
1537
1542
self .context : dict = {} # early init as customers might add context before event resolution
1538
1543
self .processed_stack_frames = []
1539
1544
self ._response_builder_class = ResponseBuilder [BaseProxyEvent ]
1545
+ self .openapi_config = OpenAPIConfig () # starting an empty dataclass
1540
1546
self ._has_response_validation_error = response_validation_error_http_code is not None
1541
1547
self ._response_validation_error_http_code = self ._validate_response_validation_error_http_code (
1542
1548
response_validation_error_http_code ,
@@ -1580,16 +1586,12 @@ def _validate_response_validation_error_http_code(
1580
1586
msg = f"'{ response_validation_error_http_code } ' must be an integer representing an HTTP status code."
1581
1587
raise ValueError (msg ) from None
1582
1588
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
1588
1590
1589
1591
def get_openapi_schema (
1590
1592
self ,
1591
1593
* ,
1592
- title : str = "Powertools API" ,
1594
+ title : str = DEFAULT_OPENAPI_TITLE ,
1593
1595
version : str = DEFAULT_API_VERSION ,
1594
1596
openapi_version : str = DEFAULT_OPENAPI_VERSION ,
1595
1597
summary : str | None = None ,
@@ -1641,6 +1643,29 @@ def get_openapi_schema(
1641
1643
The OpenAPI schema as a pydantic model.
1642
1644
"""
1643
1645
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
+
1644
1669
from aws_lambda_powertools .event_handler .openapi .compat import (
1645
1670
GenerateJsonSchema ,
1646
1671
get_compat_model_name_map ,
@@ -1739,7 +1764,7 @@ def _get_openapi_servers(servers: list[Server] | None) -> list[Server]:
1739
1764
1740
1765
# If the 'servers' property is not provided or is an empty array,
1741
1766
# 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 = "/" )]
1743
1768
1744
1769
@staticmethod
1745
1770
def _get_openapi_security (
@@ -1771,7 +1796,7 @@ def _determine_openapi_version(openapi_version: str):
1771
1796
def get_openapi_json_schema (
1772
1797
self ,
1773
1798
* ,
1774
- title : str = "Powertools API" ,
1799
+ title : str = DEFAULT_OPENAPI_TITLE ,
1775
1800
version : str = DEFAULT_API_VERSION ,
1776
1801
openapi_version : str = DEFAULT_OPENAPI_VERSION ,
1777
1802
summary : str | None = None ,
@@ -1822,6 +1847,7 @@ def get_openapi_json_schema(
1822
1847
str
1823
1848
The OpenAPI schema as a JSON serializable dict.
1824
1849
"""
1850
+
1825
1851
from aws_lambda_powertools .event_handler .openapi .compat import model_json
1826
1852
1827
1853
return model_json (
@@ -1845,11 +1871,94 @@ def get_openapi_json_schema(
1845
1871
indent = 2 ,
1846
1872
)
1847
1873
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
+
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
+
1848
1957
def enable_swagger (
1849
1958
self ,
1850
1959
* ,
1851
1960
path : str = "/swagger" ,
1852
- title : str = "Powertools for AWS Lambda (Python) API" ,
1961
+ title : str = DEFAULT_OPENAPI_TITLE ,
1853
1962
version : str = DEFAULT_API_VERSION ,
1854
1963
openapi_version : str = DEFAULT_OPENAPI_VERSION ,
1855
1964
summary : str | None = None ,
@@ -1912,6 +2021,7 @@ def enable_swagger(
1912
2021
openapi_extensions: dict[str, Any], optional
1913
2022
Additional OpenAPI extensions as a dictionary.
1914
2023
"""
2024
+
1915
2025
from aws_lambda_powertools .event_handler .openapi .compat import model_json
1916
2026
from aws_lambda_powertools .event_handler .openapi .models import Server
1917
2027
from aws_lambda_powertools .event_handler .openapi .swagger_ui import (
@@ -2156,10 +2266,7 @@ def _get_base_path(self) -> str:
2156
2266
@staticmethod
2157
2267
def _has_debug (debug : bool | None = None ) -> bool :
2158
2268
# 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 ()
2163
2270
2164
2271
@staticmethod
2165
2272
def _compile_regex (rule : str , base_regex : str = _ROUTE_REGEX ):
@@ -2272,7 +2379,7 @@ def _path_starts_with(path: str, prefix: str):
2272
2379
if not isinstance (prefix , str ) or prefix == "" :
2273
2380
return False
2274
2381
2275
- return path .startswith (prefix + " /" )
2382
+ return path .startswith (f" { prefix } /" )
2276
2383
2277
2384
def _handle_not_found (self , method : str , path : str ) -> ResponseBuilder :
2278
2385
"""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]:
2543
2650
if route .dependant .response_extra_models :
2544
2651
responses_from_routes .extend (route .dependant .response_extra_models )
2545
2652
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
+ )
2548
2656
2549
2657
2550
2658
class Router (BaseRouter ):
0 commit comments