github aws-powertools/powertools-lambda-python v3.29.0

6 hours ago

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()

Docs

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

Docs

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

📜 Documentation updates

🔧 Maintenance

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]

Don't miss a new powertools-lambda-python release

NewReleases is sending notifications on new releases.