Skip to content

Commit f5f4aec

Browse files
authored
Merge branch 'develop' into feat/add-cloud-watch-alarm-event-data-class
2 parents 71c6c34 + 2acfa7d commit f5f4aec

File tree

15 files changed

+348
-61
lines changed

15 files changed

+348
-61
lines changed

.github/workflows/publish_v2_layer.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ jobs:
258258
artifact_name: ${{ inputs.source_code_artifact_name }}
259259

260260
- name: Download CDK layer artifacts
261-
uses: actions/download-artifact@87c55149d96e628cc2ef7e6fc2aab372015aec85 # v4.1.3
261+
uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4
262262
with:
263263
path: cdk-layer-stack
264264
pattern: cdk-layer-stack-* # merge all Layer artifacts created per region earlier (reusable_deploy_v2_layer_stack.yml; step "Save Layer ARN artifact")

.github/workflows/reusable_deploy_v2_layer_stack.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ jobs:
180180
- name: install deps
181181
run: poetry install
182182
- name: Download artifact
183-
uses: actions/download-artifact@87c55149d96e628cc2ef7e6fc2aab372015aec85 # v4.1.3
183+
uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4
184184
with:
185185
name: ${{ inputs.artefact-name }}
186186
path: layer

.github/workflows/reusable_deploy_v2_sar.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ jobs:
115115
with:
116116
node-version: ${{ env.NODE_VERSION }}
117117
- name: Download artifact
118-
uses: actions/download-artifact@87c55149d96e628cc2ef7e6fc2aab372015aec85 # v4.1.3
118+
uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4
119119
with:
120120
name: ${{ inputs.artefact-name }}
121121
- name: Unzip artefact

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,24 @@
44
<a name="unreleased"></a>
55
# Unreleased
66

7+
## Bug Fixes
8+
9+
* **event_handler:** OpenAPI schema version respects Pydantic version ([#3860](https://github.com/aws-powertools/powertools-lambda-python/issues/3860))
10+
711
## Maintenance
812

13+
* **deps:** bump redis from 5.0.1 to 5.0.2 ([#3867](https://github.com/aws-powertools/powertools-lambda-python/issues/3867))
914
* **deps:** bump codecov/codecov-action from 4.0.2 to 4.1.0 ([#3856](https://github.com/aws-powertools/powertools-lambda-python/issues/3856))
15+
* **deps:** bump actions/download-artifact from 4.1.2 to 4.1.3 ([#3862](https://github.com/aws-powertools/powertools-lambda-python/issues/3862))
16+
* **deps:** bump squidfunk/mkdocs-material from `49d1bfd` to `7be068b` in /docs ([#3872](https://github.com/aws-powertools/powertools-lambda-python/issues/3872))
17+
* **deps:** bump docker/setup-buildx-action from 3.0.0 to 3.1.0 ([#3864](https://github.com/aws-powertools/powertools-lambda-python/issues/3864))
1018
* **deps:** bump squidfunk/mkdocs-material from `43b898a` to `49d1bfd` in /docs ([#3857](https://github.com/aws-powertools/powertools-lambda-python/issues/3857))
19+
* **deps:** bump pypa/gh-action-pypi-publish from 1.8.11 to 1.8.12 ([#3863](https://github.com/aws-powertools/powertools-lambda-python/issues/3863))
20+
* **deps:** bump actions/download-artifact from 4.1.3 to 4.1.4 ([#3875](https://github.com/aws-powertools/powertools-lambda-python/issues/3875))
1121
* **deps-dev:** bump black from 24.1.1 to 24.2.0 ([#3760](https://github.com/aws-powertools/powertools-lambda-python/issues/3760))
22+
* **deps-dev:** bump cfn-lint from 0.85.2 to 0.85.3 ([#3861](https://github.com/aws-powertools/powertools-lambda-python/issues/3861))
23+
* **deps-dev:** bump ruff from 0.2.2 to 0.3.0 ([#3871](https://github.com/aws-powertools/powertools-lambda-python/issues/3871))
24+
* **deps-dev:** bump mkdocs-material from 9.5.11 to 9.5.12 ([#3870](https://github.com/aws-powertools/powertools-lambda-python/issues/3870))
1225

1326

1427
<a name="v2.34.2"></a>

aws_lambda_powertools/event_handler/api_gateway.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1455,10 +1455,25 @@ def get_openapi_schema(
14551455
get_definitions,
14561456
)
14571457
from aws_lambda_powertools.event_handler.openapi.models import OpenAPI, PathItem, Server, Tag
1458+
from aws_lambda_powertools.event_handler.openapi.pydantic_loader import PYDANTIC_V2
14581459
from aws_lambda_powertools.event_handler.openapi.types import (
14591460
COMPONENT_REF_TEMPLATE,
14601461
)
14611462

1463+
# Pydantic V2 has no support for OpenAPI schema 3.0
1464+
if PYDANTIC_V2 and not openapi_version.startswith("3.1"):
1465+
warnings.warn(
1466+
"You are using Pydantic v2, which is incompatible with OpenAPI schema 3.0. Forcing OpenAPI 3.1",
1467+
stacklevel=2,
1468+
)
1469+
openapi_version = "3.1.0"
1470+
elif not PYDANTIC_V2 and not openapi_version.startswith("3.0"):
1471+
warnings.warn(
1472+
"You are using Pydantic v1, which is incompatible with OpenAPI schema 3.1. Forcing OpenAPI 3.0",
1473+
stacklevel=2,
1474+
)
1475+
openapi_version = "3.0.3"
1476+
14621477
# Start with the bare minimum required for a valid OpenAPI schema
14631478
info: Dict[str, Any] = {"title": title, "version": version}
14641479

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
DEFAULT_API_VERSION = "1.0.0"
2-
DEFAULT_OPENAPI_VERSION = "3.0.0"
2+
DEFAULT_OPENAPI_VERSION = "3.0.3"

aws_lambda_powertools/event_handler/openapi/models.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,20 +45,20 @@ class Config:
4545
# https://swagger.io/specification/#info-object
4646
class Info(BaseModel):
4747
title: str
48-
summary: Optional[str] = None
4948
description: Optional[str] = None
5049
termsOfService: Optional[str] = None
5150
contact: Optional[Contact] = None
5251
license: Optional[License] = None # noqa: A003
5352
version: str
5453

5554
if PYDANTIC_V2:
56-
model_config = {"extra": "allow"}
55+
summary: Optional[str] = None
56+
model_config = {"extra": "ignore"}
5757

5858
else:
5959

6060
class Config:
61-
extra = "allow"
61+
extra = "ignore"
6262

6363

6464
# https://swagger.io/specification/#server-variable-object

aws_lambda_powertools/event_handler/openapi/swagger_ui/swagger-ui-bundle.min.js

Lines changed: 12 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

aws_lambda_powertools/event_handler/openapi/swagger_ui/swagger-ui.min.css

Lines changed: 1 addition & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

aws_lambda_powertools/logging/logger.py

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -451,12 +451,12 @@ def decorate(event, context, *args, **kwargs):
451451
def info(
452452
self,
453453
msg: object,
454-
*args,
455-
exc_info=None,
454+
*args: object,
455+
exc_info: logging._ExcInfoType = None,
456456
stack_info: bool = False,
457457
stacklevel: int = 2,
458458
extra: Optional[Mapping[str, object]] = None,
459-
**kwargs,
459+
**kwargs: object,
460460
) -> None:
461461
extra = extra or {}
462462
extra = {**extra, **kwargs}
@@ -473,12 +473,12 @@ def info(
473473
def error(
474474
self,
475475
msg: object,
476-
*args,
477-
exc_info=None,
476+
*args: object,
477+
exc_info: logging._ExcInfoType = None,
478478
stack_info: bool = False,
479479
stacklevel: int = 2,
480480
extra: Optional[Mapping[str, object]] = None,
481-
**kwargs,
481+
**kwargs: object,
482482
) -> None:
483483
extra = extra or {}
484484
extra = {**extra, **kwargs}
@@ -495,12 +495,12 @@ def error(
495495
def exception(
496496
self,
497497
msg: object,
498-
*args,
498+
*args: object,
499499
exc_info: logging._ExcInfoType = True,
500500
stack_info: bool = False,
501501
stacklevel: int = 2,
502502
extra: Optional[Mapping[str, object]] = None,
503-
**kwargs,
503+
**kwargs: object,
504504
) -> None:
505505
extra = extra or {}
506506
extra = {**extra, **kwargs}
@@ -517,12 +517,12 @@ def exception(
517517
def critical(
518518
self,
519519
msg: object,
520-
*args,
521-
exc_info=None,
520+
*args: object,
521+
exc_info: logging._ExcInfoType = None,
522522
stack_info: bool = False,
523523
stacklevel: int = 2,
524524
extra: Optional[Mapping[str, object]] = None,
525-
**kwargs,
525+
**kwargs: object,
526526
) -> None:
527527
extra = extra or {}
528528
extra = {**extra, **kwargs}
@@ -539,12 +539,12 @@ def critical(
539539
def warning(
540540
self,
541541
msg: object,
542-
*args,
543-
exc_info=None,
542+
*args: object,
543+
exc_info: logging._ExcInfoType = None,
544544
stack_info: bool = False,
545545
stacklevel: int = 2,
546546
extra: Optional[Mapping[str, object]] = None,
547-
**kwargs,
547+
**kwargs: object,
548548
) -> None:
549549
extra = extra or {}
550550
extra = {**extra, **kwargs}
@@ -561,12 +561,12 @@ def warning(
561561
def debug(
562562
self,
563563
msg: object,
564-
*args,
565-
exc_info=None,
564+
*args: object,
565+
exc_info: logging._ExcInfoType = None,
566566
stack_info: bool = False,
567567
stacklevel: int = 2,
568568
extra: Optional[Mapping[str, object]] = None,
569-
**kwargs,
569+
**kwargs: object,
570570
) -> None:
571571
extra = extra or {}
572572
extra = {**extra, **kwargs}

docs/core/event_handler/api_gateway.md

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -959,7 +959,10 @@ This will enable full tracebacks errors in the response, print request and respo
959959

960960
### OpenAPI
961961

962-
When you enable [Data Validation](#data-validation), we use a combination of Pydantic Models and [OpenAPI](https://www.openapis.org/){target="_blank"} type annotations to add constraints to your API's parameters.
962+
When you enable [Data Validation](#data-validation), we use a combination of Pydantic Models and [OpenAPI](https://www.openapis.org/){target="_blank" rel="nofollow"} type annotations to add constraints to your API's parameters.
963+
964+
???+ warning "OpenAPI schema version depends on the installed version of Pydantic"
965+
Pydantic v1 generates [valid OpenAPI 3.0.3 schemas](https://docs.pydantic.dev/1.10/usage/schema/){target="_blank" rel="nofollow"}, and Pydantic v2 generates [valid OpenAPI 3.1.0 schemas](https://docs.pydantic.dev/latest/why/#json-schema){target="_blank" rel="nofollow"}.
963966

964967
In OpenAPI documentation tools like [SwaggerUI](#enabling-swaggerui), these annotations become readable descriptions, offering a self-explanatory API interface. This reduces boilerplate code while improving functionality and enabling auto-documentation.
965968

@@ -1042,18 +1045,18 @@ Below is an example configuration for serving Swagger UI from a custom path or C
10421045

10431046
Defining and customizing OpenAPI metadata gives detailed, top-level information about your API. Here's the method to set and tailor this metadata:
10441047

1045-
| Field Name | Type | Description |
1046-
| ------------------ | -------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
1047-
| `title` | `str` | The title for your API. It should be a concise, specific name that can be used to identify the API in documentation or listings. |
1048-
| `version` | `str` | The version of the API you are documenting. This could reflect the release iteration of the API and helps clients understand the evolution of the API. |
1049-
| `openapi_version` | `str` | Specifies the version of the OpenAPI Specification on which your API is based. For most contemporary APIs, the default value would be `3.0.0` or higher. |
1050-
| `summary` | `str` | A short and informative summary that can provide an overview of what the API does. This can be the same as or different from the title but should add context or information. |
1051-
| `description` | `str` | A verbose description that can include Markdown formatting, providing a full explanation of the API's purpose, functionalities, and general usage instructions. |
1052-
| `tags` | `List[str]` | A collection of tags that categorize endpoints for better organization and navigation within the documentation. This can group endpoints by their functionality or other criteria. |
1053-
| `servers` | `List[Server]` | An array of Server objects, which specify the URL to the server and a description for its environment (production, staging, development, etc.), providing connectivity information. |
1054-
| `terms_of_service` | `str` | A URL that points to the terms of service for your API. This could provide legal information and user responsibilities related to the usage of the API. |
1055-
| `contact` | `Contact` | A Contact object containing contact details of the organization or individuals maintaining the API. This may include fields such as name, URL, and email. |
1056-
| `license_info` | `License` | A License object providing the license details for the API, typically including the name of the license and the URL to the full license text. |
1048+
| Field Name | Type | Description |
1049+
| ------------------ | -------------- |------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
1050+
| `title` | `str` | The title for your API. It should be a concise, specific name that can be used to identify the API in documentation or listings. |
1051+
| `version` | `str` | The version of the API you are documenting. This could reflect the release iteration of the API and helps clients understand the evolution of the API. |
1052+
| `openapi_version` | `str` | Specifies the version of the OpenAPI Specification on which your API is based. When using Pydantic v1 it defaults to 3.0.3, and when using Pydantic v2, it defaults to 3.1.0. |
1053+
| `summary` | `str` | A short and informative summary that can provide an overview of what the API does. This can be the same as or different from the title but should add context or information. **Not supported when using Pydantic v1** |
1054+
| `description` | `str` | A verbose description that can include Markdown formatting, providing a full explanation of the API's purpose, functionalities, and general usage instructions. |
1055+
| `tags` | `List[str]` | A collection of tags that categorize endpoints for better organization and navigation within the documentation. This can group endpoints by their functionality or other criteria. |
1056+
| `servers` | `List[Server]` | An array of Server objects, which specify the URL to the server and a description for its environment (production, staging, development, etc.), providing connectivity information. |
1057+
| `terms_of_service` | `str` | A URL that points to the terms of service for your API. This could provide legal information and user responsibilities related to the usage of the API. |
1058+
| `contact` | `Contact` | A Contact object containing contact details of the organization or individuals maintaining the API. This may include fields such as name, URL, and email. |
1059+
| `license_info` | `License` | A License object providing the license details for the API, typically including the name of the license and the URL to the full license text. |
10571060

10581061
Include extra parameters when exporting your OpenAPI specification to apply these customizations:
10591062

tests/functional/event_handler/conftest.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import json
22

3+
import fastjsonschema
34
import pytest
45

56
from tests.functional.utils import load_event
@@ -71,3 +72,45 @@ def gw_event_vpc_lattice():
7172
@pytest.fixture
7273
def gw_event_vpc_lattice_v1():
7374
return load_event("vpcLatticeEvent.json")
75+
76+
77+
@pytest.fixture(scope="session")
78+
def pydanticv1_only():
79+
from pydantic import __version__
80+
81+
version = __version__.split(".")
82+
if version[0] != "1":
83+
pytest.skip("pydanticv1 test only")
84+
85+
86+
@pytest.fixture(scope="session")
87+
def pydanticv2_only():
88+
from pydantic import __version__
89+
90+
version = __version__.split(".")
91+
if version[0] != "2":
92+
pytest.skip("pydanticv2 test only")
93+
94+
95+
@pytest.fixture(scope="session")
96+
def openapi30_schema():
97+
from urllib.request import urlopen
98+
99+
f = urlopen("https://raw.githubusercontent.com/OAI/OpenAPI-Specification/main/schemas/v3.0/schema.json")
100+
data = json.loads(f.read().decode("utf-8"))
101+
return fastjsonschema.compile(
102+
data,
103+
use_formats=False,
104+
)
105+
106+
107+
@pytest.fixture(scope="session")
108+
def openapi31_schema():
109+
from urllib.request import urlopen
110+
111+
f = urlopen("https://raw.githubusercontent.com/OAI/OpenAPI-Specification/main/schemas/v3.1/schema.json")
112+
data = json.loads(f.read().decode("utf-8"))
113+
return fastjsonschema.compile(
114+
data,
115+
use_formats=False,
116+
)

tests/functional/event_handler/test_openapi_encoders.py

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,6 @@
99
from aws_lambda_powertools.event_handler.openapi.encoders import jsonable_encoder
1010

1111

12-
@pytest.fixture
13-
def pydanticv1_only():
14-
from pydantic import __version__
15-
16-
version = __version__.split(".")
17-
if version[0] != "1":
18-
pytest.skip("pydanticv1 test only")
19-
20-
2112
def test_openapi_encode_include():
2213
class User(BaseModel):
2314
name: str

0 commit comments

Comments
 (0)