Aws Lambda Powertools Python Versions Save

A developer toolkit to implement Serverless best practices and increase developer velocity.

v2.33.0

4 months ago

Summary

We are pleased to announce our first security feature: Data Masking. You can now encrypt, decrypt, or irreversibly erase sensitive information to protect data confidentiality.

We also made enhancements to our OpenAPI utility, and fixed some bugs!

⭐ Huge thanks to our new contributor: @maauk

Data masking

Docs

You can now encrypt, decrypt, or irreversibly erase sensitive information to protect data confidentiality.

image

We partnered with the AWS Crypto team to offer a thin layer on top of the AWS Encryption SDK and Amazon KMS, optimized to run on AWS Lambda ephemeral environments.

At launch, Data Masking solves three common use cases, with a fourth one (field encryption) coming.

  1. Selectively erase confidential data. You want to remove sensitive information from one or more fields for a given payload, however nested these fields might be.
  2. Encrypt and decrypt an entire payload. You want to protect the entire payload while ensuring data integrity, and optionally add metadata to each operation for further protection.
  3. Use multiple keys for high availability. You want to use more than one Amazon KMS key to encrypt while allowing decryption with any of the keys used for encryption.

It wouldn't be awesome if we didn't mention that we spent a few months crafting several code snippets, use cases, diagrams, and a simplified terminology to help you digest common industry security practices.

Enough with the talk :) Here's a working code snippet with these use cases combined.

from __future__ import annotations

import os

from aws_lambda_powertools import Logger
from aws_lambda_powertools.utilities.data_masking import DataMasking
from aws_lambda_powertools.utilities.data_masking.provider.kms.aws_encryption_sdk import (
    AWSEncryptionSDKProvider,
)
from aws_lambda_powertools.utilities.typing import LambdaContext

KEY_ONE = os.getenv("KMS_KEY_ARN", "")
KEY_TWO = os.getenv("KMS_KEY_TWO_ARN", "")

logger = Logger()

encryption_provider = AWSEncryptionSDKProvider(keys=[KEY_ONE, KEY_TWO])  # encrypt/decrypt operations
data_masker = DataMasking(provider=encryption_provider)


@logger.inject_lambda_context
def lambda_handler(event: dict, context: LambdaContext) -> dict:
    data: dict = event.get("body", {})

    logger.info("Erasing fields email, address.street, and company_address")

    erased: dict = data_masker.erase(data, fields=["email", "address.street", "company_address"])  # values become '*****'

    # tenant_id being optional metadata that must match in decrypt for further protection
    encrypted: str = data_masker.encrypt(data, tenant_id=event.get("tenant_id", ""))

    decrypted: dict = data_masker.decrypt(data, tenant_id=event.get("tenant_id", ""))

    return erased

⭐⭐ Huge thanks to @seshubaws for the extensive work on this feature!

Header parameter validation in OpenAPI schema

Docs

Our enhanced OpenAPI utility now enables you to seamlessly incorporate headers into your API specifications.

from typing import List

from aws_lambda_powertools.event_handler import APIGatewayRestResolver
from aws_lambda_powertools.event_handler.openapi.params import Header
from aws_lambda_powertools.shared.types import Annotated  
from aws_lambda_powertools.utilities.typing import LambdaContext

app = APIGatewayRestResolver(enable_validation=True)

@app.get("/hello")
def get_hello(header2: Annotated[List[str], Header()], header1: Annotated[str, Header()]):
    print(header2)

def lambda_handler(event: dict, context: LambdaContext) -> dict:
    return app.resolve(event, context)

Changes

  • fix(data-masking): fix and improve e2e tests for DataMasking (#3695) by @leandrodamascena
  • fix(event-handler): strip whitespace from Content-Type headers during OpenAPI schema validation (#3677) by @leandrodamascena

πŸ“œ Documentation updates

  • feat(event_handler): support Header parameter validation in OpenAPI schema (#3687) by @leandrodamascena
  • docs(data-masking): add docs for data masking utility (#3186) by @seshubaws
  • docs(proccess): add versioning and maintenance policy (#3682) by @leandrodamascena
  • chore(deps): bump squidfunk/mkdocs-material from 9aad7af to a4a2029 in /docs (#3679) by @dependabot
  • chore(deps): bump squidfunk/mkdocs-material from 58eef6c to 9aad7af in /docs (#3670) by @dependabot
  • feat(event_handler): add support for multiValueQueryStringParameters in OpenAPI schema (#3667) by @leandrodamascena
  • docs(metrics): fix empty metric warning filter (#3660) by @maauk

πŸ”§ Maintenance

  • chore(deps-dev): bump aws-cdk from 2.124.0 to 2.125.0 (#3693) by @dependabot
  • docs(data-masking): add docs for data masking utility (#3186) by @seshubaws
  • chore(deps-dev): bump ruff from 0.1.14 to 0.1.15 (#3685) by @dependabot
  • chore(deps-dev): bump sentry-sdk from 1.39.2 to 1.40.0 (#3684) by @dependabot
  • chore(deps): bump codecov/codecov-action from 3.1.5 to 3.1.6 (#3683) by @dependabot
  • chore(deps-dev): bump aws-cdk from 2.123.0 to 2.124.0 (#3678) by @dependabot
  • chore(deps): bump squidfunk/mkdocs-material from 9aad7af to a4a2029 in /docs (#3679) by @dependabot
  • chore(deps): bump codecov/codecov-action from 3.1.4 to 3.1.5 (#3674) by @dependabot
  • chore(deps-dev): bump aws-cdk from 2.122.0 to 2.123.0 (#3673) by @dependabot
  • chore(deps): bump squidfunk/mkdocs-material from 58eef6c to 9aad7af in /docs (#3670) by @dependabot
  • chore(deps): bump the layer-balancer group in /layer/scripts/layer-balancer with 1 update (#3665) by @dependabot
  • chore(deps-dev): bump ruff from 0.1.13 to 0.1.14 (#3656) by @dependabot
  • chore(deps): bump pydantic from 1.10.13 to 1.10.14 (#3655) by @dependabot

This release was made possible by the following contributors:

@dependabot, @dependabot[bot], @github-actions, @github-actions[bot], @leandrodamascena, @maauk and @seshubaws

v2.32.0

4 months ago

Summary

We're excited to introduce two significant new features in our Idempotency utility:

  • Support for Redis as an Idempotency persistent storage layer
  • DynamoDB storage layer is now faster and cheaper by leveraging conditional writes

We also made enhancements to our OpenAPI and Event Sources utilities, and fixed some bugs!

⭐ Huge thanks to our new contributors: @sbailliez, @Thomas-McKanna, and @dastra!

Redis as an Idempotency persistent storage layer

Docs

You can now seamlessly switch between DynamoDB and Redis as a persistence storage layer. This allows you to leverage the Idempotency utility in previously unavailable scenarios, such as handling responses over 400kb.

We remain committed to making efforts to introduce new backends, and we would love to hear from you on which backend we should prioritize next!

redis_idempotency2

⭐ ⭐ Huge thanks to @roger-zhangg for your help!

Optimized DynamoDB storage layer with conditional writes

AWS has recently introduced support for ReturnValuesOnConditionCheckFailure, a feature designed to streamline conditional write operations and reducing costs in Amazon DynamoDB. With this enhancement, Powertools for AWS Lambda now optimistically attempts to write items to DynamoDB. If the item already exists, it seamlessly returns it from DynamoDB without requiring an additional operation.

S3 Batch Operations Event Source

Docs

S3 Batch Operations are now supported on the Event Source utility. When using S3 Batch Operations, a Lambda function can be used to execute various operations. For each task, you can choose to either:

A) Return the task as a success (default) B) Return the task as temporarily failed (e.g., due to a timeout when connecting to other services) and enable automatic retries. C) Return the task as permanently failed, resulting in job failure.

This example illustrates how you can return different status based on your specific execution logic.

s3_batch2

OpenAPI response models

Docs

You can now define additional response models within the OpenAPI schema utility, allowing you to leverage existing Pydantic data models and classes.

response

Last but not least, you can now effortlessly download the OpenAPI schema file directly from the SwaggerUI.

Changes

  • chore(ci): Disable Redis e2e until we drop Python 3.7 (#3652) by @leandrodamascena
  • refactor(event_handler): fix BedrockAgentResolver docstring (#3645) by @leandrodamascena
  • feat(event_source): Add support for policyLevel field in CloudWatch Logs event and parser (#3624) by @leandrodamascena
  • fix(event_handler): escape OpenAPI schema on Swagger UI (#3606) by @rubenfonseca

🌟New features and non-breaking changes

  • feat(idempotency): adding redis as idempotency backend (#2567) by @roger-zhangg

πŸ“œ Documentation updates

  • feat(idempotency): leverage new DynamoDB Failed conditional writes behavior with ReturnValuesOnConditionCheckFailure (#3446) by @dastra
  • feat(event_source): Add support for S3 batch operations (#3572) by @sbailliez
  • feat(event_handler): add support for additional response models in OpenAPI schema (#3591) by @rubenfonseca
  • chore(deps): bump squidfunk/mkdocs-material from 2f29d71 to 58eef6c in /docs (#3633) by @dependabot
  • docs(homepage): add banner about Python 3.7 deprecation (#3618) by @leandrodamascena
  • chore(deps): bump jinja2 from 3.1.2 to 3.1.3 in /docs (#3620) by @dependabot
  • feat(idempotency): adding redis as idempotency backend (#2567) by @roger-zhangg
  • chore(deps): bump gitpython from 3.1.37 to 3.1.41 in /docs (#3610) by @dependabot
  • refactor(event-handler): Inject CSS and JS files into SwaggerUI route when no custom CDN is used. (#3562) by @leandrodamascena
  • feat(event_handler): add support to download OpenAPI spec file (#3571) by @Thomas-McKanna
  • docs(i-made-this): added new article on how to create a serverless API with CDK and Powertools (#3605) by @leandrodamascena

πŸ”§ Maintenance

  • chore(deps-dev): bump ruff from 0.1.13 to 0.1.14 (#3656) by @dependabot
  • chore(deps): bump pydantic from 1.10.13 to 1.10.14 (#3655) by @dependabot
  • feat(idempotency): leverage new DynamoDB Failed conditional writes behavior with ReturnValuesOnConditionCheckFailure (#3446) by @dastra
  • chore(deps): bump the layer-balancer group in /layer/scripts/layer-balancer with 1 update (#3649) by @dependabot
  • chore(deps-dev): bump aws-cdk from 2.121.1 to 2.122.0 (#3648) by @dependabot
  • chore(deps): bump the layer-balancer group in /layer/scripts/layer-balancer with 1 update (#3639) by @dependabot
  • chore(deps): bump squidfunk/mkdocs-material from 2f29d71 to 58eef6c in /docs (#3633) by @dependabot
  • chore(deps-dev): bump aws-cdk from 2.120.0 to 2.121.1 (#3634) by @dependabot
  • chore(ci): update boto3 library version to 1.26.164+ (#3632) by @leandrodamascena
  • chore(deps-dev): bump ruff from 0.1.11 to 0.1.13 (#3625) by @dependabot
  • chore(deps-dev): bump aws-cdk from 2.118.0 to 2.120.0 (#3627) by @dependabot
  • chore(deps): bump jinja2 from 3.1.2 to 3.1.3 in /docs (#3620) by @dependabot
  • chore(deps-dev): bump jinja2 from 3.1.2 to 3.1.3 (#3619) by @dependabot
  • chore(deps-dev): bump sentry-sdk from 1.39.1 to 1.39.2 (#3614) by @dependabot
  • chore(deps): bump redis from 4.6.0 to 5.0.1 (#3613) by @dependabot
  • feat(idempotency): adding redis as idempotency backend (#2567) by @roger-zhangg
  • chore(deps-dev): bump gitpython from 3.1.40 to 3.1.41 (#3611) by @dependabot
  • chore(deps): bump gitpython from 3.1.37 to 3.1.41 in /docs (#3610) by @dependabot
  • chore(deps-dev): bump cfn-lint from 0.83.7 to 0.83.8 (#3603) by @dependabot

This release was made possible by the following contributors:

@Thomas-McKanna, @dastra, @dependabot, @dependabot[bot], @github-actions, @github-actions[bot], @leandrodamascena, @roger-zhangg, @rubenfonseca and @sbailliez

v2.31.0

5 months ago

Summary

This release introduces enhanced top-level Tags in the OpenAPI schema, and adds Lambda layer support in AWS Canada region (ca-west-1). It also includes improvements to documentation and bug fixes.

⭐ Huge thanks to our new contributors: @kamilturek (Middleware factory docs), and @troyswanson (Parameters).

Support for enhanced top-level Tags

Docs: Event Handler OpenAPI

The OpenAPI schema now supports more comprehensive top-level Tags, simplifying the organization and categorization of API operations.

carbon (16) carbon (17)

Last but not least, kudos to @Mavtti for bringing attention to an issue in our error handling within the Parser utility, thereby improving the development experience.

Changes

  • refactor(parser): Improve error message when parsing models and envelopes (#3587) by @leandrodamascena
  • chore(ci): Remove dev dependencies locked to Pydantic v1 within the Pydantic v2 workflow. (#3582) by @leandrodamascena
  • fix(ci): fail dispatch analytics job when Lambda call fails (#3579) by @rubenfonseca
  • feat(event-handler): add description to request body in OpenAPI schema (#3548) by @rubenfonseca
  • feat(event_handler): support richer top level Tags (#3543) by @rubenfonseca
  • refactor(parameters): add overload signatures for get_parameter and get_parameters (#3534) by @troyswanson

πŸ“œ Documentation updates

  • docs(middleware-factory): Fix and improve typing (#3569) by @kamilturek
  • chore(deps): bump squidfunk/mkdocs-material from 9af3b7e to 2f29d71 in /docs (#3559) by @dependabot
  • feat(layers): add new comercial region Canada - ca-west-1 (#3549) by @rubenfonseca

πŸ”§ Maintenance

  • chore(deps): bump the layer-balancer group in /layer/scripts/layer-balancer with 4 updates (#3593) by @dependabot
  • chore(deps): bump actions/dependency-review-action from 3.1.4 to 3.1.5 (#3592) by @dependabot
  • chore(deps-dev): bump aws-cdk from 2.117.0 to 2.118.0 (#3589) by @dependabot
  • chore(deps-dev): bump ruff from 0.1.10 to 0.1.11 (#3588) by @dependabot
  • chore(deps-dev): bump ruff from 0.1.9 to 0.1.10 (#3583) by @dependabot
  • chore(deps-dev): bump pytest from 7.4.3 to 7.4.4 (#3576) by @dependabot
  • chore(deps): bump fastjsonschema from 2.19.0 to 2.19.1 (#3567) by @dependabot
  • chore(deps-dev): bump aws-cdk from 2.116.1 to 2.117.0 (#3565) by @dependabot
  • chore(deps-dev): bump cfn-lint from 0.83.6 to 0.83.7 (#3554) by @dependabot
  • chore(deps-dev): bump aws-cdk from 2.115.0 to 2.116.1 (#3553) by @dependabot
  • chore(deps): bump squidfunk/mkdocs-material from 9af3b7e to 2f29d71 in /docs (#3559) by @dependabot
  • chore(deps-dev): bump ruff from 0.1.8 to 0.1.9 (#3550) by @dependabot
  • chore(deps): bump the layer-balancer group in /layer/scripts/layer-balancer with 2 updates (#3544) by @dependabot
  • chore(deps): bump zgosalvez/github-actions-ensure-sha-pinned-actions from 3.0.2 to 3.0.3 (#3536) by @dependabot
  • chore(deps): bump actions/setup-node from 4.0.0 to 4.0.1 (#3535) by @dependabot

This release was made possible by the following contributors:

@dependabot, @dependabot[bot], @github-actions, @github-actions[bot], @kamilturek, @leandrodamascena, @rubenfonseca and @troyswanson

v2.30.2

6 months ago

Summary

This patch release fixes three bugs related to the OpenAPI and Swagger features:

  • Generating Operation Tags now correctly follows the official OpenAPI spec
  • Fixed Swagger UI regressions that was causing the UI to be non functional under certain scenarios
  • Ensured that all references to the OpenAPI version used is 3.0.0

⭐ Huge thanks to @MCR2019 and @danikenan for reporting those issues! ⭐

Changes

  • fix(event-handler): operation tags are now string to correct schema generation (#3528) by @rubenfonseca
  • fix(event-handler): set default OpenAPI version to 3.0.0 (#3527) by @rubenfonseca
  • fix(event-handler): upgrade Swagger UI to fix regressions (#3526) by @rubenfonseca

πŸ”§ Maintenance

  • chore(deps-dev): bump cfn-lint from 0.83.5 to 0.83.6 (#3521) by @dependabot

This release was made possible by the following contributors:

@dependabot, @dependabot[bot], @github-actions, @github-actions[bot] and @rubenfonseca

v2.30.1

6 months ago

Summary

This patch release fixes a bug when using the event handler Router together with OpenAPI metadata.

Huge thanks to @MCR2019 for finding and reporting this out!

Changes

  • fix(event_handler): allow responses and metadata when using Router (#3514) by @rubenfonseca

πŸ”§ Maintenance

  • chore(deps-dev): bump aws-cdk from 2.114.1 to 2.115.0 (#3508) by @dependabot
  • chore(deps-dev): bump the boto-typing group with 11 updates (#3509) by @dependabot
  • chore(deps-dev): bump sentry-sdk from 1.39.0 to 1.39.1 (#3512) by @dependabot

This release was made possible by the following contributors:

@dependabot, @dependabot[bot], @github-actions, @github-actions[bot] and @rubenfonseca

v2.30.0

6 months ago

Summary

This release follows the newly announced Python 3.12 runtime in AWS Lambda πŸš€

Changes

πŸ“œ Documentation updates

  • feat(general): add support for Python 3.12 (#3304) by @leandrodamascena
  • fix(docs): make the Lambda Layer version consistent (#3498) by @rubenfonseca
  • docs(customer-reference): add Transformity as a customer reference (#3497) by @rubenfonseca
  • chore(deps): bump squidfunk/mkdocs-material from 876b39c to 9af3b7e in /docs (#3486) by @dependabot

πŸ”§ Maintenance

  • feat(general): add support for Python 3.12 (#3304) by @leandrodamascena
  • chore(deps-dev): bump ruff from 0.1.7 to 0.1.8 (#3501) by @dependabot
  • chore(deps-dev): bump the boto-typing group with 1 update (#3500) by @dependabot
  • chore(deps-dev): bump sentry-sdk from 1.38.0 to 1.39.0 (#3495) by @dependabot
  • chore(deps-dev): bump cfn-lint from 0.83.4 to 0.83.5 (#3487) by @dependabot
  • chore(deps): bump squidfunk/mkdocs-material from 876b39c to 9af3b7e in /docs (#3486) by @dependabot
  • chore(tests): temporarily disable E2E parallelism (#3484) by @heitorlessa

This release was made possible by the following contributors:

@dependabot, @dependabot[bot], @github-actions, @github-actions[bot], @heitorlessa, @leandrodamascena and @rubenfonseca

v2.29.1

6 months ago

Summary

This patch release fixes a bug in the Logger utility, ensuring it prints non-ASCII values as-is instead of escaping them. Previously, non-ASCII characters were displayed in an encoded format.

Huge thanks to @bml1g12 for reporting this! :star:

Changes

  • fix(logger): log non-ascii characters as is when JSON stringifying (#3475) by @heitorlessa

πŸ“œ Documentation updates

  • chore(deps): bump squidfunk/mkdocs-material from 876b39c to 9af3b7e in /docs (#3486) by @dependabot
  • chore(deps): bump squidfunk/mkdocs-material from 20241c6 to 876b39c in /docs (#3477) by @dependabot
  • chore(deps): bump squidfunk/mkdocs-material from 8c72011 to 20241c6 in /docs (#3470) by @dependabot

πŸ”§ Maintenance

  • chore(deps-dev): bump cfn-lint from 0.83.4 to 0.83.5 (#3487) by @dependabot
  • chore(deps): bump squidfunk/mkdocs-material from 876b39c to 9af3b7e in /docs (#3486) by @dependabot
  • chore(tests): temporarily disable E2E parallelism (#3484) by @heitorlessa
  • chore(deps-dev): bump the boto-typing group with 1 update (#3478) by @dependabot
  • chore(deps): bump squidfunk/mkdocs-material from 20241c6 to 876b39c in /docs (#3477) by @dependabot
  • chore(deps): bump the layer-balancer group in /layer/scripts/layer-balancer with 2 updates (#3476) by @dependabot
  • chore(deps): bump squidfunk/mkdocs-material from 8c72011 to 20241c6 in /docs (#3470) by @dependabot
  • chore(deps): bump the layer-balancer group in /layer/scripts/layer-balancer with 3 updates (#3469) by @dependabot
  • chore(deps): bump actions/setup-python from 4.8.0 to 5.0.0 (#3465) by @dependabot
  • chore(deps): bump datadog-lambda from 5.84.0 to 5.85.0 (#3466) by @dependabot
  • chore(deps-dev): bump aws-cdk from 2.113.0 to 2.114.1 (#3464) by @dependabot
  • chore(deps): bump the layer-balancer group in /layer/scripts/layer-balancer with 2 updates (#3467) by @dependabot

This release was made possible by the following contributors:

@dependabot, @dependabot[bot], @github-actions, @github-actions[bot] and @heitorlessa

v2.29.0

6 months ago

Summary

Standardized Retrieval of API Gateway Authorizer Context

This release standardizes how to retrieve the API Gateway authorizer context in both v1 and v2 of the Lambda handler. Previously, there were inconsistencies in how customers retrieved authorization context between V1 and V2 payloads.

from aws_lambda_powertools.event_handler import APIGatewayRestResolver
from aws_lambda_powertools import Logger

app = APIGatewayRestResolver()
logger = Logger(level="INFO")


@app.get("/")
def initialize():
    context: dict = app.current_event.request_context.authorizer.get_context()
    logger.info(context.get("tenantId"))

def lambda_handler(event, context):
    return app.resolve(event, context)

We also fixed an issue with dependency injection when using decorators in the Lambda handler function. Previously, dependencies were not properly injected when decorators were present, leading to runtime errors.

Changes

  • fix(metrics): lambda_handler typing, and **kwargs preservation all middlewares (#3460) by @heitorlessa
  • feat(event_sources): add get_context() to standardize API Gateway Lambda Authorizer context in v1 and v2 (#3454) by @leandrodamascena
  • chore(layers): Update log retention to 10 years (#3424) by @sthulb

πŸ“œ Documentation updates

  • chore(deps): bump squidfunk/mkdocs-material from fc42bac to 8c72011 in /docs (#3416) by @dependabot

πŸ”§ Maintenance

  • chore(deps): bump actions/setup-python from 4.8.0 to 5.0.0 (#3465) by @dependabot
  • chore(deps): bump datadog-lambda from 5.84.0 to 5.85.0 (#3466) by @dependabot
  • chore(deps-dev): bump aws-cdk from 2.113.0 to 2.114.1 (#3464) by @dependabot
  • chore(deps): bump the layer-balancer group in /layer/scripts/layer-balancer with 2 updates (#3467) by @dependabot
  • fix(event_handler): serialize pydantic/dataclasses in exception handler (#3455) by @heitorlessa
  • chore(deps-dev): bump the boto-typing group with 1 update (#3457) by @dependabot
  • chore(deps-dev): bump ruff from 0.1.6 to 0.1.7 (#3458) by @dependabot
  • chore(deps): bump actions/setup-python from 4.7.1 to 4.8.0 (#3456) by @dependabot
  • chore(deps-dev): bump cfn-lint from 0.83.3 to 0.83.4 (#3450) by @dependabot
  • chore(deps): bump zgosalvez/github-actions-ensure-sha-pinned-actions from 3.0.1 to 3.0.2 (#3449) by @dependabot
  • chore(deps): bump datadog-lambda from 5.83.0 to 5.84.0 (#3438) by @dependabot
  • chore(deps): bump cryptography from 41.0.4 to 41.0.6 (#3431) by @dependabot
  • chore(deps-dev): bump aws-cdk from 2.112.0 to 2.113.0 (#3448) by @dependabot
  • chore(deps-dev): bump sentry-sdk from 1.36.0 to 1.38.0 (#3435) by @dependabot
  • chore(deps-dev): bump aws-cdk from 2.111.0 to 2.112.0 (#3440) by @dependabot
  • chore(deps): bump pypa/gh-action-pypi-publish from 1.8.10 to 1.8.11 (#3433) by @dependabot
  • chore(deps): bump the layer-balancer group in /layer/scripts/layer-balancer with 3 updates (#3441) by @dependabot
  • chore(deps): bump actions/dependency-review-action from 3.1.3 to 3.1.4 (#3426) by @dependabot
  • chore(deps-dev): bump aws-cdk-lib from 2.110.1 to 2.111.0 (#3428) by @dependabot
  • chore(deps): bump squidfunk/mkdocs-material from fc42bac to 8c72011 in /docs (#3416) by @dependabot
  • chore(deps-dev): bump aws-cdk from 2.110.1 to 2.111.0 (#3418) by @dependabot
  • chore(deps-dev): bump the boto-typing group with 11 updates (#3427) by @dependabot

This release was made possible by the following contributors:

@dependabot, @dependabot[bot], @github-actions, @github-actions[bot], @heitorlessa, @leandrodamascena and @sthulb

v2.28.1

6 months ago

Summary

This patch release fixes a bug on the event handler utility, where using the compress option was causing an error.

Huge thanks to @dacianf for reporting this!

Changes

  • fix(event_handler): fix compress handling (#3420) by @rubenfonseca

This release was made possible by the following contributors:

@github-actions, @github-actions[bot] and @rubenfonseca

v2.28.0

6 months ago

Summary

This release adds support for Data Validation and automatic OpenAPI generation in Event Handler.

Even better, it works with your existing resolver (API Gateway REST/HTTP, ALB, Lambda Function URL, VPC Lattice)!

Did you read that correctly? Yes, you did! Look at this:

image (9)

Data validation

Docs: Data validation

By adding enable_validation=True to your resolver constructor, you’ll change the way the resolver works. We will:

  1. inspect your route handlers to gather input and output types (including Pydantic models and dataclasses)
  2. validate and coerce the input data for you automatically before invoking your route handlers
  3. validate and coerce the output data for you automatically after invoking your route handlers
  4. enable a cool feature (see the next section!)

This moves data validation responsibilities to Event Handler resolvers, reducing a ton of boilerplate code. You can now focus on just writing your business logic, and leave the validation to us!

from typing import List, Optional

import requests
from pydantic import BaseModel, Field

from aws_lambda_powertools import Logger, Tracer
from aws_lambda_powertools.event_handler import APIGatewayRestResolver
from aws_lambda_powertools.logging import correlation_paths
from aws_lambda_powertools.utilities.typing import LambdaContext

tracer = Tracer()
logger = Logger()
app = APIGatewayRestResolver(enable_validation=True)  


class Todo(BaseModel):  
    userId: int
    id_: Optional[int] = Field(alias="id", default=None)
    title: str
    completed: bool


@app.post("/todos")
def create_todo(todo: Todo) -> str:  
    response = requests.post("https://jsonplaceholder.typicode.com/todos", json=todo.dict(by_alias=True))
    response.raise_for_status()

    return response.json()["id"]  


@app.get("/todos")
@tracer.capture_method
def get_todos() -> List[Todo]:
    todo = requests.get("https://jsonplaceholder.typicode.com/todos")
    todo.raise_for_status()

    return todo.json()  


@logger.inject_lambda_context(correlation_id_path=correlation_paths.API_GATEWAY_HTTP)
@tracer.capture_lambda_handler
def lambda_handler(event: dict, context: LambdaContext) -> dict:
    return app.resolve(event, context)

OpenAPI generation

Docs: OpenAPI generation

When you enable data validation, we automatically inspect your API in a way that makes it possible to generate OpenAPI specifications automatically!

You can export the OpenAPI spec for customization, manipulation, merging micro-functions, etc., in two ways:

  • Pydantic model using app.get_openapi_schema()
  • JSON Schema using app.get_openapi_json_schema()

Here’s one way to print the schema if you were to run your Python Lambda handler locally:

import requests

from aws_lambda_powertools.event_handler import APIGatewayRestResolver
from aws_lambda_powertools.event_handler.openapi.models import Contact, Server
from aws_lambda_powertools.utilities.typing import LambdaContext

app = APIGatewayRestResolver(enable_validation=True)


@app.get("/todos/<todo_id>")
def get_todo_title(todo_id: int) -> str:
    todo = requests.get(f"https://jsonplaceholder.typicode.com/todos/{todo_id}")
    todo.raise_for_status()

    return todo.json()["title"]


def lambda_handler(event: dict, context: LambdaContext) -> dict:
    return app.resolve(event, context)


if __name__ == "__main__":
    print(
        app.get_openapi_json_schema(
            title="TODO's API",
            version="1.21.3",
            summary="API to manage TODOs",
            description="This API implements all the CRUD operations for the TODO app",
            tags=["todos"],
            servers=[Server(url="https://stg.example.org/orders", description="Staging server")],
            contact=Contact(name="John Smith", email="[email protected]"),
        ),
    )

Can you see where this is going? Keep reading :)

Swagger UI

Docs: Swagger UI

Last but not least... you can now enable an embedded Swagger UI to visualize and interact with your newly auto-documented API!

from typing import List, Optional

import requests
from pydantic import BaseModel, Field

from aws_lambda_powertools import Logger, Tracer
from aws_lambda_powertools.event_handler import APIGatewayRestResolver
from aws_lambda_powertools.logging import correlation_paths
from aws_lambda_powertools.utilities.typing import LambdaContext

app = APIGatewayRestResolver(enable_validation=True)  
app.enable_swagger()  # by default, path="/swagger"

@app.get("/todos")
@tracer.capture_method
def get_todos() -> List[Todo]:
    todo = requests.get("https://jsonplaceholder.typicode.com/todos")
    todo.raise_for_status()

    return todo.json()
    
def lambda_handler(event: dict, context: LambdaContext) -> dict:
    return app.resolve(event, context)

The Swagger UI appears by default at the /swagger path, but you can customize this to serve the documentation from another path, and specify the source for Swagger UI assets.

image (10)

We can’t wait for you try this new features!

Changes

  • fix(event_handler): fix format for OpenAPI path templating (#3399) by @rubenfonseca
  • fix(event_handler): allow fine grained Response with data validation (#3394) by @rubenfonseca
  • fix(event_handler): apply serialization as the last operation for middlewares (#3392) by @rubenfonseca

🌟New features and non-breaking changes

  • feat(event_handler): allow customers to catch request validation errors (#3396) by @rubenfonseca

πŸ“œ Documentation updates

  • docs(event_handlers): new data validation and OpenAPI feature (#3386) by @rubenfonseca

πŸ› Bug and hot fixes

  • fix(event_handler): hide error details by default (#3406) by @rubenfonseca
  • fix(event_handler): lazy load Pydantic to improve cold start (#3397) by @rubenfonseca

πŸ”§ Maintenance

  • chore(deps-dev): bump the boto-typing group with 1 update (#3400) by @dependabot
  • chore(deps-dev): bump aws-cdk-lib from 2.110.0 to 2.110.1 (#3402) by @dependabot
  • chore(deps): bump datadog-lambda from 4.82.0 to 5.83.0 (#3401) by @dependabot
  • chore(deps-dev): bump aws-cdk from 2.110.0 to 2.110.1 (#3403) by @dependabot
  • chore(deps-dev): bump pytest-xdist from 3.4.0 to 3.5.0 (#3387) by @dependabot
  • chore(deps-dev): bump sentry-sdk from 1.35.0 to 1.36.0 (#3388) by @dependabot
  • chore(deps): bump the layer-balancer group in /layer/scripts/layer-balancer with 3 updates (#3389) by @dependabot

This release was made possible by the following contributors:

@dependabot, @dependabot[bot], @github-actions, @github-actions[bot], @heitorlessa, and @rubenfonseca