Summary
This release brings custom serialization/deserialization to Idempotency, and Middleware support in Event Handler (API Gateway REST/HTTP, ALB, Lambda Function URL, VPC Lattice). Oh didn't I say some bug fixes too? π
π Big welcome to the new contributors: @adriantomas, @aradyaron, @nejcskofic, @waveFrontSet
Idempotency custom serialization
Docs
π Huge thanks to @aradyaron!!
Previously, any function annotated with @idempotent_function
will have its return type as a JSON object - this was challenging for customers using Pydantic, Dataclasses, or any custom types.
You can now use output_serializer
to automatically serialize the return type for Dataclasses or Pydantic, and bring your own serializer/deserializer too!
from aws_lambda_powertools.utilities.idempotency import (
DynamoDBPersistenceLayer,
IdempotencyConfig,
idempotent_function,
)
from aws_lambda_powertools.utilities.idempotency.serialization.pydantic import PydanticSerializer
from aws_lambda_powertools.utilities.parser import BaseModel
from aws_lambda_powertools.utilities.typing import LambdaContext
dynamodb = DynamoDBPersistenceLayer(table_name="IdempotencyTable")
config = IdempotencyConfig(event_key_jmespath="order_id") # see Choosing a payload subset section
class OrderItem(BaseModel):
sku: str
description: str
class Order(BaseModel):
item: OrderItem
order_id: int
class OrderOutput(BaseModel):
order_id: int
@idempotent_function(
data_keyword_argument="order",
config=config,
persistence_store=dynamodb,
output_serializer=PydanticSerializer,
)
# order output is inferred from return type
def process_order(order: Order) -> OrderOutput:
return OrderOutput(order_id=order.order_id)
def lambda_handler(event: dict, context: LambdaContext):
config.register_lambda_context(context) # see Lambda timeouts section
order_item = OrderItem(sku="fake", description="sample")
order = Order(item=order_item, order_id=1)
# `order` parameter must be called as a keyword argument to work
process_order(order=order)
Middleware in Event Handler
Docs
π Huge thanks to @walmsles for the implementation and marvelous illustrations!!
You can now bring your own middleware to run logic before or after requests when using Event Handler.
The goal continues to be having built-in features over middlewares, so you don't have to own boilerplate code. That said, we recognize we can't virtually cover every use case - that's where middleware comes in!
Example using per-route and global middlewares
import middleware_global_middlewares_module
import requests
from aws_lambda_powertools import Logger
from aws_lambda_powertools.event_handler import APIGatewayRestResolver, Response
app = APIGatewayRestResolver()
logger = Logger()
app.use(middlewares=[middleware_global_middlewares_module.log_request_response])
@app.get("/todos", middlewares=[middleware_global_middlewares_module.inject_correlation_id])
def get_todos():
todos: Response = requests.get("https://jsonplaceholder.typicode.com/todos")
todos.raise_for_status()
return {"todos": todos.json()[:10]}
@logger.inject_lambda_context
def lambda_handler(event, context):
return app.resolve(event, context)
Changes
- refactor(batch): type response() method (#3023) by @adriantomas
πNew features and non-breaking changes
- feat(event_handler): add Middleware support for REST Event Handler (#2917) by @walmsles
- feat(idempotency): add support to custom serialization/deserialization on idempotency decorator (#2951) by @aradyaron
π Documentation updates
- feat(event_handler): add Middleware support for REST Event Handler (#2917) by @walmsles
- feat(idempotency): add support to custom serialization/deserialization on idempotency decorator (#2951) by @aradyaron
- chore(deps): bump squidfunk/mkdocs-material from
f4764d1
todd1770c
in /docs (#3044) by @dependabot - chore(deps): bump squidfunk/mkdocs-material from
b1f7f94
tof4764d1
in /docs (#3031) by @dependabot - chore(deps): bump squidfunk/mkdocs-material from
97da15b
tob1f7f94
in /docs (#3021) by @dependabot
π Bug and hot fixes
- fix(parser): change ApproximateCreationDateTime field to datetime in DynamoDBStreamChangedRecordModel (#3049) by @waveFrontSet
- fix(event_handler): expanding safe URI characters to include +$& (#3026) by @nejcskofic
π§ Maintenance
- chore(deps-dev): bump pytest from 7.4.1 to 7.4.2 (#3057) by @dependabot
- chore(deps): bump actions/upload-artifact from 3.1.2 to 3.1.3 (#3053) by @dependabot
- chore(deps): bump the layer-balancer group in /layer/scripts/layer-balancer with 1 update (#3052) by @dependabot
- chore(deps-dev): bump hvac from 1.1.1 to 1.2.0 (#3054) by @dependabot
- chore(deps-dev): bump cfn-lint from 0.79.8 to 0.79.9 (#3046) by @dependabot
- chore(deps): bump actions/checkout from 3.6.0 to 4.0.0 (#3041) by @dependabot
- chore(deps-dev): bump mkdocs-material from 9.2.6 to 9.2.7 (#3043) by @dependabot
- chore(deps-dev): bump pytest from 7.4.0 to 7.4.1 (#3042) by @dependabot
- chore(deps): bump squidfunk/mkdocs-material from
f4764d1
todd1770c
in /docs (#3044) by @dependabot - chore(deps-dev): bump aws-cdk from 2.93.0 to 2.94.0 (#3036) by @dependabot
- chore(deps-dev): bump ruff from 0.0.286 to 0.0.287 (#3035) by @dependabot
- chore(deps-dev): bump cfn-lint from 0.79.7 to 0.79.8 (#3033) by @dependabot
- chore(deps): bump squidfunk/mkdocs-material from
b1f7f94
tof4764d1
in /docs (#3031) by @dependabot - chore(deps-dev): bump mkdocs-material from 9.2.5 to 9.2.6 (#3032) by @dependabot
- chore(deps-dev): bump sentry-sdk from 1.29.2 to 1.30.0 (#3028) by @dependabot
- chore(deps-dev): bump the boto-typing group with 11 updates (#3027) by @dependabot
- chore(deps): bump docker/setup-buildx-action from 2.9.1 to 2.10.0 (#3022) by @dependabot
- chore(deps): bump squidfunk/mkdocs-material from
97da15b
tob1f7f94
in /docs (#3021) by @dependabot - chore(deps-dev): bump the boto-typing group with 1 update (#3013) by @dependabot
- chore(deps-dev): bump ruff from 0.0.285 to 0.0.286 (#3014) by @dependabot
This release was made possible by the following contributors:
@adriantomas, @aradyaron, @dependabot, @dependabot[bot], @github-actions, @github-actions[bot], @nejcskofic, @walmsles and @waveFrontSet