Skip to content

Commit ed8d188

Browse files
authored
Merge branch 'develop' into docs/idempotency-guarantees
2 parents f548f56 + 46fe028 commit ed8d188

File tree

19 files changed

+222
-54
lines changed

19 files changed

+222
-54
lines changed

.github/workflows/publish_v2_layer.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -117,14 +117,14 @@ jobs:
117117
pip install --require-hashes -r requirements.txt
118118
119119
- name: Set up QEMU
120-
uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v2.0.0
120+
uses: docker/setup-qemu-action@5927c834f5b4fdf503fca6f4c7eccda82949e1ee # v2.0.0
121121
with:
122122
platforms: arm64
123123
# NOTE: we need QEMU to build Layer against a different architecture (e.g., ARM)
124124

125125
- name: Set up Docker Buildx
126126
id: builder
127-
uses: docker/setup-buildx-action@d70bba72b1f3fd22344832f00baa16ece964efeb # v3.3.0
127+
uses: docker/setup-buildx-action@4fd812986e6c8c2a69e18311145f9371337f27d4 # v3.4.0
128128
with:
129129
install: true
130130
driver: docker

.github/workflows/quality_check.yml

+1
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ jobs:
7777
- name: Upload coverage to Codecov
7878
uses: codecov/codecov-action@e28ff129e5465c2c0dcc6f003fc735cb6ae0c673 # 4.5.0
7979
with:
80+
token: ${{ secrets.CODECOV_TOKEN }}
8081
file: ./coverage.xml
8182
env_vars: PYTHON
8283
name: aws-lambda-powertools-python-codecov

CHANGELOG.md

+21-2
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,35 @@
44
<a name="unreleased"></a>
55
# Unreleased
66

7+
## Bug Fixes
8+
9+
* **event_handler:** convert null body to empty string in ALBResolver to avoid HTTP 502 ([#4683](https://github.com/aws-powertools/powertools-lambda-python/issues/4683))
10+
* **event_handler:** custom serializer recursive values when using data validation ([#4664](https://github.com/aws-powertools/powertools-lambda-python/issues/4664))
11+
712
## Maintenance
813

14+
* Add token to codecov action ([#4682](https://github.com/aws-powertools/powertools-lambda-python/issues/4682))
15+
* **ci:** new pre-release 2.40.2a1 ([#4669](https://github.com/aws-powertools/powertools-lambda-python/issues/4669))
16+
* **ci:** new pre-release 2.40.2a3 ([#4688](https://github.com/aws-powertools/powertools-lambda-python/issues/4688))
917
* **ci:** new pre-release 2.40.2a0 ([#4665](https://github.com/aws-powertools/powertools-lambda-python/issues/4665))
18+
* **ci:** new pre-release 2.40.2a2 ([#4679](https://github.com/aws-powertools/powertools-lambda-python/issues/4679))
19+
* **deps:** bump github.com/aws/aws-sdk-go-v2/config from 1.27.23 to 1.27.24 in /layer/scripts/layer-balancer in the layer-balancer group ([#4684](https://github.com/aws-powertools/powertools-lambda-python/issues/4684))
20+
* **deps:** bump docker/setup-qemu-action from 3.0.0 to 3.1.0 ([#4685](https://github.com/aws-powertools/powertools-lambda-python/issues/4685))
21+
* **deps:** bump zgosalvez/github-actions-ensure-sha-pinned-actions from 3.0.9 to 3.0.10 ([#4678](https://github.com/aws-powertools/powertools-lambda-python/issues/4678))
1022
* **deps:** bump the layer-balancer group in /layer/scripts/layer-balancer with 3 updates ([#4659](https://github.com/aws-powertools/powertools-lambda-python/issues/4659))
23+
* **deps-dev:** bump aws-cdk from 2.147.2 to 2.147.3 ([#4672](https://github.com/aws-powertools/powertools-lambda-python/issues/4672))
24+
* **deps-dev:** bump cdklabs-generative-ai-cdk-constructs from 0.1.198 to 0.1.199 ([#4668](https://github.com/aws-powertools/powertools-lambda-python/issues/4668))
1125
* **deps-dev:** bump aws-cdk-aws-lambda-python-alpha from 2.147.1a0 to 2.147.2a0 ([#4667](https://github.com/aws-powertools/powertools-lambda-python/issues/4667))
26+
* **deps-dev:** bump aws-cdk-lib from 2.147.2 to 2.147.3 ([#4674](https://github.com/aws-powertools/powertools-lambda-python/issues/4674))
27+
* **deps-dev:** bump mkdocs-material from 9.5.27 to 9.5.28 ([#4676](https://github.com/aws-powertools/powertools-lambda-python/issues/4676))
28+
* **deps-dev:** bump cfn-lint from 1.4.2 to 1.5.0 ([#4675](https://github.com/aws-powertools/powertools-lambda-python/issues/4675))
29+
* **deps-dev:** bump cfn-lint from 1.4.1 to 1.4.2 ([#4660](https://github.com/aws-powertools/powertools-lambda-python/issues/4660))
1230
* **deps-dev:** bump aws-cdk-lib from 2.147.1 to 2.147.2 ([#4661](https://github.com/aws-powertools/powertools-lambda-python/issues/4661))
31+
* **deps-dev:** bump cdklabs-generative-ai-cdk-constructs from 0.1.199 to 0.1.200 ([#4677](https://github.com/aws-powertools/powertools-lambda-python/issues/4677))
1332
* **deps-dev:** bump aws-cdk from 2.147.1 to 2.147.2 ([#4657](https://github.com/aws-powertools/powertools-lambda-python/issues/4657))
1433
* **deps-dev:** bump ruff from 0.4.10 to 0.5.0 ([#4644](https://github.com/aws-powertools/powertools-lambda-python/issues/4644))
15-
* **deps-dev:** bump cdklabs-generative-ai-cdk-constructs from 0.1.198 to 0.1.199 ([#4668](https://github.com/aws-powertools/powertools-lambda-python/issues/4668))
16-
* **deps-dev:** bump cfn-lint from 1.4.1 to 1.4.2 ([#4660](https://github.com/aws-powertools/powertools-lambda-python/issues/4660))
34+
* **deps-dev:** bump mypy-boto3-s3 from 1.34.120 to 1.34.138 in the boto-typing group ([#4673](https://github.com/aws-powertools/powertools-lambda-python/issues/4673))
35+
* **deps-dev:** bump cdklabs-generative-ai-cdk-constructs from 0.1.200 to 0.1.201 ([#4687](https://github.com/aws-powertools/powertools-lambda-python/issues/4687))
1736

1837

1938
<a name="v2.40.1"></a>

aws_lambda_powertools/event_handler/api_gateway.py

+23
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
cast,
3131
)
3232

33+
from typing_extensions import override
34+
3335
from aws_lambda_powertools.event_handler import content_types
3436
from aws_lambda_powertools.event_handler.exceptions import NotFoundError, ServiceError
3537
from aws_lambda_powertools.event_handler.openapi.constants import DEFAULT_API_VERSION, DEFAULT_OPENAPI_VERSION
@@ -2652,3 +2654,24 @@ def __init__(
26522654
def _get_base_path(self) -> str:
26532655
# ALB doesn't have a stage variable, so we just return an empty string
26542656
return ""
2657+
2658+
@override
2659+
def _to_response(self, result: Union[Dict, Tuple, Response]) -> Response:
2660+
"""Convert the route's result to a Response
2661+
2662+
ALB requires a non-null body otherwise it converts as HTTP 5xx
2663+
2664+
3 main result types are supported:
2665+
2666+
- Dict[str, Any]: Rest api response with just the Dict to json stringify and content-type is set to
2667+
application/json
2668+
- Tuple[dict, int]: Same dict handling as above but with the option of including a status code
2669+
- Response: returned as is, and allows for more flexibility
2670+
"""
2671+
2672+
# NOTE: Minor override for early return on Response with null body for ALB
2673+
if isinstance(result, Response) and result.body is None:
2674+
logger.debug("ALB doesn't allow None responses; converting to empty string")
2675+
result.body = ""
2676+
2677+
return super()._to_response(result)
+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
"""Exposes version constant to avoid circular dependencies."""
22

3-
VERSION = "2.40.2a1"
3+
VERSION = "2.40.2a4"

docs/core/event_handler/api_gateway.md

+46-16
Original file line numberDiff line numberDiff line change
@@ -51,15 +51,45 @@ This is the sample infrastructure for API Gateway and Lambda Function URLs we ar
5151

5252
### Event Resolvers
5353

54-
Before you decorate your functions to handle a given path and HTTP method(s), you need to initialize a resolver.
54+
Before you decorate your functions to handle a given path and HTTP method(s), you need to initialize a resolver. A resolver will handle request resolution, including [one or more routers](#split-routes-with-router), and give you access to the current event via typed properties.
5555

56-
A resolver will handle request resolution, including [one or more routers](#split-routes-with-router), and give you access to the current event via typed properties.
56+
By default, we will use `APIGatewayRestResolver` throughout the documentation. You can use any of the following:
5757

58-
For resolvers, we provide: `APIGatewayRestResolver`, `APIGatewayHttpResolver`, `ALBResolver`, `LambdaFunctionUrlResolver`, and `VPCLatticeResolver`. From here on, we will default to `APIGatewayRestResolver` across examples.
58+
| Resolver | AWS service |
59+
| ------------------------------------------------------- | -------------------------------------- |
60+
| **[`APIGatewayRestResolver`](#api-gateway-rest-api)** | Amazon API Gateway REST API |
61+
| **[`APIGatewayHttpResolver`](#api-gateway-http-api)** | Amazon API Gateway HTTP API |
62+
| **[`ALBResolver`](#application-load-balancer)** | Amazon Application Load Balancer (ALB) |
63+
| **[`LambdaFunctionUrlResolver`](#lambda-function-url)** | AWS Lambda Function URL |
64+
| **[`VPCLatticeResolver`](#vpc-lattice)** | Amazon VPC Lattice |
5965

60-
???+ info "Auto-serialization"
61-
We serialize `Dict` responses as JSON, trim whitespace for compact responses, set content-type to `application/json`, and
62-
return a 200 OK HTTP status. You can optionally set a different HTTP status code as the second argument of the tuple:
66+
#### Response auto-serialization
67+
68+
> Want full control of the response, headers and status code? [Read about `Response` object here](#fine-grained-responses).
69+
70+
For your convenience, we automatically perform these if you return a dictionary response:
71+
72+
1. Auto-serialize `dictionary` responses to JSON and trim it
73+
2. Include the response under each resolver's equivalent of a `body`
74+
3. Set `Content-Type` to `application/json`
75+
4. Set `status_code` to 200 (OK)
76+
77+
=== "getting_started_resolvers_response_serialization.py"
78+
79+
```python hl_lines="9"
80+
--8<-- "examples/event_handler_rest/src/getting_started_resolvers_response_serialization.py"
81+
```
82+
83+
1. This dictionary will be serialized, trimmed, and included under the `body` key
84+
85+
=== "getting_started_resolvers_response_serialization_output.json"
86+
87+
```json hl_lines="8"
88+
--8<-- "examples/event_handler_rest/src/getting_started_resolvers_response_serialization_output.json"
89+
```
90+
91+
??? info "Coming from Flask? We also support tuple response"
92+
You can optionally set a different HTTP status code as the second argument of the tuple.
6393

6494
```python hl_lines="15 16"
6595
--8<-- "examples/event_handler_rest/src/getting_started_return_tuple.py"
@@ -462,16 +492,16 @@ In the following example, we use a new `Header` OpenAPI type to add [one out of
462492

463493
With data validation enabled, we natively support serializing the following data types to JSON:
464494

465-
| Data type | Serialized type |
466-
| -------------------------------------------------------------------- | -------------------------------------------------------------------------------- |
467-
| **Pydantic models** | `dict` |
468-
| **Python Dataclasses** | `dict` |
469-
| **Enum** | Enum values |
470-
| **Datetime** | Datetime ISO format string |
471-
| **Decimal** | `int` if no exponent, or `float` |
472-
| **Path** | `str` |
473-
| **UUID** | `str` |
474-
| **Set** | `list` |
495+
| Data type | Serialized type |
496+
| -------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
497+
| **Pydantic models** | `dict` |
498+
| **Python Dataclasses** | `dict` |
499+
| **Enum** | Enum values |
500+
| **Datetime** | Datetime ISO format string |
501+
| **Decimal** | `int` if no exponent, or `float` |
502+
| **Path** | `str` |
503+
| **UUID** | `str` |
504+
| **Set** | `list` |
475505
| **Python primitives** _(dict, string, sequences, numbers, booleans)_ | [Python's default JSON serializable types](https://docs.python.org/3/library/json.html#encoders-and-decoders){target="_blank" rel="nofollow"} |
476506

477507
???+ info "See [custom serializer section](#custom-serializer) for bringing your own."
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
from aws_lambda_powertools.event_handler import APIGatewayRestResolver
2+
from aws_lambda_powertools.utilities.typing.lambda_context import LambdaContext
3+
4+
app = APIGatewayRestResolver()
5+
6+
7+
@app.get("/ping")
8+
def ping():
9+
return {"message": "pong"} # (1)!
10+
11+
12+
def lambda_handler(event: dict, context: LambdaContext) -> dict:
13+
return app.resolve(event, context)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"statusCode": 200,
3+
"multiValueHeaders": {
4+
"Content-Type": [
5+
"application/json"
6+
]
7+
},
8+
"body": "{'message':'pong'}",
9+
"isBase64Encoded": false
10+
}

layer/scripts/layer-balancer/go.mod

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,23 @@ go 1.18
44

55
require (
66
github.com/aws/aws-sdk-go-v2 v1.30.1
7-
github.com/aws/aws-sdk-go-v2/config v1.27.23
7+
github.com/aws/aws-sdk-go-v2/config v1.27.24
88
github.com/aws/aws-sdk-go-v2/service/lambda v1.56.1
99
golang.org/x/exp v0.0.0-20230321023759-10a507213a29
1010
golang.org/x/sync v0.7.0
1111
)
1212

1313
require (
1414
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.3 // indirect
15-
github.com/aws/aws-sdk-go-v2/credentials v1.17.23 // indirect
15+
github.com/aws/aws-sdk-go-v2/credentials v1.17.24 // indirect
1616
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.9 // indirect
1717
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.13 // indirect
1818
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.13 // indirect
1919
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 // indirect
2020
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.3 // indirect
2121
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.15 // indirect
2222
github.com/aws/aws-sdk-go-v2/service/sso v1.22.1 // indirect
23-
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.1 // indirect
23+
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.2 // indirect
2424
github.com/aws/aws-sdk-go-v2/service/sts v1.30.1 // indirect
2525
github.com/aws/smithy-go v1.20.3 // indirect
2626
github.com/jmespath/go-jmespath v0.4.0 // indirect

layer/scripts/layer-balancer/go.sum

+6-6
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ github.com/aws/aws-sdk-go-v2 v1.30.1 h1:4y/5Dvfrhd1MxRDD77SrfsDaj8kUkkljU7XE83NP
22
github.com/aws/aws-sdk-go-v2 v1.30.1/go.mod h1:nIQjQVp5sfpQcTc9mPSr1B0PaWK5ByX9MOoDadSN4lc=
33
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.3 h1:tW1/Rkad38LA15X4UQtjXZXNKsCgkshC3EbmcUmghTg=
44
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.3/go.mod h1:UbnqO+zjqk3uIt9yCACHJ9IVNhyhOCnYk8yA19SAWrM=
5-
github.com/aws/aws-sdk-go-v2/config v1.27.23 h1:Cr/gJEa9NAS7CDAjbnB7tHYb3aLZI2gVggfmSAasDac=
6-
github.com/aws/aws-sdk-go-v2/config v1.27.23/go.mod h1:WMMYHqLCFu5LH05mFOF5tsq1PGEMfKbu083VKqLCd0o=
7-
github.com/aws/aws-sdk-go-v2/credentials v1.17.23 h1:G1CfmLVoO2TdQ8z9dW+JBc/r8+MqyPQhXCafNZcXVZo=
8-
github.com/aws/aws-sdk-go-v2/credentials v1.17.23/go.mod h1:V/DvSURn6kKgcuKEk4qwSwb/fZ2d++FFARtWSbXnLqY=
5+
github.com/aws/aws-sdk-go-v2/config v1.27.24 h1:NM9XicZ5o1CBU/MZaHwFtimRpWx9ohAUAqkG6AqSqPo=
6+
github.com/aws/aws-sdk-go-v2/config v1.27.24/go.mod h1:aXzi6QJTuQRVVusAO8/NxpdTeTyr/wRcybdDtfUwJSs=
7+
github.com/aws/aws-sdk-go-v2/credentials v1.17.24 h1:YclAsrnb1/GTQNt2nzv+756Iw4mF8AOzcDfweWwwm/M=
8+
github.com/aws/aws-sdk-go-v2/credentials v1.17.24/go.mod h1:Hld7tmnAkoBQdTMNYZGzztzKRdA4fCdn9L83LOoigac=
99
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.9 h1:Aznqksmd6Rfv2HQN9cpqIV/lQRMaIpJkLLaJ1ZI76no=
1010
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.9/go.mod h1:WQr3MY7AxGNxaqAtsDWn+fBxmd4XvLkzeqQ8P1VM0/w=
1111
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.13 h1:5SAoZ4jYpGH4721ZNoS1znQrhOfZinOhc4XuTXx/nVc=
@@ -22,8 +22,8 @@ github.com/aws/aws-sdk-go-v2/service/lambda v1.56.1 h1:d8ff+JrsS+nSjQK1/F8xPgBl/
2222
github.com/aws/aws-sdk-go-v2/service/lambda v1.56.1/go.mod h1:+DUS8jDnu671W48h4+Hl6xnNeRiz+TuycnxGz2RCTGg=
2323
github.com/aws/aws-sdk-go-v2/service/sso v1.22.1 h1:p1GahKIjyMDZtiKoIn0/jAj/TkMzfzndDv5+zi2Mhgc=
2424
github.com/aws/aws-sdk-go-v2/service/sso v1.22.1/go.mod h1:/vWdhoIoYA5hYoPZ6fm7Sv4d8701PiG5VKe8/pPJL60=
25-
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.1 h1:lCEv9f8f+zJ8kcFeAjRZsekLd/x5SAm96Cva+VbUdo8=
26-
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.1/go.mod h1:xyFHA4zGxgYkdD73VeezHt3vSKEG9EmFnGwoKlP00u4=
25+
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.2 h1:ORnrOK0C4WmYV/uYt3koHEWBLYsRDwk2Np+eEoyV4Z0=
26+
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.2/go.mod h1:xyFHA4zGxgYkdD73VeezHt3vSKEG9EmFnGwoKlP00u4=
2727
github.com/aws/aws-sdk-go-v2/service/sts v1.30.1 h1:+woJ607dllHJQtsnJLi52ycuqHMwlW+Wqm2Ppsfp4nQ=
2828
github.com/aws/aws-sdk-go-v2/service/sts v1.30.1/go.mod h1:jiNR3JqT15Dm+QWq2SRgh0x0bCNSRP2L25+CqPNpJlQ=
2929
github.com/aws/smithy-go v1.20.3 h1:ryHwveWzPV5BIof6fyDvor6V3iUL7nTfiTKXHiW05nE=

0 commit comments

Comments
 (0)