Summary
We're thrilled to announce native async resolution for the Event Handler. Write async def route handlers, call await app.resolve_async(event, context), and mix sync/async middlewares. Everything runs natively on the event loop.
We also fixed OpenAPI schema generation for Pydantic @computed_field, a deadlock when sync middlewares raised before calling next(), and ALB returning 422 when response body is None.
A huge thanks to @hirenkumar-n-dholariya, @amrabed, and @catarinacps for their contributions!
Async Event Handler with resolve_async()
You can now define async route handlers and resolve them without blocking the event loop.
Even though the Lambda handler itself is sync, you can use asyncio.run(app.resolve_async(event, context)) to fan out multiple I/O calls concurrently with asyncio.gather or call async libraries directly.
import asyncio
from aws_lambda_powertools.event_handler import APIGatewayHttpResolver
from aws_lambda_powertools.utilities.typing import LambdaContext
app = APIGatewayHttpResolver()
async def get_orders(user_id: str) -> list:
...
async def get_profile(user_id: str) -> dict:
...
@app.get("/dashboard/<user_id>")
async def get_dashboard(user_id: str):
orders, profile = await asyncio.gather(
get_orders(user_id),
get_profile(user_id),
)
return {"orders": orders, "profile": profile}
def lambda_handler(event: dict, context: LambdaContext):
return asyncio.run(app.resolve_async(event, context))Sync and async middlewares work together seamlessly. Sync middlewares are bridged to the event loop in a background thread, so you don't need to rewrite existing middleware to adopt async handlers.
OpenAPI computed_field support
Pydantic @computed_field properties now appear in generated OpenAPI schemas. Previously they were excluded because we always used mode="validation" when generating JSON schemas.
from pydantic import BaseModel, computed_field
from aws_lambda_powertools.event_handler import APIGatewayHttpResolver
app = APIGatewayHttpResolver(enable_validation=True)
class Order(BaseModel):
price: float
quantity: int
@computed_field
@property
def total(self) -> float:
return self.price * self.quantity
@app.get("/order")
def get_order() -> Order:
return Order(price=10.0, quantity=3)Last but not least, thanks to @chriselion and @avplab for reporting bugs in our Event Handler resolvers.
Changes
- fix(event_handler): prevent deadlock when async middleware raises before calling next() (#8196) by @leandrodamascena
- fix(event_handler): fix ALB resolver returns when response body is None (#8194) by @leandrodamascena
- feat(openapi): add compute_field support (#8188) by @leandrodamascena
- fix(idempotency): resolve tech debt issues with falsy responses and Redis persistency (#8176) by @hirenkumar-n-dholariya
- fix(parser): type hints should reflect primitive types support (#8175) by @catarinacps
- feat(event_handler): adding resolve async internal (#8170) by @leandrodamascena
- feat: add AsyncMiddlewareFrame support (#8158) by @leandrodamascena
- feat(event-handler): add _registered_api_adapter_async() internal building block (#8157) by @hirenkumar-n-dholariya
- refactor(event_handler): extract async logic to a separated file (#8138) by @leandrodamascena
📜 Documentation updates
- feat(event_handler): adding resolve async public API (#8171) by @leandrodamascena
- chore(deps): bump gitpython from 3.1.44 to 3.1.47 in /docs (#8172) by @dependabot[bot]
- docs: add lambda templates content (#8159) by @amrabed
🔧 Maintenance
- chore: update aws-encryption-sdk allowed versions (#8191) by @leandrodamascena
- chore(deps): update requests requirement from >=2.32.0 to >=2.33.1 in /examples/event_handler_graphql/src (#8189) by @dependabot[bot]
- chore(deps): batch dependency updates (#8184) by @leandrodamascena
- chore(deps-dev): bump gitpython from 3.1.44 to 3.1.47 (#8173) by @dependabot[bot]
- chore(deps): bump gitpython from 3.1.44 to 3.1.47 in /docs (#8172) by @dependabot[bot]
- chore(deps): batch update dependencies (#8168) by @leandrodamascena
This release was made possible by the following contributors:
@amrabed, @catarinacps, @dependabot[bot], @github-actions[bot], @hirenkumar-n-dholariya, @leandrodamascena, dependabot[bot] and github-actions[bot]