A suite of utilities for AWS Lambda Functions that makes tracing with AWS X-Ray, structured logging and creating custom metrics asynchronously easier

Overview

AWS Lambda Powertools (Python)

Build codecov.io PythonSupport PyPI version PyPi monthly downloads

A suite of Python utilities for AWS Lambda functions to ease adopting best practices such as tracing, structured logging, custom metrics, and more. (AWS Lambda Powertools Java is also available).

πŸ“œ Documentation | 🐍 PyPi | Roadmap | Quick hello world example | Detailed blog post

Join us on the AWS Developers Slack at #lambda-powertools - Invite, if you don't have an account

Features

  • Tracing - Decorators and utilities to trace Lambda function handlers, and both synchronous and asynchronous functions
  • Logging - Structured logging made easier, and decorator to enrich structured logging with key Lambda context details
  • Metrics - Custom Metrics created asynchronously via CloudWatch Embedded Metric Format (EMF)
  • Event handler: AppSync - AWS AppSync event handler for Lambda Direct Resolver and Amplify GraphQL Transformer function
  • Event handler: API Gateway and ALB - Amazon API Gateway REST/HTTP API and ALB event handler for Lambda functions invoked using Proxy integration
  • Bring your own middleware - Decorator factory to create your own middleware to run logic before, and after each Lambda invocation
  • Parameters utility - Retrieve and cache parameter values from Parameter Store, Secrets Manager, or DynamoDB
  • Batch processing - Handle partial failures for AWS SQS batch processing
  • Typing - Static typing classes to speedup development in your IDE
  • Validation - JSON Schema validator for inbound events and responses
  • Event source data classes - Data classes describing the schema of common Lambda event triggers
  • Parser - Data parsing and deep validation using Pydantic
  • Idempotency - Convert your Lambda functions into idempotent operations which are safe to retry
  • Feature Flags - A simple rule engine to evaluate when one or multiple features should be enabled depending on the input

Installation

With pip installed, run: pip install aws-lambda-powertools

Examples

Credits

License

This library is licensed under the MIT-0 License. See the LICENSE file.

Comments
  • feat(feat-flags): new simple feature toggles rule engine

    feat(feat-flags): new simple feature toggles rule engine

    https://github.com/awslabs/aws-lambda-powertools-python/issues/470

    First poc branch. Has only pure python, no pydantic. Missing: md doc , schema validation implementstion (currently has a todo commengt there), more tests for exception cases

    usage example can be found at this gist: https://gist.github.com/risenberg-cyberark/903bc41079218bb719c98321f8e6152b

    feature size/XXL tests 
    opened by ran-isenberg 49
  • RFC: Pass custom context dict to resolve method

    RFC: Pass custom context dict to resolve method

    Is this related to an existing feature request or issue?

    https://github.com/awslabs/aws-lambda-powertools-python/discussions/1546

    Which AWS Lambda Powertools utility does this relate to?

    Event Handler - REST API

    Summary

    It would be useful if you could provide an optional dict to the app.resolve() method, that would then be available in the handlers themselves. This would contain generic information that is needed for all requests.

    Use case

    We are implementing callbacks for Twilio. For every event, we need to:

    1. Decode the body
    2. Parse the parameters
    3. Validate the request

    Next, we need the same parameters from step 2 in almost every request.

    Proposal

    Provide an extra parameter to the resolve() method:

    app.py

    from aws_lambda_powertools.event_handler import APIGatewayRestResolver
    from aws_lambda_powertools.utilities.typing import LambdaContext
    
    import todos
    
    
    app = APIGatewayRestResolver()
    app.include_router(todos.router)
    
    
    def lambda_handler(event: dict, context: LambdaContext) -> dict:
        some_info = {"some_custom": "data"}
        return app.resolve(event, context, route_context=some_info)
    

    In the handler itself, it could then be accessible via route_context:

    todos.py

    import requests
    
    from aws_lambda_powertools.event_handler.api_gateway import Router
    from requests import Response
    
    router = Router()
    
    
    @router.get("/todos")
    def get_todos():
        some_data = router.route_context.get("some_custom")
       
        todos: Response = requests.get("https://jsonplaceholder.typicode.com/todos")
        todos.raise_for_status()
    
        return {"todos": todos.json()[:10]}
    

    Out of scope

    n/a

    Potential challenges

    n/a

    Dependencies and Integrations

    No response

    Alternative solutions

    Currently I'm passing the data in app.lambda_context.__dict__.

    Acknowledgment

    RFC 
    opened by MaartenUreel 27
  • Maintenance: Change parameters appconfig utility API due to GetConfiguration deprecation

    Maintenance: Change parameters appconfig utility API due to GetConfiguration deprecation

    Summary

    The current API will be deprecated in the near future according to AWS AppConfig team. See this See https://github.com/awslabs/aws-lambda-powertools-python/blob/develop/aws_lambda_powertools/utilities/parameters/appconfig.py

    Why is this needed?

    GetConfiguration - this API action has been deprecated. Calls to receive configuration data should use the StartConfigurationSession and GetLatestConfiguration APIs instead.

    Which area does this relate to?

    Parameters

    Solution

    Use new APIs, hopefully in a non breaking manner.

    Acknowledgment

    breaking-change internal v2 
    opened by ran-isenberg 27
  • feat(event-handler): prefixes to strip for custom mappings

    feat(event-handler): prefixes to strip for custom mappings

    Issue #, if available: https://github.com/awslabs/aws-lambda-powertools-roadmap/issues/34

    • closes #576

    Description of changes:

    Changes:

    • Add prefix to be stripped from the event path, default is None which does not modify the path
    • Add docstring for serializer

    Example usage:

    • Passing in multiple strip_prefixes "/unique/v1" and "/foo/v1"
    • Route /status will then match on /unique/v1/status (and /status)
    • By default strip_prefixes is None, and therefore does not touch the event path
    • Note the prefix should not end with a /
    import os
    from aws_lambda_powertools.event_handler.api_gateway import ApiGatewayResolver
    
    app = ApiGatewayResolver(strip_prefixes=["/unique/v1", "/foo/v1"])
    
    @app.get("/status")
    def foo():
        return {"status": "OK"}
    
    # All calls should return a 200
    response = app({"httpMethod": "GET", "path": "/unique/v1/status"}, None)
    assert response["statusCode"] == 200
    response = app({"httpMethod": "GET", "path": "/foo/v1/status"}, None)
    assert response["statusCode"] == 200
    response = app({"httpMethod": "GET", "path": "/status"}, None)
    assert response["statusCode"] == 200
    

    Checklist

    By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

    feature size/M tests need-documentation 
    opened by michaelbrewer 25
  • feat: Advanced parser utility (pydantic)

    feat: Advanced parser utility (pydantic)

    Issue, if available: #147, #95

    Description of changes:

    Added a new validation module. It has the validator decorator code with 3 envelopes (eventbridge, dynamoDB and custom user) and tests. Also has the eventbridge & dynamoDB schemas.

    Checklist

    Breaking change checklist

    **RFC issue #95 :

    • [ ] Migration process documented
    • [ ] Implement warnings (if it can live side by side)

    By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

    feature 
    opened by ran-isenberg 25
  • feat(data_classes): add KinesisFirehoseEvent

    feat(data_classes): add KinesisFirehoseEvent

    Issue number: #1539

    Summary

    Adding KinesisFirehoseEvent data class for handling Kinesis Firehose Lambda events (for Data Transformation).

    Changes

    Please provide a summary of what's being changed

    • Adding KinesisFirehoseEvent data class and respective sub-DictWrapper classes for handling Kinesis firehose event structure
    • Adding functional test for KinesisFirehoseEvent
      • This handles both text events and json events
    • Updating documentation for KinesisFirehoseEvent

    User experience

    Please share what the user experience looks like before and after this change

    This is included in the documentation updates.

    Checklist

    If your change doesn't seem to apply, please leave them unchecked.

    Is this a breaking change?

    RFC issue number:

    Checklist:

    • [ ] Migration process documented
    • [ ] Implement warnings (if it can live side by side)

    Acknowledgment

    By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

    Disclaimer: We value your time and bandwidth. As such, any pull requests created on non-triaged issues might not be successful.


    View rendered docs/utilities/data_classes.md

    documentation triage feature size/L tests 
    opened by ryandeivert 24
  • `child=True` is not creating a logger?

    `child=True` is not creating a logger?

    What were you trying to accomplish?

    Re-use a logger in a sub-module, using the child=True feature, per the documentation.

    Expected Behavior

    With the following setup, there should be two log entries, one with "service": "foo" and one with "service": "foo.bar".

    cat foo.py:

    $ cat foo.py
    import aws_lambda_powertools
    import bar
    
    log = aws_lambda_powertools.Logger(service="foo")
    
    log.info('hallelujah')
    bar.bar()
    

    cat bar.py:

    import aws_lambda_powertools
    
    log = aws_lambda_powertools.Logger(child=True)
    
    def bar():
        log.info('doublestuff')
    

    Current Behavior

    $ python foo.py
    {"timestamp": "2020-08-27 11:20:16,245", "level": "INFO", "location": "<module>:6", "service": "foo", "sampling_rate": 0.0, "message": "hallelujah"}
    

    Even setting the service explicitly in the submodule to foo.bar, the service remains foo in the output, though at least now their are two log entries.

    cat bar.py:

    $ cat bar.py
    import aws_lambda_powertools
    
    log = aws_lambda_powertools.Logger(service="foo.bar", child=True)
    
    def bar():
        log.info('doublestuff')
    
    $ξ‚° python foo.py
    {"timestamp": "2020-08-27 11:26:05,330", "level": "INFO", "location": "<module>:6", "service": "foo", "sampling_rate": 0.0, "message": "hallelujah"}
    {"timestamp": "2020-08-27 11:26:05,330", "level": "INFO", "location": "bar:6", "service": "foo", "sampling_rate": 0.0, "message": "doublestuff"}
    

    Steps to Reproduce (for bugs)

    See above.

    Environment

    • Powertools version used: 1.4.0
    • Packaging format (Layers, PyPi): PyPi
    • AWS Lambda function runtime: running locally, not in lambda yet
    documentation 
    opened by lorengordon 24
  • feat(apigateway): add Router to allow large routing composition

    feat(apigateway): add Router to allow large routing composition

    Add Router class to ApiGatewayResolver

    Issue #, if available: #644

    Description of changes:

    Add a Router class to be used as a proxy for ApiGatewayResolver. The class is able to at as a placeholder for the app instance and collect routes to later be applied; it includes all the functionality of current routes.

    To access query strings or headers the original event and context are made available as router.current_event and router.lambda_context respectively. Also, to improve performance of a function which uses an endpoint with multiple methods, it offers a slight variation of the route() method's signature allowing a list/tuple.

    Usage example:

    app/main.py:

    from aws_lambda_powertools import Logger, Tracer
    from aws_lambda_powertools.event_handler.api_gateway import ApiGatewayResolver
    from aws_lambda_powertools.logging import correlation_paths
    
    from .routers import users, items
    
    tracer = Tracer()
    logger = Logger()
    app = ApiGatewayResolver()
    app.include_router(users.router)
    app.include_router(items.router, prefix="/items")
    
    @logger.inject_lambda_context(correlation_id_path=correlation_paths.API_GATEWAY_REST)
    @tracer.capture_lambda_handler
    def lambda_handler(event, context):
        return app.resolve(event, context)
    

    app/routers/items.py:

    from aws_lambda_powertools import Logger, Tracer
    from aws_lambda_powertools.event_handler.api_gateway import Router
    
    tracer = Tracer()
    logger = Logger(child=True)
    router = Router()
    
    @router.get('/hello')
    @tracer.capture_method
    def get_hello():
        return {
            "message": ['/hello', 'GET'],
            "query_string": router.current_event.query_string_parameters,
        }
    
    @router.route('/world', ('GET','POST'))
    @tracer.capture_method
    def multi_world():
        return {
            "message": ['/world', 'GET/POST'],
            "query_string": router.current_event.query_string_parameters,
        }
    

    Checklist

    By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

    feature size/L tests 
    opened by BVMiko 23
  • Ability to swap out the logger with default python logger during local testing

    Ability to swap out the logger with default python logger during local testing

    Is your feature request related to a problem? Please describe.

    When working locally, we often wish to visualise the "message" of logs without structured logging as it is more readable and we have no intention of searching the logs. We also wish to log to file often when testing locally.

    Is there any way we can hot-swap the default Python logger or replace the logger universally across a codebase?

    Describe the solution you'd like

    Ability to disable structured logging across a code base and default to a standard python logger such that we have a way to make the code base log to local file and display without structured logs during local testing.

    Describe alternatives you've considered

    I thought initially we could just mock out the logger with the default logger, but the introduction of child=True (which is not in the default logger) would mean that does not work I think.

    I was thinking maybe we could also try and add the default logger as an additional logger by patching the init of the powertools logger maybe?

    need-more-information feature-request 
    opened by bml1g12 23
  • Idempotency and Lambda timeouts

    Idempotency and Lambda timeouts

    Is your feature request related to a problem? Please describe. Currently if a lambda timesout the idempotency item is left in the 'INPROGRESS' status and subsequent lambda retries fail with IdempotencyAlreadyInProgressError.

    Describe the solution you'd like Add an additional field to the persistence record e.g. function_timeout and store in it the timestamp when the lambda will timeout: now().timestamp() + int(context.get_remaining_time_in_millis() / 1000) Expand the DDB condition: OR function_timeout < :now

    Describe alternatives you've considered Create a signal handler in the lambda that raises an exception just before the lambda is about to timeout.

    Additional context N/A

    bug p2 researching 
    opened by n2N8Z 22
  • Add AWS CDK examples for creating and using a layer from the Serverless Application Repository

    Add AWS CDK examples for creating and using a layer from the Serverless Application Repository

    What were you initially searching for in the docs? Using the AWS CDK, I wanted to deploy a Lambda layer from the Powertools Serverless Application Repository ARN for re-use within my CDK application.

    The Lambda Layer documentation does not include how to do this.

    Is this related to an existing part of the documentation? Please share a link https://awslabs.github.io/aws-lambda-powertools-python/#lambda-layer

    Describe how we could make it clearer A code snippet and details could be provided to make it easier for a customer to get up and running faster.

    If you have a proposed update, please share it here

    Using similar language to the existing documentation, but some rewording could also used to provide the overall detail with SAM and CDK examples below it.

    If using the AWS CDK, you can create include this SAR App and lock to a specific semantic version. The Layer can be used in the same CDK application. Once deployed, it'll be available across the account this is deployed to.

    ** insert a TypeScript CDK example **

    # Create the AWS Lambda Powertools for Python layer
    powertools_arn = 'arn:aws:serverlessrepo:eu-west-1:057560766410:applications/aws-lambda-powertools-python-layer'
    powertools_application = aws_sam.CfnApplication(self, 'AWSLambdaPowertoolsApplication',
                                                    location={'applicationId': powertools_arn,
                                                              'semanticVersion': '1.12.0'})
    powertools_resource = cdk.CfnResource(powertools_application, 'AWSLambdaPowertoolsResource',
                                          type='AWS::Serverless::Application',
                                          properties={'Location': {
                                              'ApplicationId': powertools_arn,
                                              'SemanticVersion': '1.12.0'
                                          }})
    powertools_layer = aws_lambda.LayerVersion.from_layer_version_arn(
        self, 'AWSLambdaPowertoolsLayer', powertools_resource.get_att("Outputs.LayerVersionArn").to_string())
    
    # Reference the Layer in a Lambda definition
    my_function = aws_lambda.Function(
        self, "MyFunction",
        layers=[powertools_layer],
        runtime=aws_lambda.Runtime.PYTHON_3_8,
    )
    
    documentation 
    opened by austoonz 22
  • Fix(idempotency): Log nested exception message

    Fix(idempotency): Log nested exception message

    **Issue number: #1772

    Summary

    Raise IdempotencyPersistenceLayerError exception with additional context taken from raised downstream exception

    Changes

    Please provide a summary of what's being changed

    • Modify idempotency core logic to pass downstream exception to newly raised IdempotencyPersistenceLayerError exception
    • Create base exception class that formats output visible in stdout and inherit from it in idempotency exceptions classes Before this change:
    [ERROR] IdempotencyPersistenceLayerError: ('Failed to save in progress record to idempotency store', ClientError('An error occurred (AccessDeniedException) when calling the PutItem operation: User: <REMOVED> is not authorized to perform: dynamodb:PutItem on resource: <REMOVED> because no identity-based policy allows the dynamodb:PutItem action'))
    

    After:

    [ERROR] IdempotencyPersistenceLayerError: Failed to save in progress record to idempotency store: (An error occurred (AccessDeniedException) when calling the PutItem operation: User: <REMOVED> is not authorized to perform: dynamodb:PutItem on resource:<REMOVED> because no identity-based policy allows the dynamodb:PutItem action)
    

    This change is not mandatory. I'm happy to hear your opinion whether we should reformat exception message or not and what format would be the best

    • Adjust tests

    User experience

    Before then change all downstream exception details was hidden from user, making debugging harder. Now downstream details are available For details please follow: https://github.com/awslabs/aws-lambda-powertools-python/issues/1772

    Checklist

    If your change doesn't seem to apply, please leave them unchecked.

    Is this a breaking change?

    RFC issue number:

    Checklist:

    • [ ] Migration process documented
    • [ ] Implement warnings (if it can live side by side)

    Acknowledgment

    By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

    Disclaimer: We value your time and bandwidth. As such, any pull requests created on non-triaged issues might not be successful.

    size/M tests 
    opened by mploski 4
  • Bug: Custom CloudWatch metrics not always appearing for split route(s)

    Bug: Custom CloudWatch metrics not always appearing for split route(s)

    Expected Behaviour

    When uploading a custom metric using the aws_lambda_powertools.metrics package, the metrics should appear in CloudWatch Metrics.

    Current Behaviour

    Metrics appear intermittently and appear to be tied to whether a lambda was cold started (and also had a cold start metric uploaded).

    Code snippet

    Split route handler:
    
    metrics: Metrics = Metrics()
    
    @router.delete("/v1/asset", cors=True)
    @tracer.capture_method
    def delete_asset() -> dict:
        metrics.add_metric(name="AssetDeleted", unit=MetricUnit.Count, value=1)
        return {"message": "Asset deletion successful"}
    
    Lambda handler:
    
    @metrics.log_metrics(capture_cold_start_metric=True)
    @logger.inject_lambda_context(correlation_id_path=correlation_paths.API_GATEWAY_REST, log_event=True)
    @tracer.capture_lambda_handler
    @auth.enforce_allow_list
    @auth.restrict_api_key
    def lambda_handler(event: Dict, context: LambdaContext):
        return app.resolve(event, context)
    

    Possible Solution

    When examining the cloudwatch logs, the unsuccessful metrics appear in the same log line as the tracer log, for example:

    {
        "resource": "/v1/asset",
        "path": "/v1/asset",
        "httpMethod": "DELETE",
    ...more data...
    }{
        "_aws": {
            "Timestamp": 1672800187055,
            "CloudWatchMetrics": [
                {
                    "Namespace": "MyNamespace",
                    "Dimensions": [
                        [
                            "service"
                        ]
                    ],
                    "Metrics": [
                        {
                            "Name": "AssetDeleted",
                            "Unit": "Count"
                        }
                    ]
                }
            ]
        },
        "service": "MyLambda",
        "AssetDeleted": [
            1
        ]
    }
    
    

    When successful metrics appear (such as when they are uploaded as part of a cold start), they appear in their own log line in CloudWatch and are presumably parsed.

    Steps to Reproduce

    • Create a split route lambda handler, log cold starts
    • In the split route(s) attempt to create/upload custom metrics
    • Observe not all metrics appear in CloudWatch metrics as expected

    AWS Lambda Powertools for Python version

    latest

    AWS Lambda function runtime

    3.6

    Packaging format used

    PyPi

    Debugging logs

    No response

    researching cant-reproduce metrics 
    opened by pawosty 6
  • Bug: `log_uncaught_exceptions` only works locally and not on lambda

    Bug: `log_uncaught_exceptions` only works locally and not on lambda

    Expected Behaviour

    When log_uncaught_exceptions=True, uncaught exceptions in a lambda are handled and transformed to a structured log.

    Current Behaviour

    Uncaught exceptions are printed unstructured.

    Code snippet

    from aws_lambda_powertools import Logger
    from aws_lambda_powertools.utilities.typing import LambdaContext
    
    logger = Logger(log_uncaught_exceptions=True)
    
    def lambda_handler(event: dict, context: LambdaContext) -> str:
        raise(Exception("asdf"))
    

    Possible Solution

    Probably none. Document this behavior.

    I don't think sys.excepthook can be overridden in a lambda container, but I have no proof because the original forum thread that details this has been deleted by AWS with no replacement.

    Steps to Reproduce

    Set log_uncaught_exceptions=True in an actual running lambda. If log_uncaught_exceptions=True on a local machine, the behavior runs just as intended.

    AWS Lambda Powertools for Python version

    latest

    AWS Lambda function runtime

    3.9

    Packaging format used

    Lambda Layers

    Debugging logs

    No response

    bug help wanted logger 
    opened by bellis-ai 4
  • Maintenance: appconfig _get method return type and logic

    Maintenance: appconfig _get method return type and logic

    Summary

    Hello there! I hope you all are doing well

    I'm working on the AppConfig provider for typescript powertools and I want to address some questions and concerns to the python team. I hope you'll help me to figure that out.

    1. We have a conversation here about the return type of function _get in appconfig.py. As I understand return value from AppConfig should be returned as is. The same I see in the docs example. That is why I think you missed it in PR #877 please clarify this for me if I'm wrong.

    2. I'm concerned about _get function logic. What if we need two different configuration profiles for the save application and environment?

    appconf_provider = parameters.AppConfigProvider(environment="my_env", application="my_app", config=config)
    
    def handler(event, context):
        value1: bytes = appconf_provider.get("my_conf_A")
        value2: bytes = appconf_provider.get("my_conf_B")
    

    with the value1 we start_configuration_session and get InitialConfigurationToken which encapsulates

    sdk_options["ConfigurationProfileIdentifier"] = name
    sdk_options["ApplicationIdentifier"] = self.application
    sdk_options["EnvironmentIdentifier"] = self.environment
    

    We use that initial token in the subsequent API call (the request consists of the token only) to get my_conf_A configuration and NextPollConfigurationToken. After that, we save NextPollConfigurationToken in this._next_token.

    Not we want to get "my_conf_B" and store it in value2. _get function check for self._next_token existence and make an API call with the existent NextPollConfigurationToken which encapsulates ConfigurationProfileIdentifier with my_conf_A in it and completely ignores name argument.

    I assume we get the same values in value1 and value2. I'm not sure if is it a real-world situation, but as I understand, for the same application and environment, we can have several configuration profiles. Docs section.

    There is also an unused self.current_version = "" in the class.

    1. Other small things I noticed:
    • I'm not too much into python, but when I looked at the _get_multiple function I noticed that you raise NotImplementedError() in derived class and the docs say that It should not be used to indicate that an operator or method is not meant to be supported at all – in that case either leave the operator / method undefined or, if a subclass, set it to None. Maybe it's not an issue – let me know!
    • In the docs example, I think the comment was copy-pasted from the secrets section, maybe you should consider it to change to # Retrieve the latest configuration.

    Why is this needed?

    To provide consistency across implementations in different languages.

    Which area does this relate to?

    Parameters, Typing

    Solution

    A possible solution for the return type:

    In the appconfig.py Current return type: def _get(self, name: str, **sdk_options) -> str: Suggested return type: def _get(self, name: str, **sdk_options) -> bytes:

    A possible solution for the method logic:

    Store name from the previous call along with NextPollConfigurationToken and flush self._next_token and self.last_returned_value if name is different from the previous call.

    Another option is to use dict to store NextPollConfigurationToken tokens with name as the key. But it increases complexity, cause in this case you should also store last_returned_value for each token. I think flush and starting a new session is the better option.

    All best, Sergei.

    Acknowledgment

    triage internal 
    opened by shdq 1
  • Brief pause on new features for winter holidays until January

    Brief pause on new features for winter holidays until January

    Brief pause

    Hey everyone! Due to parental leaves and winter holidays, we will have low coverage to support discussions, feature requests, and Discord until January.

    Bug prioritization

    If you reported a bug that is impacting you in production, please mention @sthulb, @mploski or @heitorlessa and we will prioritize it.

    We appreciate everyone's understanding and we wish you an amazing holidays (or Christmas depending on your religious orientation)!

    opened by heitorlessa 0
  • [Support Lambda Powertools]: globaldatanet

    [Support Lambda Powertools]: globaldatanet

    Organization Name

    globaldatanet

    Your Name

    Stephan Huber

    Your current position

    AWS Cloud Developer

    (Optional) Company logo

    https://raw.githubusercontent.com/globaldatanet/.github/main/profile/logo.png

    (Optional) Use case

    No response

    Also using other Lambda Powertools languages?

    • [ ] Java
    • [X] TypeScript
    • [ ] .NET
    customer-reference 
    opened by sthuber90 0
Releases(v2.5.0)
  • v2.5.0(Dec 21, 2022)

    Summary

    This release improves logging incoming events that might be wrapped in common containers such as Event Source Data Classes, Pydantic/Parser BaseModels, and Dataclasses.

    Also we addressed an issue when a header is set explicit to None.

    Big thanks to @jasmarc for the bug report!

    Example:

    import json
    
    from aws_lambda_powertools.event_handler import (
        APIGatewayRestResolver,
        Response,
    )
    
    app = APIGatewayRestResolver()
    
    @app.get("/none")
    def hello():
        headers = {"This-Header-Will-Be-Omitted": None}
        response = {"hello": "world"}
        return Response(body=json.dumps(response), headers=headers, status_code=200)
    
    
    def lambda_handler(event, context):
        return app.resolve(event, context)
    

    Changes

    🌟New features and non-breaking changes

    • feat(logger): unwrap event from common models if asked to log (#1778) by @heitorlessa

    πŸ“œ Documentation updates

    • docs(validation): fix broken link; enrich built-in jmespath links (#1777) by @heitorlessa
    • docs(idempotency): fix, improve, and increase visibility for batch integration (#1776) by @heitorlessa

    πŸ› Bug and hot fixes

    • fix(event_handlers): omit explicit None HTTP header values (#1793) by @leandrodamascena

    πŸ”§ Maintenance

    • chore(deps-dev): bump isort from 5.11.2 to 5.11.3 (#1788) by @dependabot
    • chore(deps-dev): bump aws-cdk-lib from 2.54.0 to 2.55.1 (#1787) by @dependabot
    • chore(deps-dev): bump mypy-boto3-cloudwatch from 1.26.17 to 1.26.30 (#1785) by @dependabot
    • chore(deps-dev): bump isort from 5.10.1 to 5.11.2 (#1782) by @dependabot
    • chore(deps-dev): bump pytest-asyncio from 0.20.2 to 0.20.3 (#1767) by @dependabot
    • chore(deps): bump certifi from 2022.9.24 to 2022.12.7 (#1768) by @dependabot
    • chore(deps-dev): bump mypy-boto3-dynamodb from 1.26.13.post16 to 1.26.24 (#1765) by @dependabot
    • chore(deps-dev): bump mypy-boto3-logs from 1.26.17 to 1.26.27 (#1775) by @dependabot
    • chore(deps-dev): bump aws-cdk-lib from 2.53.0 to 2.54.0 (#1764) by @dependabot
    • chore(deps-dev): bump flake8-bugbear from 22.10.27 to 22.12.6 (#1760) by @dependabot
    • chore(deps-dev): bump filelock from 3.8.0 to 3.8.2 (#1759) by @dependabot
    • chore(deps-dev): bump pytest-xdist from 3.0.2 to 3.1.0 (#1758) by @dependabot
    • chore(deps-dev): bump mkdocs-material from 8.5.10 to 8.5.11 (#1756) by @dependabot
    • chore(deps-dev): bump importlib-metadata from 4.13.0 to 5.1.0 (#1750) by @dependabot
    • chore(deps): bump zgosalvez/github-actions-ensure-sha-pinned-actions from 1.4.0 to 2.0.1 (#1752) by @dependabot
    • chore(deps-dev): bump flake8-black from 0.3.3 to 0.3.5 (#1738) by @dependabot
    • chore(deps-dev): bump mypy-boto3-cloudwatch from 1.26.0.post1 to 1.26.17 (#1753) by @dependabot
    • chore(deps): bump zgosalvez/github-actions-ensure-sha-pinned-actions from 1.3.0 to 1.4.0 (#1749) by @dependabot

    This release was made possible by the following contributors:

    @dependabot, @dependabot[bot], @heitorlessa, @leandrodamascena and Release bot

    Source code(tar.gz)
    Source code(zip)
  • v2.4.0(Nov 24, 2022)

    Summary

    This release introduces a brand new streaming utility to handle datasets larger than the available memory.

    This addresses scenarios where you want to process Amazon S3 objects as seekable data streams, with minimal memory consumption.

    S3Object basic usage

    Built-in data transformations

    Docs

    We've added support for popular data transformations to decompress and deserialize data (gzip, CSV and ZIP). This way you can transform the data while streaming, and only use the minimum amount of memory necessary.

    Built-in data transformations

    Bring your own data transformation

    Docs

    You can also create your own data transformations and add them to the pipeline. For example, here's how to use the ijson library to parse JSON as a data stream:

    Custom JSON data transformation

    We plan to support more data transformations in the future too!

    🌟 Would you like to see a specific data transformation supported in Powertools? Drop us a line in the python channel of our Discord.

    Changes

    🌟New features and non-breaking changes

    • feat(streaming): add new s3 streaming utility (#1719) by @rubenfonseca

    πŸ“œ Documentation updates

    • docs(idempotency): fix register_lambda_context order (#1747) by @heitorlessa
    • feat(streaming): add new s3 streaming utility (#1719) by @rubenfonseca

    πŸ”§ Maintenance

    • feat(streaming): add new s3 streaming utility (#1719) by @rubenfonseca
    • chore(deps-dev): bump mypy-boto3-cloudformation from 1.26.0.post1 to 1.26.11.post1 (#1746) by @dependabot
    • chore(deps-dev): bump mypy-boto3-lambda from 1.26.0.post1 to 1.26.12 (#1742) by @dependabot
    • chore(deps-dev): bump aws-cdk-lib from 2.50.0 to 2.51.1 (#1741) by @dependabot
    • chore(deps-dev): bump mypy-boto3-dynamodb from 1.26.0.post1 to 1.26.13.post16 (#1743) by @dependabot
    • chore(deps-dev): bump mypy-boto3-secretsmanager from 1.26.0.post1 to 1.26.12 (#1744) by @dependabot
    • chore(deps-dev): bump mypy-boto3-ssm from 1.26.4 to 1.26.11.post1 (#1740) by @dependabot
    • chore(deps-dev): bump types-requests from 2.28.11.4 to 2.28.11.5 (#1729) by @dependabot
    • chore(deps): bump aws-xray-sdk from 2.10.0 to 2.11.0 (#1730) by @dependabot
    • chore(deps-dev): bump mkdocs-material from 8.5.9 to 8.5.10 (#1731) by @dependabot

    This release was made possible by the following contributors:

    @dependabot, @dependabot[bot], @heitorlessa, @rubenfonseca and Release bot

    Source code(tar.gz)
    Source code(zip)
  • v2.3.1(Nov 21, 2022)

    Summary

    This patch release address an issue in Event Handler REST API to support dynamic routes with an equal sign (=).

    Big thanks to @baraksalomon for the bug report!

    Previously, a dynamic route containing = would result in a not found response (HTTP 404).

    Example

    from aws_lambda_powertools.event_handler import APIGatewayRestResolver
    from aws_lambda_powertools.utilities.typing import LambdaContext
    
    app = APIGatewayRestResolver()
    
    # NOTE: `/token/bXl0b2tlbg==` should be matched and not return 404 now
    @app.get("/token/<token>")
    def get_token(token: str):
        return {"received": f"{token}"}
    
    
    def lambda_handler(event: dict, context: LambdaContext) -> dict:
        return app.resolve(event, context)
    

    Changes

    πŸ› Bug and hot fixes

    • fix(apigateway): support dynamic routes with equal sign (RFC3986) (#1737) by @heitorlessa

    πŸ”§ Maintenance

    • chore(deps-dev): bump mypy-boto3-xray from 1.26.9 to 1.26.11.post1 (#1734) by @dependabot

    This release was made possible by the following contributors:

    @dependabot, @dependabot[bot], @heitorlessa and Release bot

    Source code(tar.gz)
    Source code(zip)
  • v2.3.0(Nov 17, 2022)

    Summary

    This release features: (1) Extract CloudWatch Logs sent to Kinesis streams, (2) Handling multiple exceptions in Event Handler REST, and (3) Log uncaught exceptions in Logger.

    Big thanks to new contributors: @ascopes (logger static typing), @bnsouza (expand testing docs in Event Handler), @kt-hr (bugfix multiple routes in Event Handler), @mangoes-git (bugfix for fetching SecretBinary)

    Event Source Data Class Extract CWL

    Parser Extract CWL

    Extracting CloudWatch Logs shipped to Kinesis Data Streams

    Docs

    This address a common use case of centralizing CloudWatch Logs from multiple regions or accounts using Kinesis Data Streams.

    You can now easily extract CloudWatch Logs (decompress, decode, etc.) using either Event Source Data Classes or Parser. It also seamless integrates with Batch so you can benefit from partial failure handling among other benefits, when processing large batch of logs from Kinesis.

    Event Source Data Classes

    from aws_lambda_powertools.utilities.batch import (BatchProcessor, EventType,
                                                       batch_processor)
    from aws_lambda_powertools.utilities.data_classes.kinesis_stream_event import (
        KinesisStreamRecord, extract_cloudwatch_logs_from_record)
    
    processor = BatchProcessor(event_type=EventType.KinesisDataStreams)
    
    
    def record_handler(record: KinesisStreamRecord):
        log = extract_cloudwatch_logs_from_record(record)
        return log.message_type == "DATA_MESSAGE"
    
    
    @batch_processor(record_handler=record_handler, processor=processor)
    def lambda_handler(event, context):
        return processor.response()
    

    Parser

    from aws_lambda_powertools.utilities.batch import (BatchProcessor, EventType,
                                                       batch_processor)
    from aws_lambda_powertools.utilities.parser.models import (
        KinesisDataStreamModel, KinesisDataStreamRecord)
    from aws_lambda_powertools.utilities.parser.models.kinesis import \
        extract_cloudwatch_logs_from_record
    
    processor = BatchProcessor(event_type=EventType.KinesisDataStreams, model=KinesisDataStreamModel)
    
    
    def record_handler(record: KinesisDataStreamRecord):
        log = extract_cloudwatch_logs_from_record(record)
        return log.messageType == "DATA_MESSAGE"
    
    
    @batch_processor(record_handler=record_handler, processor=processor)
    def lambda_handler(event, context):
        return processor.response()
    

    Handling multiple exceptions in Event Handler

    Docs

    You can now catch multiple exceptions when registering an exception handler.

    This is useful when you have related exceptions you want to handle the same way.

    import requests
    
    from aws_lambda_powertools.event_handler import (
        APIGatewayRestResolver,
        Response,
        content_types,
    )
    from aws_lambda_powertools.utilities.typing import LambdaContext
    
    app = APIGatewayRestResolver()
    
    
    @app.exception_handler([ValueError, requests.HTTPError])
    def handle_invalid_limit_qs(ex: ValueError | requests.HTTPError):  # receives exception raised
        metadata = {"path": app.current_event.path, "query_strings": app.current_event.query_string_parameters}
        logger.error(f"Malformed request: {ex}", extra=metadata)
    
        return Response(
            status_code=400,
            content_type=content_types.TEXT_PLAIN,
            body="Invalid request parameters.",
        )
    
    
    @app.get("/todos")
    def get_todos():
        max_results: int = int(app.current_event.get_query_string_value(name="limit", default_value=0))
    
        todos: requests.Response = requests.get(f"https://jsonplaceholder.typicode.com/todos?limit={max_results}")
        todos.raise_for_status()
    
        return {"todos": todos.json()}
    
    
    def lambda_handler(event: dict, context: LambdaContext) -> dict:
        return app.resolve(event, context)
    

    Logging uncaught exceptions

    Docs

    You can now automatically log uncaught exceptions using Logger via log_uncaught_exceptions=True.

    Logger will use Python's exception hook to log such exception with your pre-configured Logger instance for maximum context.

    import requests
    
    from aws_lambda_powertools import Logger
    from aws_lambda_powertools.utilities.typing import LambdaContext
    
    ENDPOINT = "http://httpbin.org/status/500"
    logger = Logger(log_uncaught_exceptions=True)
    
    
    def handler(event: dict, context: LambdaContext) -> str:
        ret = requests.get(ENDPOINT)
        # HTTP 4xx/5xx status will lead to requests.HTTPError
        # Logger will log this exception before this program exits non-successfully
        ret.raise_for_status()
    
        return "hello world"
    

    This would generate the following output in CloudWatch Logs

    {
        "level": "ERROR",
        "location": "log_uncaught_exception_hook:756",
        "message": "500 Server Error: INTERNAL SERVER ERROR for url: http://httpbin.org/status/500",
        "timestamp": "2022-11-16 13:51:29,198+0100",
        "service": "payment",
        "exception": "Traceback (most recent call last):\n  File \"<input>\", line 52, in <module>\n    handler({}, {})\n  File \"<input>\", line 17, in handler\n    ret.raise_for_status()\n  File \"<input>/lib/python3.9/site-packages/requests/models.py\", line 1021, in raise_for_status\n    raise HTTPError(http_error_msg, response=self)\nrequests.exceptions.HTTPError: 500 Server Error: INTERNAL SERVER ERROR for url: http://httpbin.org/status/500",
        "exception_name": "HTTPError"
    }
    

    Changes

    🌟New features and non-breaking changes

    • feat(parser): export Pydantic.errors through escape hatch (#1728) by @heitorlessa
    • feat(logger): log uncaught exceptions via system's exception hook (#1727) by @heitorlessa
    • feat(parser): extract CloudWatch Logs in Kinesis streams (#1726) by @heitorlessa
    • feat(event_sources): extract CloudWatch Logs in Kinesis streams (#1710) by @heitorlessa
    • feat(apigateway): multiple exceptions in exception_handler (#1707) by @sprkem

    πŸ“œ Documentation updates

    • docs(idempotency): add missing Lambda Context; note on thread-safe (#1732) by @heitorlessa
    • feat(logger): log uncaught exceptions via system's exception hook (#1727) by @heitorlessa
    • feat(event_sources): extract CloudWatch Logs in Kinesis streams (#1710) by @heitorlessa
    • feat(apigateway): multiple exceptions in exception_handler (#1707) by @sprkem
    • docs(apigateway): add all resolvers in testing your code section for accuracy (#1688) by @bnsouza
    • docs(homepage): update default value for POWERTOOLS_DEV (#1695) by @dreamorosi

    πŸ› Bug and hot fixes

    • fix(parameters): get_secret correctly return SecretBinary value (#1717) by @mangoes-git
    • fix(apigateway): support nested router decorators (#1709) by @kt-hr

    πŸ”§ Maintenance

    • chore(deps-dev): bump flake8-builtins from 2.0.0 to 2.0.1 (#1715) by @dependabot
    • chore(deps-dev): bump pytest-asyncio from 0.20.1 to 0.20.2 (#1723) by @dependabot
    • chore(deps-dev): bump mypy-boto3-appconfig from 1.25.0 to 1.26.0.post1 (#1722) by @dependabot
    • chore(deps-dev): bump mypy-boto3-ssm from 1.26.0.post1 to 1.26.4 (#1721) by @dependabot
    • chore(deps-dev): bump mypy-boto3-xray from 1.26.0.post1 to 1.26.9 (#1720) by @dependabot
    • chore(deps-dev): bump mypy-boto3-lambda from 1.25.0 to 1.26.0.post1 (#1705) by @dependabot
    • chore(deps-dev): bump mypy-boto3-s3 from 1.25.0 to 1.26.0.post1 (#1716) by @dependabot
    • chore(deps-dev): bump mypy-boto3-appconfigdata from 1.25.0 to 1.26.0.post1 (#1704) by @dependabot
    • chore(deps-dev): bump mypy-boto3-xray from 1.25.0 to 1.26.0.post1 (#1703) by @dependabot
    • chore(deps-dev): bump mypy-boto3-cloudwatch from 1.25.0 to 1.26.0.post1 (#1714) by @dependabot
    • chore(logger): overload inject_lambda_context with generics (#1583) by @ascopes
    • chore(deps-dev): bump types-requests from 2.28.11.3 to 2.28.11.4 (#1701) by @dependabot
    • chore(deps-dev): bump mypy-boto3-logs from 1.25.0 to 1.26.3 (#1702) by @dependabot
    • chore(deps-dev): bump pytest-xdist from 2.5.0 to 3.0.2 (#1655) by @dependabot
    • chore(deps-dev): bump mkdocs-material from 8.5.7 to 8.5.9 (#1697) by @dependabot
    • chore(deps-dev): bump flake8-comprehensions from 3.10.0 to 3.10.1 (#1699) by @dependabot
    • chore(deps-dev): bump types-requests from 2.28.11.2 to 2.28.11.3 (#1698) by @dependabot
    • chore(deps-dev): bump pytest-benchmark from 3.4.1 to 4.0.0 (#1659) by @dependabot
    • chore(deps-dev): bump mypy-boto3-secretsmanager from 1.25.0 to 1.26.0.post1 (#1691) by @dependabot
    • chore(deps): bump dependabot/fetch-metadata from 1.3.4 to 1.3.5 (#1689) by @dependabot
    • chore(deps-dev): bump flake8-bugbear from 22.10.25 to 22.10.27 (#1665) by @dependabot
    • chore(deps-dev): bump mypy-boto3-ssm from 1.25.0 to 1.26.0.post1 (#1690) by @dependabot

    This release was made possible by the following contributors:

    @ascopes, @bnsouza, @dependabot, @dependabot[bot], @dreamorosi, @heitorlessa, @kt-hr, @mangoes-git, @sprkem and Release bot

    Source code(tar.gz)
    Source code(zip)
  • v2.2.0(Nov 7, 2022)

    Summary

    This release features: (1) a new get_parameters_by_name function to fetch multiple Parameter Store parameters from distinct paths, and (2) a new EphemeralMetrics class for multi-tenancy and ISV use cases that require multiple metrics namespace.

    hero image

    Fetching distinct parameters by name

    Docs

    You can now fetch distinct parameters by their full name with get_parameters_by_name.

    Previously, you could only fetch multiple parameters by path via get_parameters. We also heard from customers they'd like more flexibility when fetching parameters.

    This new high level function has the following in mind:

    • Per parameter config: cache parameters differently while fetching them in batch
    • Decrypt all, none, or a few: transparent batch operations for when decryption is required without being worried on aggressive throttling
    • Fail-fast vs graceful error handling: choose whether to fail at the error, or aggregate errors so you can handle them gracefully

    Quick flow on how get_parameters_by_name decides which System Manager Parameter Store to use based on per parameter config (or global):

                               β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                           β”Œβ”€β”€β”€β–Ά  Decrypt entire batch  │─────┐
                           β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β”‚     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                           β”‚                                  β”œβ”€β”€β”€β”€β”€β–Ά GetParameters API  β”‚
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”‚     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
    β”‚   Split batch    │───┼──▢│ No decryption required β”‚β”€β”€β”€β”€β”€β”˜
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                           β”‚                                        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                           β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”           β”‚  GetParameter API  β”‚
                           └──▢│Decrypt some but not allβ”‚β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Άβ”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
                               β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜           β”‚ GetParameters API  β”‚
                                                                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
    

    EphemeralMetrics

    Docs

    You can use EphemeralMetrics class when looking to isolate multiple instances of metrics with distinct namespaces and/or dimensions.

    from aws_lambda_powertools.metrics import EphemeralMetrics, MetricUnit
    from aws_lambda_powertools.utilities.typing import LambdaContext
    
    metrics = EphemeralMetrics()
    
    
    @metrics.log_metrics
    def lambda_handler(event: dict, context: LambdaContext):
        metrics.add_metric(name="SuccessfulBooking", unit=MetricUnit.Count, value=1)
    

    By default, Metrics share metrics data across instances. This prevents common data deduplication due to CloudWatch EMF constraints on metric dimensions. However, this limits use cases where you want to create metrics for different applications within the same Lambda function, namely multi-tenancy - whether you use distinct metrics dimensions per metric or multiple metric namespaces.

    There are subtle differences between the two:

    | Feature | Metrics | EphemeralMetrics | | ----------------------------------------------------------------------------------------------------------- | ------- | ---------------- | | Share data across instances (metrics, dimensions, metadata, etc.) | Yes | - | | Default dimensions that persists across Lambda invocations (metric flush) | Yes | - |

    Changes

    🌟New features and non-breaking changes

    • feat(parameters): add get_parameters_by_name for SSM params in distinct paths (#1678) by @heitorlessa
    • feat(metrics): add EphemeralMetrics as a non-singleton option (#1676) by @heitorlessa

    πŸ“œ Documentation updates

    • feat(parameters): add get_parameters_by_name for SSM params in distinct paths (#1678) by @heitorlessa
    • feat(metrics): add EphemeralMetrics as a non-singleton option (#1676) by @heitorlessa

    πŸ”§ Maintenance

    • chore(deps-dev): bump aws-cdk-lib from 2.49.0 to 2.50.0 (#1683) by @dependabot
    • feat(parameters): add get_parameters_by_name for SSM params in distinct paths (#1678) by @heitorlessa
    • chore(deps-dev): bump mypy-boto3-dynamodb from 1.25.0 to 1.26.0.post1 (#1682) by @dependabot
    • chore(deps-dev): bump mypy-boto3-cloudformation from 1.25.0 to 1.26.0.post1 (#1679) by @dependabot

    This release was made possible by the following contributors:

    @dependabot, @dependabot[bot], @heitorlessa, Release bot

    Source code(tar.gz)
    Source code(zip)
  • v2.1.0(Oct 31, 2022)

    Summary

    This release features: (1) Logger UX enhancements, (2) New docs community section (We Made This), and (3) New issue form to accept customer references in our docs.

    Big thanks to new contributors πŸ‘: @nayaverdier (logger mypy fix), @pierskarsenbarg (Pulumi docs), and @dmwesterhoff (idempotency_function bug finding)

    Logger-hero

    Logger

    Simplifying log statements for additional metadata

    Docs

    You can now pass any arbitrary and ephemeral metadata as keyword-arguments when logging: logging.info("Incoming payment", customer_id="...")

    Previously, you had to use the extras parameter. This ergonomics improvement makes it easier to surface keys at the root of your structured log on a per log statement basis.

    This has been a long overdue and we're so so excited to have this finally out!

    Use RFC3339 date format with a single flag

    Docs

    You can now set use_rfc3339=True to instruct Logger to change the timestamp key to a value compliant with both RFC3339 and ISO8601: 2022-10-27T16:27:43.738+02:00

    Big thanks to @kishaningithub @JJSphar for the discussion and UX here!

    image

    New community docs section

    Docs

    You can now submit blog posts, workshops, videos, and sample projects featuring Lambda Powertools.

    Please check out the early submitted content from our awesome community!

    PS: We accept content in any language!

    image

    Become a customer reference

    You can now give us permission to list your organization name in the Lambda Powertools documentation..

    This helps us tremendously and new customers looking to learn who's using it. This permission is explicit for our documentation.

    image

    β™₯️

    Changes

    🌟New features and non-breaking changes

    • feat(logger): add use_rfc3339 and auto-complete formatter opts in Logger (#1662) by @heitorlessa
    • feat(logger): accept arbitrary keyword=value for ephemeral metadata (#1658) by @heitorlessa
    • feat(layers): add layer balancer script (#1643) by @rubenfonseca

    πŸ“œ Documentation updates

    • feat(logger): add use_rfc3339 and auto-complete formatter opts in Logger (#1662) by @heitorlessa
    • feat(logger): accept arbitrary keyword=value for ephemeral metadata (#1658) by @heitorlessa
    • docs(homepage): add Pulumi code example (#1652) by @pierskarsenbarg
    • docs(community): fix social handlers for Ran (#1654) by @ran-isenberg
    • docs(we-made-this): new community content section (#1650) by @leandrodamascena

    πŸ› Bug and hot fixes

    • fix(logger): fix unknown attributes being ignored by mypy (#1670) by @nayaverdier
    • fix(idempotency): idempotent_function should support standalone falsy values (#1669) by @heitorlessa
    • fix(deps): update build system to poetry-core (#1651) by @rubenfonseca

    πŸ”§ Maintenance

    • chore(deps-dev): bump aws-cdk-lib from 2.48.0 to 2.49.0 (#1671) by @dependabot
    • chore(deps-dev): bump aws-cdk-lib from 2.47.0 to 2.48.0 (#1664) by @dependabot
    • fix(deps): update build system to poetry-core (#1651) by @rubenfonseca
    • chore(deps-dev): bump flake8-variables-names from 0.0.4 to 0.0.5 (#1628) by @dependabot
    • chore(deps): bump docker/setup-qemu-action from 2.0.0 to 2.1.0 (#1627) by @dependabot
    • chore(deps-dev): bump pytest-asyncio from 0.16.0 to 0.20.1 (#1635) by @dependabot
    • chore(deps): bump peaceiris/actions-gh-pages from 3.8.0 to 3.9.0 (#1649) by @dependabot

    This release was made possible by the following contributors:

    @dependabot, @dependabot[bot], @heitorlessa, @leandrodamascena, @nayaverdier, @pierskarsenbarg, @ran-isenberg, @rubenfonseca and Release bot

    Source code(tar.gz)
    Source code(zip)
  • v2.0.0(Oct 24, 2022)

    Summary

    We are extremely happy to announce the smallest release version ever - v2.0.0 πŸŽ‰πŸŽ‰!

    The number one customer request was reducing package size. Some customers use a different tracing provider. Others used Parser (Pydantic) for data modelling and deep data validation instead of JSON Schema Validation. A few brought large machine learning models and every bit of space they can save matters.

    The number two request was ARM64 support. Customers want to benefit from performance and cost savings for their workloads. However, they don’t want to invest additional time testing and compiling dependencies they use daily for ARM64.

    We’ve spent the past 2 months optimizing as much as we could. We kept breaking changes to a minimum to make your transition to v2 as smooth as possible.

    For backwards incompatible changes, we’ve spent considerable effort making sure they are visible, why we implemented them, and and what to do if they affect you.

    Our sincerest appreciation for the community help and patience while we’ve worked on this release - Thank you ❀️!


    Table of contents

    What's New in V2

    Python compatibility

    We dropped support for Python 3.6. We highly recommend moving to the latest Python available in AWS Lambda (3.9).

    Package size reduction by 97.6%

    We now rely on AWS SDK available in the Lambda runtime, and all other dependencies are marked as optional.

    There are subtle but important differences in the installation experience - PyPi (all optional) and Lambda Layer (all included).

    PyPi

    The compressed package size is now approximately 240K (previously 10M).

    We updated each documentation to emphasize when an additional dependency is required (Tracer, Validation and Parser). If you prefer to install all of them, use pip install aws-lambda-powertools[all].

    Note. If you need to use newer AWS services or features not available in the Lambda runtime provided SDK, you'll need to bundle boto3 as a dependency.

    Lambda Layer

    The compressed package size is now approximately 2M (previously 17M).

    Lambda Layer includes all dependencies. They're also optimized for package size and speed (Pydantic now compiled with Cython for ~30-50% speed gain).

    ARM Support

    We now offer full support to ARM via Lambda Layer and SAR installation. All C-extension dependencies are compiled, optimized and tested against Lambda environment.

    PyPi and Lambda Layer available upon release notes event

    You can now safely subscribe to GitHub Release event to know when PyPi and Lambda Layer ARNs have the latest version.

    Previously, PyPi, Lambda Layers, and docs were updated after a release notes went live to GitHub (~15m completion). Due to Lambda Layer compilation (x86/ARM64), this process takes on average 30m longer.

    As such, we make releases prior to sharing release notes, guaranteeing for customers watching for GitHub Releases that Layer ARNs available in the documentation match PyPi releases (no more delays).

    Event Handler REST new features

    Multi-value header and cookies support

    When returning custom responses, you now can add a list of values for a header, including cookies.

    Event Handler will seamless adapt to the expected format based on resolver used, whether that is REST API, HTTP API, ALB, or Function URL.

    from http import HTTPStatus
    from uuid import uuid4
    
    import requests
    
    from aws_lambda_powertools.event_handler import (
        APIGatewayRestResolver,
        Response,
        content_types,
    )
    from aws_lambda_powertools.shared.cookies import Cookie
    from aws_lambda_powertools.utilities.typing import LambdaContext
    
    app = APIGatewayRestResolver()
    
    
    @app.get("/todos")
    def get_todos():
        todos: requests.Response = requests.get("https://jsonplaceholder.typicode.com/todos")
        todos.raise_for_status()
    
        dummy_transactions = [f"{uuid4()}", f"{uuid4()}", f"{uuid4()}"]
        multi_value_header = {"X-Transaction-Id": dummy_transactions}
    
        return Response(
            status_code=HTTPStatus.OK.value,  # 200
            content_type=content_types.APPLICATION_JSON,
            body=todos.json()[:10],
            headers=multi_value_header,  # NEW
            cookies=[Cookie(name="session_id", value="12345")],  # NEW
        )
    
    def lambda_handler(event: dict, context: LambdaContext) -> dict:
        return app.resolve(event, context)
    

    NOTE. For ALB, you have to explicitly enable multi-value headers in the target configuration.

    Trailing slash route support

    APIGatewayRestResolver now seamless support route resolution with trailing slashes: /todos/.

    Previously, requests with a trailing slash would return HTTP 404 due to route mismatch.

    Note. This was not necessary for HTTP API and ALB.

    Fully qualified names for Tracer subsegments

    tracer.capture_method or tracer.capture_lambda_handler decorators now use the decorated function or method fully qualified name as the subsegment name.

    This enables accurate traces for ABC or Protocol classes, where their method name will be the same but for distinct classes.

    image

    Backwards incompatible change in v2

    Here’s a quick view of deprecated features removed and backwards incompatible changes.

    | Area | Change | Code change required | IAM Permissions change required | | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | ------------------------------- | | Batch | Removed legacy SQS batch processor in favour of BatchProcessor. | Yes | - | | Environment variables | Removed legacy POWERTOOLS_EVENT_HANDLER_DEBUG in favour of POWERTOOLS_DEV. | - | - | | Event Handler | Updated headers response format due to multi-value headers and cookie support. | Tests only | - | | Event Source Data Classes | Replaced DynamoDBStreamEvent AttributeValue with native Python types. | Yes | - | | Feature Flags / Parameters | Updated AppConfig API calls due to GetConfiguration API deprecation. | - | Yes | | Idempotency | Updated partition key to include fully qualified function/method names. | - | - |

    Event Source Data Classes DynamoDBStreamEvent

    Upgrade guide

    You will now receive native Python types when accessing DynamoDB records via keys, new_image, and old_image attributes in DynamoDBStreamEvent.

    Previously, you'd receive an AttributeValue instance. For most customers, this made it difficult to handle Change Data Capture use cases due to having an additional step to deserialize data to Python native types (str, dict etc) when processing them.

    from aws_lambda_powertools.utilities.data_classes.dynamo_db_stream_event import (
        DynamoDBStreamEvent,
        DynamoDBRecordEventName
    )
    
    def send_to_sqs(data: Dict):
        body = json.dumps(data)
        ...
    
    @event_source(data_class=DynamoDBStreamEvent)
    def lambda_handler(event: DynamoDBStreamEvent, context):
        for record in event.records:
    
            # BEFORE
            new_image: Dict[str, AttributeValue] = record.dynamodb.new_image
            event_type: AttributeValue = new_image["eventType"].get_value
            if event_type == "PENDING":
                # deserialize attribute value into Python native type
                # NOTE: nested objects would need additional logic
                data = {k: v.get_value for k, v in image.items()}
                send_to_sqs(data)
    
            # AFTER
            new_image: Dict[str, Any] = record.dynamodb.new_image
            if new_image.get("eventType") == "PENDING":
                send_to_sqs(new_image)  # Here new_image is just a Python Dict type
    

    Feature Flags and Parameters AppConfig new IAM permission

    Upgrade guide. No code changes required.

    We replaced GetConfiguration API (now deprecated) with GetLatestConfiguration and StartConfigurationSession.

    As such, you must update your IAM Role permissions to allow the following IAM actions:

    • appconfig:GetLatestConfiguration
    • appconfig:StartConfigurationSession

    Idempotency partition key format

    Upgrade guide. No code changes required

    Similar to Tracer, we also updated Idempotency to use fully qualified name. This means that recent non-expired idempotent transactions will be ignored.

    image

    Deprecated features removed

    Legacy SQS Batch Processor

    Upgrade guide.

    We removed the deprecated PartialSQSProcessor class and sqs_batch_processor decorator in favour of BatchProcessor launched 11 months ago.

    BatchProcessor provides nearly the same developer experience while improving speed and security, as it natively integrates with Lambda ReportBachItemFailures feature.

    POWERTOOLS_EVENT_HANDLER_DEBUG environment variable

    We removed the POWERTOOLS_EVENT_HANDLER_DEBUG environment variable in favour of POWERTOOLS_DEV.

    POWERTOOLS_DEV consolidate additional features to ease prototyping against local or non-production environment.

    Changes

    🌟New features and non-breaking changes

    • feat(ci): release docs as alpha when doing a pre-release (#1624) by @rubenfonseca
    • feat(data-classes): replace AttributeValue in DynamoDBStreamEvent with deserialized Python values (#1619) by @shanab
    • feat(apigateway): ignore trailing slashes in routes (APIGatewayRestResolver) (#1609) by @walmsles
    • docs(homepage): auto-update Layer ARN on every release (#1610) by @rubenfonseca
    • feat(data_classes): add KinesisFirehoseEvent (#1540) by @ryandeivert

    πŸ“œ Documentation updates

    • fix(ci): remove v2 suffix from SAR apps (#1633) by @rubenfonseca
    • docs(upgrade_guide): add latest changes and quick summary (#1623) by @leandrodamascena
    • refactor(apigateway): remove POWERTOOLS_EVENT_HANDLER_DEBUG env var (#1620) by @heitorlessa
    • feat(data-classes): replace AttributeValue in DynamoDBStreamEvent with deserialized Python values (#1619) by @shanab
    • feat(apigateway): ignore trailing slashes in routes (APIGatewayRestResolver) (#1609) by @walmsles
    • docs(homepage): auto-update Layer ARN on every release (#1610) by @rubenfonseca
    • feat(data_classes): add KinesisFirehoseEvent (#1540) by @ryandeivert

    πŸ› Bug and hot fixes

    • fix(parser): S3Model Object Deleted omits size and eTag attr (#1638) by @barreeeiroo
    • fix(ci): remove v2 suffix from SAR apps (#1633) by @rubenfonseca

    πŸ”§ Maintenance

    • chore(deps-dev): bump aws-cdk-lib from 2.46.0 to 2.47.0 (#1629) by @dependabot
    • chore: merge v2 branch (#1625) by @rubenfonseca
    • docs(upgrade_guide): add latest changes and quick summary (#1623) by @leandrodamascena
    • chore(deps-dev): bump mypy-boto3-s3 from 1.24.76 to 1.24.94 (#1622) by @dependabot
    • chore(ci): remove v1 workflows (#1617) by @rubenfonseca
    • feat(apigateway): ignore trailing slashes in routes (APIGatewayRestResolver) (#1609) by @walmsles
    • chore(dep): add cfn-lint as a dev dependency (#1612) by @heitorlessa
    • chore(deps): remove email-validator; use Str over EmailStr in SES model (#1608) by @rubenfonseca
    • docs(homepage): auto-update Layer ARN on every release (#1610) by @rubenfonseca
    • chore(deps): bump release-drafter/release-drafter from 5.21.0 to 5.21.1 (#1611) by @dependabot

    This release was made possible by the following contributors:

    @barreeeiroo, @dependabot, @dependabot[bot], @heitorlessa, @kt-hr, @leandrodamascena, @rubenfonseca, @ryandeivert, @shanab, @walmsles, @ran-isenberg and Release bot

    Source code(tar.gz)
    Source code(zip)
  • v1.31.1(Oct 14, 2022)

    Summary

    This patch release is focused on Parser with SNS FIFO.

    When using SNS FIFO topics, SNS removes three fields, namely: SigningCertUrl, Signature, and SignatureVersion. As such, we're marking these fields as Optional to prevent ValidationError. Thanks to @plondino for flagging this.

    NOTE: In the future, we'll be looking at creating separate FIFO Models.

    Hacktoberfest

    Big thanks to @digitalisx and @senmm who helped addresses typos in the documentation. Thank you for helping make the documentation better for everyone πŸ’ž!

    Changes

    NOTE: This release will be available in PyPi in roughly 5m, and Lambda Layers across all AWS commercial regions in ~15m.

    πŸ“œ Documentation updates

    • docs(governance): allow community to suggest feature content (#1593) by @heitorlessa
    • docs(idempotency): "persisntence" typo (#1596) by @senmm
    • docs(idempotency) - Update invalid link target. (#1588) by @eldritchideen
    • docs(governance): new form to allow customers self-nominate as public reference (#1589) by @heitorlessa
    • docs(logger): fix typo. (#1587) by @digitalisx

    πŸ› Bug and hot fixes

    • fix(parser): loose validation on SNS fields to support FIFO (#1606) by @heitorlessa

    πŸ”§ Maintenance

    • docs(governance): allow community to suggest feature content (#1593) by @heitorlessa
    • chore(deps-dev): bump mypy-boto3-ssm from 1.24.81 to 1.24.90 (#1594) by @dependabot
    • chore(deps-dev): bump flake8-builtins from 1.5.3 to 2.0.0 (#1582) by @dependabot

    This release was made possible by the following contributors:

    @dependabot, @dependabot[bot], @digitalisx, @eldritchideen, @heitorlessa, @rubenfonseca, @senmm and Release bot

    Source code(tar.gz)
    Source code(zip)
  • v1.31.0(Oct 10, 2022)

    Summary

    This release fixes a bug in Metrics where subsequent instances didn't share a dimensions set - Huge thanks to @cfchou for flagging it and for being super proactive in creating a test ahead of time.

    This also adds support for Amazon Kinesis Firehose in Parser - big thanks to @ran-isenberg!

    image

    Changes

    🌟New features and non-breaking changes

    • feat(parser): add KinesisFirehoseModel (#1556) by @ran-isenberg

    πŸ› Bug and hot fixes

    • fix(metrics): ensure dimension_set is reused across instances (pointer) (#1581) by @heitorlessa

    πŸ”§ Maintenance

    • chore(deps-dev): bump types-requests from 2.28.11.1 to 2.28.11.2 (#1576) by @dependabot
    • chore(deps-dev): bump typing-extensions from 4.3.0 to 4.4.0 (#1575) by @dependabot

    This release was made possible by the following contributors:

    @am29d, @dependabot, @dependabot[bot], @heitorlessa, @ran-isenberg and Release bot

    Source code(tar.gz)
    Source code(zip)
  • v1.30.0(Oct 5, 2022)

    Summary

    This release adds support for (1) Lambda context in Batch processing, (2) Context sharing support in REST and GraphQL APIs, and (3) Consolidate features to make prototyping local/non-prod environments easier. Bug fixes and other minor improvements are at the bottom.

    image

    Accessing Lambda context in Batch processing

    Docs

    You can now opt-in to receive a Lambda context object if your function has a parameter named lambda_context.

    This unlocks long-running data pipelines, where you need to know how much time you have left before your function times out - thanks to @mew1033 for the feature request.

    from typing import Optional
    
    from aws_lambda_powertools.utilities.batch import (BatchProcessor, EventType,
                                                       batch_processor)
    from aws_lambda_powertools.utilities.data_classes.sqs_event import SQSRecord
    from aws_lambda_powertools.utilities.typing import LambdaContext
    
    processor = BatchProcessor(event_type=EventType.SQS) # or DynamoDB, Kinesis
    
    # lambda_context will be populated at runtime
    def record_handler(record: SQSRecord, lambda_context: Optional[LambdaContext] = None): ...
    
    @batch_processor(record_handler=record_handler, processor=processor)
    def lambda_handler(event, context: LambdaContext):
        return processor.response()
    

    New context support in Event Handler (REST and GraphQL)

    Docs

    You can now inject contextual information before or during event routing. This is the precursor to Middleware support in Event Handler. This unlocks two common use cases:

    • You split routes using Router() feature, and you need to pass data from App() without running into potential circular import issues
    • You have custom logic to run before every event, and want to expose the result to any registered route with minimal effort

    Thanks to @MaartenUreel for the feature request, and @benbridts, @gwlester, and @walmsles for the discussion to get to an optimal UX.

    UX

    Entrypoint: app.py

    import todos
    
    from aws_lambda_powertools.event_handler import APIGatewayRestResolver
    from aws_lambda_powertools.utilities.typing import LambdaContext
    
    app = APIGatewayRestResolver()
    app.include_router(todos.router)
    
    
    def lambda_handler(event: dict, context: LambdaContext) -> dict:
        app.append_context(is_admin=True)  # arbitrary number of key=value data
        return app.resolve(event, context)
    

    todos.py

    import requests
    from requests import Response
    
    from aws_lambda_powertools.event_handler.api_gateway import Router
    
    
    ENDPOINT = "https://jsonplaceholder.typicode.com/todos"
    
    router = Router()
    
    @router.get("/todos")
    def get_todos():
        is_admin: bool = router.context.get("is_admin", False)
        todos = {}
    
        if is_admin:
            todos: Response = requests.get(ENDPOINT)
            todos.raise_for_status()
            todos = todos.json()[:10]
    
        return {"todos": todos}
    

    Optimizing for non-production environments

    Docs

    Thanks to @pmarko1711, Logger now uses pretty-print when you set POWERTOOLS_DEV=1 environment variable. This also helps us consolidate features where we can make it easier to prototype locally or against a non-production environment.

    Debug mode simplified

    When raising bug reports, you can now get Lambda Powertools debug logs with POWERTOOLS_DEBUG=1. Previously, you had to change your source code to explicitly enable debugging in Powertools.

    Changes

    🌟New features and non-breaking changes

    • feat(logger): introduce POWERTOOLS_DEBUG for internal debugging (#1572) by @heitorlessa
    • feat(logger): include logger name attribute when copy_config_to_registered_logger is used (#1568) by @heitorlessa
    • feat(event-handler): context support to share data between routers (#1567) by @heitorlessa
    • feat(batch): inject lambda_context if record handler signature accepts it (#1561) by @heitorlessa
    • feat(logger): pretty-print JSON when POWERTOOLS_DEV is set (#1548) by @pmarko1711

    πŸ“œ Documentation updates

    • docs(homepage): introduce POWERTOOLS_DEV env var (#1569) by @heitorlessa
    • docs(parser): add JSON string field extension example (#1526) by @rubenfonseca

    πŸ› Bug and hot fixes

    • fix(apigateway): update Response class to require status_code only (#1560) by @heitorlessa
    • fix(event_sources): implement Mapping protocol on DictWrapper for better interop with existing middlewares (#1516) by @Tankanow
    • fix(typing): level arg in copy_config_to_registered_loggers (#1534) by @kbakk

    πŸ”§ Maintenance

    • chore(multiple): localize powertools_dev env logic and warning (#1570) by @heitorlessa
    • chore(deps-dev): bump types-requests from 2.28.11 to 2.28.11.1 (#1571) by @dependabot
    • chore(deps): bump dependabot/fetch-metadata from 1.3.3 to 1.3.4 (#1565) by @dependabot
    • chore(deps-dev): bump mkdocs-material from 8.5.3 to 8.5.4 (#1563) by @dependabot
    • chore(deps-dev): bump mypy-boto3-secretsmanager from 1.24.54 to 1.24.83 (#1557) by @dependabot
    • chore(deps-dev): bump pytest-cov from 3.0.0 to 4.0.0 (#1551) by @dependabot
    • chore(deps-dev): bump flake8-bugbear from 22.9.11 to 22.9.23 (#1541) by @dependabot
    • fix(event_sources): implement Mapping protocol on DictWrapper for better interop with existing middlewares (#1516) by @Tankanow
    • chore(deps-dev): bump mypy-boto3-ssm from 1.24.80 to 1.24.81 (#1544) by @dependabot
    • chore(deps-dev): bump mypy-boto3-ssm from 1.24.69 to 1.24.80 (#1542) by @dependabot
    • chore(deps-dev): bump mako from 1.2.2 to 1.2.3 (#1537) by @dependabot
    • chore(deps-dev): bump types-requests from 2.28.10 to 2.28.11 (#1538) by @dependabot
    • chore(deps): bump email-validator from 1.2.1 to 1.3.0 (#1533) by @dependabot
    • chore(deps-dev): bump mkdocs-material from 8.5.1 to 8.5.3 (#1532) by @dependabot
    • chore(deps): bump fastjsonschema from 2.16.1 to 2.16.2 (#1530) by @dependabot
    • chore(deps): bump codecov/codecov-action from 3.1.0 to 3.1.1 (#1529) by @dependabot
    • chore(deps): bump actions/setup-python from 3 to 4 (#1528) by @dependabot
    • chore(deps-dev): bump mypy-boto3-s3 from 1.24.36.post1 to 1.24.76 (#1531) by @dependabot

    This release was made possible by the following contributors:

    @Tankanow, @dependabot, @dependabot[bot], @heitorlessa, @kbakk, @pmarko1711, @rubenfonseca

    Source code(tar.gz)
    Source code(zip)
  • v1.29.2(Sep 19, 2022)

    Summary

    This patch release fixes a bug in the Serverless Application Repository (SAR) Extras Layer for customers using Parser/Pydantic, where the module wasn't available.

    Changes

    πŸ› Bug and hot fixes

    • fix(deps): bump dev dep mako version to address CVE-2022-40023 (#1524) by @rubenfonseca
    • fix(internal): SAR layer build not including pydantic (#1519) by @am29d

    πŸ”§ Maintenance

    • fix(deps): bump dev dep mako version to address CVE-2022-40023 (#1524) by @rubenfonseca
    • chore(deps): bump release-drafter/release-drafter from 5.20.1 to 5.21.0 (#1520) by @dependabot
    • chore(deps-dev): bump mkdocs-material from 8.5.0 to 8.5.1 (#1521) by @dependabot
    • chore(deps-dev): bump mypy-boto3-dynamodb from 1.24.60 to 1.24.74 (#1522) by @dependabot

    This release was made possible by the following contributors:

    @dependabot, @dependabot[bot], @rubenfonseca and Release bot

    Source code(tar.gz)
    Source code(zip)
  • v1.29.1(Sep 13, 2022)

    Due to a problem with the release pipeline, we had to yank the v1.29.0 release from PyPI. To fix the problem we are releasing v1.29.1 with no additional changes.

    Summary

    This release adds a new major integration with Apache Kafka (both Amazon Managed Streaming for Apache Kafka (MSK) and self-managed clusters). We also extended the Event Source Data Classes to support CloudWatch dashboard custom widgets.

    Apache Kafka

    Powertools can now seamlessly consume events sourced from Apache Kafka (MSK, self-managed). Apache Kafka as an event source operates similarly to using Amazon Simple Queue Service (Amazon SQS) or Amazon Kinesis.

    You can easily consume a Kafka event by using the KafkaEvent Data Class:

    image

    If you want extra flexibility and validation, you can also use the Pydantic models KafkaMskEventModel (for Apache MSK) and KafkaSelfManagedEventModel (for self-managed clusters): carbon (17) (1) If your Kafka event payload has a known structure, you could also leverage the KafkaEnvelope model.

    Thank you @lyoung-confluent and @ran-isenberg for your contribution!

    🌟 Would you like to see more integrations between Apache Kafka and Lambda Powertools? Drop us a line in the python channel of our Discord.

    CloudWatch dashboards custom widgets

    We also added support for handling events generated by CloudWatch dashboard custom widgets:

    carbon (18) (1)

    Big thanks to @sthuber90 for your contribution!

    Changes

    🌟New features and non-breaking changes

    • feat(parser): add KafkaMskEventModel and KafkaSelfManagedEventModel (#1499) by @ran-isenberg
    • feat(data-classes): add KafkaEvent and KafkaEventRecord (#1485) by @lyoung-confluent
    • feat(event_sources): add CloudWatch dashboard custom widget event (#1474) by @sthuber90
    • chore(ci): add workflow to suggest splitting large PRs (#1480) by @heitorlessa

    πŸ“œ Documentation updates

    • feat(parser): add KafkaMskEventModel and KafkaSelfManagedEventModel (#1499) by @ran-isenberg
    • feat(data-classes): add KafkaEvent and KafkaEventRecord (#1485) by @lyoung-confluent
    • feat(event_sources): add CloudWatch dashboard custom widget event (#1474) by @sthuber90

    πŸ”§ Maintenance

    • chore(deps): bump flake8-bugbear from 22.8.23 to 22.9.11 (#1512) by @dependabot
    • chore(deps): bump mkdocs-material from 8.4.3 to 8.4.4 (#1513) by @dependabot
    • chore(deps): bump types-requests from 2.28.9 to 2.28.10 (#1508) by @dependabot
    • chore(deps): bump aws-cdk-aws-apigatewayv2-integrations-alpha from 2.40.0a0 to 2.41.0a0 (#1510) by @dependabot
    • chore(deps-dev): bump mypy-boto3-ssm from 1.24.39.post2 to 1.24.69 (#1509) by @dependabot
    • chore(deps-dev): bump aws-cdk-lib from 2.40.0 to 2.41.0 (#1507) by @dependabot
    • chore(deps-dev): bump aws-cdk-aws-apigatewayv2-integrations-alpha from 2.39.1a0 to 2.40.0a0 (#1496) by @dependabot
    • chore(deps-dev): bump mkdocs-material from 8.4.2 to 8.4.3 (#1504) by @dependabot
    • chore(deps): bump pydantic from 1.10.1 to 1.10.2 (#1502) by @dependabot
    • chore(deps-dev): bump pytest from 7.1.2 to 7.1.3 (#1497) by @dependabot
    • chore(deps-dev): bump black from 22.6.0 to 22.8.0 (#1494) by @dependabot
    • chore(deps-dev): bump aws-cdk-lib from 2.39.1 to 2.40.0 (#1495) by @dependabot
    • chore(maintenance): add discord link to first PR and first issue (#1493) by @rubenfonseca
    • chore(deps): bump pydantic from 1.10.0 to 1.10.1 (#1491) by @dependabot
    • chore(deps-dev): bump flake8-variables-names from 0.0.4 to 0.0.5 (#1490) by @dependabot
    • chore(deps-dev): bump mkdocs-material from 8.4.1 to 8.4.2 (#1483) by @dependabot
    • chore(ci): create reusable docs publishing workflow (#1482) by @heitorlessa
    • chore(deps-dev): bump mypy-boto3-dynamodb from 1.24.55.post1 to 1.24.60 (#1481) by @dependabot
    • chore(ci): add workflow to suggest splitting large PRs (#1480) by @heitorlessa
    • chore(ci): add linter for GitHub Actions as pre-commit hook (#1479) by @heitorlessa
    • chore(deps-dev): bump black from 21.12b0 to 22.8.0 (#1515) by @dependabot
    • chore(deps-dev): bump mkdocs-material from 8.4.4 to 8.5.0 (#1514) by @dependabot
    • chore(ci): add linter for GitHub Actions as pre-commit hook (#1479) by @heitorlessa

    This release was made possible by the following contributors:

    @dependabot, @dependabot[bot], @heitorlessa, @leandrodamascena, @lyoung-confluent, @ran-isenberg, @rubenfonseca, @sthuber90 and Release bot

    Source code(tar.gz)
    Source code(zip)
  • v1.28.0(Aug 25, 2022)

    Summary

    This release brings major updates: upcoming v2 to drop Python 3.6 support, Lambda Function URL support in Parser(Pydantic), and.... πŸ₯ πŸ₯ πŸ₯ our new public Discord Server - join us

    Oh hey, please welcome Leandro as our new full-time maintainer - @leandrodamascenaπŸŽ‰

    Lambda Function URL support in Parser

    This release adds support for Lambda Function URL for Parser (Pydantic Model) - big thanks to @ran-isenberg. It extends the work previously done in v1.27.0 for Event Source Data Classes.

    image

    Upcoming v2 and breaking changes

    We’ve got a new RFC for our first major version v2.0.0 - aiming to end of September. We’re striving to make the bare minimum breaking changes given the timeframe we have. Please get acquainted with the breaking changes (e.g., legacy sqs_batch_processor, Event Handler to support multi-value headers) and do share your feedback.

    Improved documentation code snippets

    We know that a good documentation is critical for adopting any open-source project. We continue to make progress in rewriting code snippets to be more realistic, and apply our code quality standards like we do for any other change.

    In this release, we've refactored the JMESPath Functions,, Validation, Typing, and Middleware factory documentation to include real examples of using these features. You can follow progress on upcoming refactoring in our board of activities.

    :eyes: Take a look at this gigantic yet realistic all-in-one middleware combining Powertools features.

    Here’s a sneak peek:

    image

    image

    End-to-testing (E2E)

    We’ve published our internal framework to create and run E2E testing via GitHub Actions. This allow us to start working on further complement our functional testing, and soon begin wider coverage on integration tests. We’ll be documenting how customers can contribute E2E soon - you can find the internal details here.

    image

    Changes

    🌟New features and non-breaking changes

    • feat(parser): add support for Lambda Function URL (#1442) by @ran-isenberg

    πŸ“œ Documentation updates

    • docs(typing): snippets split, improved, and lint (#1465) by @leandrodamascena
    • docs(middleware-factory): snippets split, improved, and lint (#1451) by @leandrodamascena
    • chore(batch): deprecate sqs_batch_processor (#1463) by @rubenfonseca
    • docs(validation): snippets split, improved, and lint (#1449) by @leandrodamascena
    • feat(parser): add support for Lambda Function URL (#1442) by @ran-isenberg
    • chore(deps): bump pydantic from 1.9.1 to 1.9.2 (#1448) by @dependabot
    • docs(jmespath_util): snippets split, improved, and lint (#1419) by @leandrodamascena

    πŸ› Bug and hot fixes

    • fix(ci): calculate parallel jobs based on infrastructure needs (#1475) by @heitorlessa

    πŸ”§ Maintenance

    • chore(ci): prevent concurrent git update in critical workflows (#1478) by @heitorlessa
    • fix(ci): calculate parallel jobs based on infrastructure needs (#1475) by @heitorlessa
    • chore(deps-dev): bump flake8-bugbear from 22.8.22 to 22.8.23 (#1473) by @dependabot
    • chore(tests): enable end-to-end test workflow (#1470) by @heitorlessa
    • chore(governance): add Leandro as maintainer (#1468) by @leandrodamascena
    • chore(tests): build and deploy Lambda Layer stack once (#1466) by @heitorlessa
    • chore(batch): deprecate sqs_batch_processor (#1463) by @rubenfonseca
    • chore(tests): refactor E2E logger to ease maintenance, writing tests and parallelization (#1460) by @heitorlessa
    • docs(validation): snippets split, improved, and lint (#1449) by @leandrodamascena
    • chore(tests): refactor E2E tracer to ease maintenance, writing tests and parallelization (#1457) by @heitorlessa
    • chore(deps): bump release-drafter/release-drafter from 5.20.0 to 5.20.1 (#1458) by @dependabot
    • chore(deps): bump pydantic from 1.9.1 to 1.9.2 (#1448) by @dependabot

    This release was made possible by the following contributors:

    @am29d, @dependabot, @dependabot[bot], @heitorlessa, @leandrodamascena, @peterschutt, @ran-isenberg, @rubenfonseca, @sthuber90 and Release bot

    Source code(tar.gz)
    Source code(zip)
  • v1.27.0(Aug 5, 2022)

    Summary

    This is our feature release after our extended pause, we couldn't be more excited to bring you: Lambda Function URL, Metrics now supports up to 29 dimensions, and Pre-configured GitPod.io dev environment for contributors.

    Huge thanks to a new contributor: @leandrodamascena

    Event Handler - Lambda Function URL

    You can now use LambdaFunctionUrlResolver to seamless develop with Lambda Function URL. Developer experience remains exactly the same for other REST Event Handlers, making it easier to switch between Application Load Balancer, and API Gateway (REST and HTTP) APIs.

    Correlation ID support and documentation have been documented accordingly - here's how it looks like!

    image

    Improved onboarding to first contribution

    For new contributors and those new to Python, @leandrodamascena contributed a pre-configured Cloud-based development environment based on Gitpod.io product. When visiting our contribution guide, you will now see a link to instantly spin up a dev environment pre-configured with all dependencies, linters, and git pre-commit hooks to fast track reviews.

    image

    image

    Increasing Metrics dimension limit to 29

    Amazon CloudWatch Metrics made tons of improvements 2 days ago. This release takes advantage of the new metric dimension to increase our validation limit to 29 (MAX-1). By default, we add a service dimension to more easily identify metrics for a given service, hence the limit being 29 and not 30.

    Next release

    We plan on closing the gap on releases with Lambda Layer versioning by automatically generating documentation for all regions. This means publishing 5 additional regions customers asked for support and making it easier to find out which Lambda Layer has which PyPi version. Beyond that, docs and Event Handler improvements, and maybe a surprise if time allows.

    Changes

    🌟New features and non-breaking changes

    • feat(metrics): update max user-defined dimensions from 9 to 29 (#1417) by @leandrodamascena
    • feat(ci): create reusable changelog generation (#1418) by @heitorlessa
    • feat(event_handlers): Add support for Lambda Function URLs (#1408) by @rubenfonseca

    πŸ“œ Documentation updates

    • feat(metrics): update max user-defined dimensions from 9 to 29 (#1417) by @leandrodamascena
    • feat(event_handlers): Add support for Lambda Function URLs (#1408) by @rubenfonseca
    • chore(docs): remove pause sentence from roadmap (#1409) by @rubenfonseca

    πŸ› Bug and hot fixes

    • fix(event_sources): add test for Function URL AuthZ (#1421) by @rubenfonseca

    πŸ”§ Maintenance

    • fix(event_sources): add test for Function URL AuthZ (#1421) by @rubenfonseca
    • chore(deps): bump constructs from 10.1.1 to 10.1.66 (#1414) by @dependabot
    • chore(docs): remove pause sentence from roadmap (#1409) by @rubenfonseca
    • chore(governance): remove devcontainer in favour of gitpod.io (#1411) by @leandrodamascena
    • chore(governance): add pre-configured dev environment with GitPod.io to ease contributions (#1403) by @leandrodamascena
    • chore(deps): bump constructs from 10.1.1 to 10.1.65 (#1407) by @dependabot
    • chore(deps-dev): bump types-requests from 2.28.6 to 2.28.7 (#1406) by @dependabot
    • chore(deps): bump constructs from 10.1.1 to 10.1.64 (#1405) by @dependabot
    • chore(deps): bump attrs from 21.4.0 to 22.1.0 (#1397) by @dependabot
    • chore(deps): bump constructs from 10.1.1 to 10.1.63 (#1402) by @dependabot
    • chore(deps-dev): bump types-requests from 2.28.5 to 2.28.6 (#1401) by @dependabot
    • chore(deps): bump constructs from 10.1.1 to 10.1.60 (#1399) by @dependabot
    • chore(deps): bump jsii from 1.57.0 to 1.63.2 (#1400) by @dependabot

    This release was made possible by the following contributors:

    @dependabot, @dependabot[bot], @heitorlessa, @leandrodamascena, @rubenfonseca, Docs and Release bot

    Source code(tar.gz)
    Source code(zip)
  • v1.26.7(Jul 29, 2022)

    Summary

    This release adds a change to the idempotency utility, expiring in-progress executions if the Lambda function times out halfway through.

    The new feature requires no code changes. However, if you're using just the idempotent_function decorator, you will want to register the Lambda context on your handler to take advantage of this feature:

    To prevent against extended failed retries when a Lambda function times out, Powertools now calculates and includes the remaining invocation available time as part of the idempotency record. If a second invocation happens after this timestamp, and the record is marked as INPROGRESS, we will execute the invocation again as if it was in the EXPIRED state (e.g, expire_seconds field elapsed).

    We also enabled static analysis (mypy) on the new statically typed documentation snippets - big thanks to @VictorCovalski for spotting one issue in Event Handler that later led to 50 other fixes.

    Oh! Did I also tell you we’ve got a new full time maintainer? Big welcome to Ruben :wink: https://twitter.com/rubenfonseca

    Changes

    🌟New features and non-breaking changes

    • feat(idempotency): handle lambda timeout scenarios for INPROGRESS records (#1387) by @rubenfonseca

    πŸ“œ Documentation updates

    • feat(idempotency): handle lambda timeout scenarios for INPROGRESS records (#1387) by @rubenfonseca
    • docs(examples): enforce and fix all mypy errors (#1393) by @heitorlessa

    πŸ› Bug and hot fixes

    • fix(event_handlers): ImportError when importing Response from top-level event_handler (#1388) by @VictorCovalski

    πŸ”§ Maintenance

    • chore(deps): bump jsii from 1.57.0 to 1.63.1 (#1390) by @dependabot
    • chore(deps): bump constructs from 10.1.1 to 10.1.59 (#1396) by @dependabot
    • chore(deps-dev): bump flake8-isort from 4.1.1 to 4.1.2.post0 (#1384) by @dependabot
    • docs(examples): enforce and fix all mypy errors (#1393) by @heitorlessa
    • chore(ci): drop 3.6 from workflows (#1395) by @heitorlessa
    • chore(maintainers): add Ruben as a maintainer (#1392) by @rubenfonseca
    • chore(ci): add conditional to skip pypi release (#1366) by @heitorlessa

    This release was made possible by the following contributors:

    @VictorCovalski, @dependabot, @dependabot[bot], @heitorlessa, @rubenfonseca and Release bot

    Source code(tar.gz)
    Source code(zip)
  • v1.26.6(Jul 25, 2022)

    Third-time is the luck of the Irish (new security release mechanisms)

    Summary

    This patch release addresses an internal issue for Event Handler REST API compression feature when headers value is None -- Huge thanks for spotting and fixing it as a first-time contributor @tbuatois!!

    We now have public Lambda Layers deployed across all AWS commercial regions (22) - stellar multi-month work by @am29d. We have one last work to complete before we share the additional ARNs with everyone -- automate documentation generation for every Layer Version::Region mapping.

    image

    Lastly on Operational Excellence, we've implemented further security layers for GitHub Actions following GitHub's Hardening Guide, and created a Maintenance Issue template to make tech debt work more visible to all customers and future maintainers.

    Changes

    πŸ› Bug and hot fixes

    • fix(event_handlers): handle lack of headers when using auto-compression feature (#1325) by @tbuatois

    πŸ”§ Maintenance

    • chore(ci): use gh environment for beta and prod layer deploy (#1356) by @am29d
    • chore(ci): remove core group from codeowners (#1358) by @heitorlessa
    • chore(ci): use OIDC and encrypt release secrets (#1355) by @heitorlessa
    • chore(ci): introduce codeowners (#1352) by @heitorlessa
    • chore(ci): lockdown workflow_run by origin (#1350) by @heitorlessa
    • chore(deps): bump constructs from 10.1.1 to 10.1.52 (#1343) by @dependabot
    • chore(deps-dev): bump mypy-boto3-cloudwatch from 1.24.0 to 1.24.35 (#1342) by @dependabot
    • chore(layers): replace layers account secret (#1329) by @heitorlessa
    • chore(governance): add new maintenance issue template for tech debt and governance (#1326) by @heitorlessa
    • chore(layers): expand to all aws commercial regions (#1324) by @heitorlessa

    This release was made possible by the following contributors:

    @am29d, @dependabot, @dependabot[bot], @heitorlessa, @tbuatois and Release bot

    Source code(tar.gz)
    Source code(zip)
  • v1.26.5(Jul 20, 2022)

    Summary

    This patch release addresses a packaging regression that introduced mypy boto3 typing packages as prod dependencies instead of dev dependencies -- huge thanks to @tb102122 for spotting this 30m ago.

    Everything else in this release is related to operational excellence on improving GitHub Actions workflow performance, and last steps to make our new Lambda Layer release pipeline ready.

    Changes

    πŸ› Bug and hot fixes

    • fix(deps): correct mypy types as dev dependency (#1322) by @heitorlessa
    • fix(ci): keep layer version permission resource (#1318) by @am29d
    • fix(ci): lambda layer workflow release version and conditionals (#1316) by @am29d
    • fix(ci): remove additional quotes in PR action (#1317) by @heitorlessa
    • fix(ci): install poetry before calling setup/python with cache (#1315) by @rubenfonseca

    πŸ”§ Maintenance

    • fix(deps): correct mypy types as dev dependency (#1322) by @heitorlessa
    • fix(ci): lambda layer workflow release version and conditionals (#1316) by @am29d
    • chore(ci): adds caching when installing python dependencies (#1311) by @rubenfonseca

    This release was made possible by the following contributors:

    @am29d, @dependabot[bot], @heitorlessa, @rubenfonseca and Release bot

    Source code(tar.gz)
    Source code(zip)
  • v1.26.4(Jul 18, 2022)

    Summary

    This release continues our focus on Operational Excellence with several GitHub Actions to improve our automation on governance tasks (e.g., PR labelling, security, release automation, dependencies, etc.).

    We also moved the Lambda Layer release pipeline to Github Actions (#1278). This will expand the official Lambda Layer to all commercial AWS regions, once operational. Huge thanks to @am29d!

    In addition, we laid the groundwork for end-to-end (E2E) testing, starting with the core features (logger, metrics, tracer). Thank you @mploski!

    Changes

    πŸ› Bug and hot fixes

    • fix(parser): raise ValidationError when SNS->SQS keys are intentionally missing (#1299) by @rubenfonseca
    • fix(ci): fixes typos and small issues on github scripts (#1302) by @rubenfonseca

    πŸ”§ Maintenance

    • chore(ci): increase release automation and limit to one manual step (#1297) by @heitorlessa
    • chore(deps): bump constructs from 10.1.1 to 10.1.49 (#1308) by @dependabot
    • chore(deps): bump fastjsonschema from 2.15.3 to 2.16.1 (#1309) by @dependabot
    • fix(parser): raise ValidationError when SNS->SQS keys are intentionally missing (#1299) by @rubenfonseca
    • chore(deps): bump constructs from 10.1.1 to 10.1.46 (#1306) by @dependabot
    • chore(ci): lockdown 3rd party workflows to pin sha (#1301) by @heitorlessa
    • chore(ci): automatically add area label based on title (#1300) by @rubenfonseca
    • chore(deps): bump jsii from 1.61.0 to 1.62.0 (#1294) by @dependabot
    • chore(ci): add end to end testing mechanism (#1247) by @mploski
    • chore(deps-dev): bump mypy-boto3-appconfig from 1.24.0 to 1.24.29 (#1295) by @dependabot

    This release was made possible by the following contributors:

    @am29d, @dependabot, @dependabot[bot], @heitorlessa, @mploski and @rubenfonseca

    Source code(tar.gz)
    Source code(zip)
  • v1.26.3(Jul 4, 2022)

    Summary

    This patch release addresses an issue with Lambda handlers with custom signatures (*args, **kwargs) when using logger.inject_lambda_context decorator - thanks to @RonRandemaker

    Thanks to @kbakk, we now have officially documented how to inject standard logging record attributes when using Logger.

    This release continues our focus on Operational Excellence with several GitHub Actions to improve our automation on governance tasks (e.g., PR labeling, Comments on issues closed, Markdown linting rules etc.).

    Last but not least, we've started revamping all documentation examples, including making some of them more realistic to how customers would code.

    image

    Ah! Before I forget...huge thanks to new contributors @RonRademaker, @kbakk.

    Changes

    πŸ“œ Documentation updates

    • docs(metrics): snippets split, improved, and lint (#1272) by @heitorlessa
    • docs(logger): document enriching logs with logrecord attributes (#1271) by @kbakk
    • docs(logger): snippets split, improved, and lint (#1262) by @heitorlessa
    • docs(tracer): snippets split, improved, and lint (#1261) by @heitorlessa
    • docs(tracer): split and lint code snippets (#1260) by @heitorlessa
    • docs(lint): add markdownlint rules and automation (#1256) by @heitorlessa

    πŸ› Bug and hot fixes

    • fix(logger): preserve std keys when using custom formatters (#1264) by @heitorlessa
    • fix(logger): support additional args for handlers when injecting lambda context (#1276) by @RonRademaker

    πŸ”§ Maintenance

    • chore(deps): bump dependabot/fetch-metadata from 1.3.2 to 1.3.3 (#1273) by @dependabot
    • chore(deps-dev): bump flake8-bugbear from 22.6.22 to 22.7.1 (#1274) by @dependabot
    • chore(deps): bump aws-xray-sdk from 2.9.0 to 2.10.0 (#1270) by @dependabot
    • chore(deps): bump dependabot/fetch-metadata from 1.1.1 to 1.3.2 (#1269) by @dependabot
    • docs(logger): snippets split, improved, and lint (#1262) by @heitorlessa
    • docs(tracer): snippets split, improved, and lint (#1261) by @heitorlessa
    • docs(tracer): split and lint code snippets (#1260) by @heitorlessa
    • docs(lint): add markdownlint rules and automation (#1256) by @heitorlessa
    • chore(deps-dev): bump flake8-bugbear from 22.4.25 to 22.6.22 (#1258) by @dependabot
    • chore(deps-dev): bump mypy-boto3-dynamodb from 1.24.0 to 1.24.12 (#1255) by @dependabot
    • chore(deps-dev): bump mypy-boto3-secretsmanager from 1.24.0 to 1.24.11.post3 (#1252) by @dependabot
    • chore(test-perf): use pytest-benchmark to improve reliability (#1250) by @heitorlessa

    This release was made possible by the following contributors:

    @RonRademaker, @dependabot, @dependabot[bot], @heitorlessa and @kbakk

    Source code(tar.gz)
    Source code(zip)
  • v1.26.2(Jun 16, 2022)

    Summary

    This release addresses CORS Pre-flight issue when using Event Handler with ALB. Prior to this release, ALB would return HTTP 502 if Lambda would return a null body for a Pre-flight (HTTP OPTIONS) request. This release sets body to an empty string for compliance, and it doesn't affect API Gateway/AppSync features.

    Shoutout to @francispeabody for spotting this behaviour, as CORS Specification doesn't dictate whether there should be a response or not leaving to each service to make their own judgement.

    Changes

    πŸ› Bug and hot fixes

    • fix(event-handler): body to empty string in CORS preflight (ALB non-compliant) (#1249) by @heitorlessa

    πŸ”§ Maintenance

    • chore(deps): bump actions/setup-python from 3 to 4 (#1244) by @dependabot
    • chore(deps-dev): bump mypy-boto3-appconfig from 1.23.0.post1 to 1.24.0 (#1233) by @dependabot
    • chore(deps-dev): bump mypy-boto3-dynamodb from 1.23.0.post1 to 1.24.0 (#1234) by @dependabot
    • chore(deps-dev): bump mypy-boto3-secretsmanager from 1.23.8 to 1.24.0 (#1232) by @dependabot
    • chore(deps-dev): bump mypy-boto3-ssm from 1.23.0.post1 to 1.24.0 (#1231) by @dependabot
    • chore(deps-dev): bump mypy from 0.960 to 0.961 (#1241) by @dependabot
    • chore(metrics): revert dimensions test and split (#1243) by @heitorlessa

    This release was made possible by the following contributors:

    @am29d, @dependabot, @dependabot[bot] and @heitorlessa

    Source code(tar.gz)
    Source code(zip)
  • v1.26.1(Jun 7, 2022)

    Summary

    This is an emergency release to ensure Metrics utility raises an exception when customers add 9 user-defined metric dimensions.

    Huge thanks to @dnlopes for spotting this bug thus warranting this emergency release.

    Background

    Lambda Powertools adds a service CloudWatch Metric Dimension on top of user-defined dimensions (max 8). Prior to this release, customers were able to add 9 user-defined dimensions leading to a total of 10 metric dimensions. This makes CloudWatch EMF fail silently and not convert them as metrics.

    The confusion stems from CloudWatch Metrics and CloudWatch Logs EMF having different limits. CloudWatch Metrics support 10 dimensions while CloudWatch EMF (async) support 9. For EMF, all validation must happen client side as EMF fails silently should any limit is hit and no feedback is given.

    We provided this feedback to the CloudWatch EMF team, and they're looking at ways to improve customers feedback on the server-side so it's less reliant on client-side validation.

    Changes

    πŸ“œ Documentation updates

    • fix(metrics): raise SchemaValidationError for >8 metric dimensions (#1240) by @heitorlessa
    • docs(maintainers): initial maintainers playbook (#1222) by @heitorlessa

    πŸ› Bug and hot fixes

    • fix(metrics): raise SchemaValidationError for >8 metric dimensions (#1240) by @heitorlessa

    πŸ”§ Maintenance

    • docs(maintainers): initial maintainers playbook (#1222) by @heitorlessa
    • chore(deps-dev): bump mypy from 0.950 to 0.960 (#1224) by @dependabot
    • chore(deps-dev): bump mypy-boto3-secretsmanager from 1.23.0.post1 to 1.23.8 (#1225) by @dependabot

    This release was made possible by the following contributors:

    @dependabot, @dependabot[bot] and @heitorlessa

    Source code(tar.gz)
    Source code(zip)
  • v1.26.0(May 20, 2022)

    Summary

    This release unblocks customers using Parameters utility when trying to use VPC private endpoints, or looking to bring their own boto3 clients to ease testing, custom settings, etc.

    Documentation

    User Experience

    image

    As part of this release, we've made progress on a few governance topics such as a new dedicated board of activities and our first iteration of the new roadmap process - you can read more details on our current pause message update.

    image

    image

    Changes

    🌟New features and non-breaking changes

    • feat(parameters): accept boto3_client to support private endpoints and ease testing (#1096) by @ran-isenberg

    πŸ“œ Documentation updates

    • feat(parameters): accept boto3_client to support private endpoints and ease testing (#1096) by @ran-isenberg
    • docs(roadmap): add new roadmap section (#1204) by @heitorlessa

    πŸ› Bug and hot fixes

    • fix(docs): remove Slack link (#1210) by @sthulb
    • fix(batch): missing space in BatchProcessingError message (#1201) by @mew1033
    • fix(batch): docstring fix for success_handler() record parameter (#1202) by @peterschutt

    πŸ”§ Maintenance

    • chore(deps-dev): bump mypy-boto3-secretsmanager from 1.21.34 to 1.23.0.post1 (#1218) by @dependabot
    • chore(deps-dev): bump mypy-boto3-appconfig from 1.21.34 to 1.23.0.post1 (#1219) by @dependabot
    • chore(deps-dev): bump mypy-boto3-ssm from 1.21.34 to 1.23.0.post1 (#1220) by @dependabot
    • chore(deps): bump pydantic from 1.9.0 to 1.9.1 (#1221) by @dependabot
    • feat(parameters): accept boto3_client to support private endpoints and ease testing (#1096) by @ran-isenberg
    • chore(deps): bump email-validator from 1.1.3 to 1.2.1 (#1199) by @dependabot

    This release was made possible by the following contributors:

    @dependabot, @dependabot[bot], @heitorlessa, @mew1033, @peterschutt, @ran-isenberg and @sthulb

    Source code(tar.gz)
    Source code(zip)
  • v1.25.10(Apr 29, 2022)

    Summary

    This patch release addresses the following main issues:

    • Event Handler: Previously, Lambda handlers decorated with event source data class that also use Event Handler were incompatible
    • Event Handler: Raising a ServiceError like NotFound as part of an exception handler ended up propagating a ServiceError instead of converting into a non-successful response (e.g., 4xx)
    • Event Source Data Classes: Missing date field type annotation in SESEvent to string instead of list, and missing fields like cc, bcc, sender, and reply_to, and dkim related fields
    • Parameters: Previously, customers couldn't easily clear parameters (SSM, Secrets Manager, AppConfig, DynamoDB) cache as part of their automated tests

    image

    Changes

    🌟 New features and non-breaking changes

    • feat(parameters): add clear_cache method for providers (#1194) by @heitorlessa

    πŸ› Bug and hot fixes

    • fix(data-classes): fix SES date field typing and add missing fields (#1045) by @michaelbrewer
    • fix(deps-dev): remove jmespath due to dev deps conflict (#1148) by @sthulb
    • fix(deps): ignore boto3 updates until needed (#1151) by @sthulb
    • fix(event_handler): allow event source data class events (#1159) by @michaelbrewer
    • fix(event_handler): exception_handler to handle ServiceError exceptions (#1160) by @michaelbrewer

    πŸ”§ Maintenance

    • chore(deps-dev): bump flake8-bugbear from 22.1.11 to 22.4.25 (#1156) by @dependabot
    • chore(deps-dev): bump mypy from 0.942 to 0.950 (#1162) by @dependabot
    • chore(deps-dev): bump flake8-eradicate from 1.2.0 to 1.2.1 (#1158) by @dependabot
    • chore(deps): bump github/codeql-action from 1 to 2 (#1154) by @dependabot
    • chore(ci): disable mergify configuration after breaking changes (#1188) by @heitorlessa
    • fix(deps): ignore boto3 updates until needed (#1151) by @sthulb
    • chore(deps-dev): bump mkdocs-git-revision-date-plugin from 0.3.1 to 0.3.2 (#1146) by @dependabot
    • chore(deps): bump codecov/codecov-action from 3.0.0 to 3.1.0 (#1143) by @dependabot
    • chore(deps-dev): bump xenon from 0.8.0 to 0.9.0 (#1145) by @dependabot
    • chore(deps-dev): bump mypy from 0.931 to 0.942 (#1133) by @dependabot
    • fix(deps-dev): remove jmespath due to dev deps conflict (#1148) by @sthulb

    This release was made possible by the following contributors:

    @dependabot, @dependabot[bot], @heitorlessa, @huonw, @michaelbrewer, and @sthulb

    Source code(tar.gz)
    Source code(zip)
  • v1.25.9(Apr 21, 2022)

    Summary

    Quick patch release to fix jmespath pip marker to exact Python 3.6 version to address conflict in later versions.

    Changes

    πŸ› Bug and hot fixes

    • fix(deps): correct py36 marker for jmespath

    This release was made possible by the following contributors:

    @dependabot[bot], @heitorlessa and @mergify[bot]

    Source code(tar.gz)
    Source code(zip)
  • v1.25.8(Apr 21, 2022)

    Summary

    This patch release updates jmespath marker to address a dependency conflict for customers bundling the latest version of boto3, as part of their Lambda deployment package. Boto's latest version upgraded jmespath to 1.0 which drops support for Python 3.6.

    Changes

    πŸ“œ Documentation updates

    • docs(layer): remove link from clipboard button (#1135) by @heitorlessa

    πŸ› Bug and hot fixes

    • fix(deps): update jmespath marker to support 1.0 and py3.6 (#1139) by @michaelbrewer

    πŸ”§ Maintenance

    • chore(deps-dev): bump mkdocs-material from 8.2.4 to 8.2.7 (#1131) by @dependabot
    • chore(deps-dev): bump pytest from 6.2.5 to 7.0.1 (#1063) by @dependabot

    This release was made possible by the following contributors:

    @Dunedan, @dependabot, @dependabot[bot], @heitorlessa, @corey-cole, @sthulb, and @michaelbrewer

    Source code(tar.gz)
    Source code(zip)
  • v1.25.7(Apr 8, 2022)

    Summary

    This patch release addresses bugs on Logger, Event Handler REST API, Idempotency, and a static type annotation on middleware factory utility.

    We also updated our issues to use the new GitHub Issue Form, including a new Ask a Question, and Static typing mismatch report. The latter addresses an increase of bug reports that are better categorized as static typing mismatch - this will help us understand whether we might be able to support both Mypy and Pyright in the future.

    image

    Logger

    Thanks to @eliasbrange, customers using clear_state=True will no longer be affected by custom keys being accidentally removed in subsequent invocations - a regression introduced two releases ago. We improved tests on clear_state functionality.

    Idempotency

    Thanks to @ojongerius, customers changing the incoming event within the Lambda handler will no longer impact idempotency hash calculation. This was caused by Python's default pass by reference behaviour.

    Event Handler REST API

    Thanks to @sthuber90, customers receiving API calls that contain whitespace in path parameters - /customer/power tools - will no longer return 404s. Despite API Gateway correctly decoding whitespace, our regex for safe and unsafe URI chars missed an explicit whitespace.

    Middleware Factory

    Thanks to @huonw, Mypy customers using --strict mode will no longer complain about the return type of custom decorators using lambda_handler_decorator. It's a hard problem to solve considering our support for Python 3.6+. Later in the year, we'll look into the value-effort ratio of supporting strict mode, and how to gradually bring typing_extensions package across the board.

    Huge thanks to new contributors: @sthuber90, @eliasbrange, and @ojongerius

    Changes

    πŸ› Bug and hot fixes

    • fix(api_gateway): allow whitespace in routes' path parameter (#1099) by @sthuber90
    • fix(middleware_factory): ret type annotation for handler dec (#1066) by @huonw
    • fix(logger): clear_state should keep custom key formats (#1095) by @eliasbrange
    • fix(idempotency): pass by value on idem key to guard inadvertent mutations (#1090) by @ojongerius

    This release was made possible by the following contributors:

    @eliasbrange, @heitorlessa, @huonw, @mergify[bot], @ojongerius and @sthuber90

    Source code(tar.gz)
    Source code(zip)
  • v1.25.6(Apr 1, 2022)

    Summary

    This patch release fixes a regression in Logger introduced in 1.25.3 when using clear_state=True. A fix for customer formatters introduced in 1.25.3 ended up introducing a regression, where standard keys like level, location and timestamp no longer being present when using clear_state=True for the default Logger formatter.

    Thanks to @alexanderluiscampino for a high quality bug report, and @HAK-CODE for confirming the issue two hours ago, we managed to reproduce it quickly, improved our tests, and thus making this emergency release.

    Changes

    πŸ› Bug and hot fixes

    • fix(logger): clear_state regression on absent standard keys (#1088) by @heitorlessa

    This release was made possible by the following contributors:

    @heitorlessa and @mergify[bot]

    Source code(tar.gz)
    Source code(zip)
  • v1.25.5(Mar 18, 2022)

    Summary

    Thanks to @DandyDev, this emergency release fixes a regression on logger utils to clone formatting configuration from Powertools Logger to external Loggers.

    Changes

    πŸ› Bug and hot fixes

    • fix(logger-utils): regression on exclude set leading to no formatter (#1080) by @mploski

    This release was made possible by the following contributors:

    @heitorlessa, @mergify[bot] and @mploski

    Source code(tar.gz)
    Source code(zip)
  • v1.25.4(Mar 17, 2022)

    Summary

    This is a patch release for those using Logger utils to clone Lambda Powertools Logger configuration to all existing Python Loggers.

    Thanks to @DandyDev for spotting a log duplication for external loggers, and for @mploski for helping fix it.

    Changes

    πŸ› Bug and hot fixes

    • fix(logger-utils): ensure external loggers doesn't propagate logs on config copy (#1075) by @mploski

    This release was made possible by the following contributors:

    @heitorlessa, @mploski and Michal Ploski

    Source code(tar.gz)
    Source code(zip)
  • v1.25.3(Mar 9, 2022)

    Summary

    This patch release is strictly about customers bringing their own Logging Formatter.

    This release ensures that when using Clear State with a custom formatter, all previously added keys will be cleared. It also guarantees that Lambda Context information will no longer be cleared abruptly before logs are printed (also for custom formatters).

    There is no code change needed on customers end. We also improved the documentation to clarify the most common use cases on bringing your own formatter, and exceptional cases where you want to replace the entire Powertools Logger Formatter logic.

    Huge thanks to @jacobdarrossi for spotting, and @ilias-at-adarma for confirming this bug.

    Changes

    πŸ“œ Documentation updates

    • fix(logger): ensure state is cleared for custom formatters (#1072) by @heitorlessa
    • docs(plugin): add mermaid to create diagram as code (#1070) by @dreamorosi

    πŸ› Bug and hot fixes

    • fix(logger): ensure state is cleared for custom formatters (#1072) by @heitorlessa

    This release was made possible by the following contributors:

    @dreamorosi and @heitorlessa

    Source code(tar.gz)
    Source code(zip)
aws-lambda-scheduler lets you call any existing AWS Lambda Function you have in a future time.

aws-lambda-scheduler aws-lambda-scheduler lets you call any existing AWS Lambda Function you have in the future. This functionality is achieved by dyn

Oğuzhan Yılmaz 57 Dec 17, 2022
Python + AWS Lambda Hands OnPython + AWS Lambda Hands On

Python + AWS Lambda Hands On Python Criada em 1990, por Guido Van Rossum. "Bala de prata" (quase). Muito utilizado em: Automatizaçáes - Selenium, Beau

Marcelo Ortiz de Santana 8 Sep 9, 2022
Aws-lambda-requests-wrapper - Request/Response wrapper for AWS Lambda with API Gateway

AWS Lambda Requests Wrapper Request/Response wrapper for AWS Lambda with API Gat

null 1 May 20, 2022
A python library for creating Slack slash commands using AWS Lambda Functions

slashbot Slashbot makes it easy to create slash commands using AWS Lambda functions. These can be handy for creating a secure way to execute automated

Eric Brassell 17 Oct 21, 2022
Lambda-function - Python codes that allow notification of changes made to some services using the AWS Lambda Function

AWS Lambda Function This repository contains python codes that allow notificatio

Elif ApaydΔ±n 3 Feb 11, 2022
Criando Lambda Functions para Ingerir Dados de APIs com AWS CDK

LIVE001 - AWS Lambda para Ingerir Dados de APIs Fazer o deploy de uma função lambda com infraestrutura como código Lambda vai numa API externa e extra

Andre Sionek 12 Nov 20, 2022
Automated AWS account hardening with AWS Control Tower and AWS Step Functions

Automate activities in Control Tower provisioned AWS accounts Table of contents Introduction Architecture Prerequisites Tools and services Usage Clean

AWS Samples 20 Dec 7, 2022
SSH-Restricted deploys an SSH compliance rule (AWS Config) with auto-remediation via AWS Lambda if SSH access is public.

SSH-Restricted SSH-Restricted deploys an SSH compliance rule with auto-remediation via AWS Lambda if SSH access is public. SSH-Auto-Restricted checks

Adrian Hornsby 30 Nov 8, 2022
POC de uma AWS lambda que executa a consulta de preços de criptomoedas, e é implantada na AWS usando Github actions.

Cryptocurrency Prices Overview Instalação Repositório Configuração CI/CD Roadmap Testes Overview A ideia deste projeto é aplicar o conteúdo estudado s

Gustavo Santos 3 Aug 31, 2022
AWS-serverless-starter - AWS Lambda serverless stack via Serverless framework

Serverless app via AWS Lambda, ApiGateway and Serverless framework Configuration

 BΙ™xtiyar 3 Feb 2, 2022
FAIR Enough Metrics is an API for various FAIR Metrics Tests, written in python

β˜‘οΈ FAIR Enough metrics for research FAIR Enough Metrics is an API for various FAIR Metrics Tests, written in python, conforming to the specifications

Maastricht University IDS 3 Jul 6, 2022
An Advanced Python Playing Card Module that makes creating playing card games simple and easy!

playingcards.py An Advanced Python Playing Card Module that makes creating playing card games simple and easy! Features Easy to Understand Class Objec

Blake Potvin 5 Aug 30, 2022
Building and deploying AWS Lambda Shared Layers

AWS Lambda Shared Layers This repository is hosting the code from the following blog post: AWS Lambda & Shared layers for Python. The goal of this rep

Flaneer 7 Dec 2, 2021
AWS Lambda - Parsing Cloudwatch Data and sending the response via email.

AWS Lambda - Parsing Cloudwatch Data and sending the response via email. Author: Evan Erickson Language: Python Backend: AWS / Serverless / AWS Lambda

Evan Scott Erickson 1 Nov 14, 2021
Troposphere and shellscript based AWS infrastructure automation creates an awsapigateway lambda with a go backend

Automated-cloudformation-infra Troposphere and shellscript based AWS infrastructure automation. Feel free to clone and edit for personal usage. The en

null 1 Jan 3, 2022
AWS SQS event redrive Lambda With Python

AWS SQS event redrive Lambda This repository contains one simple AWS Lambda function in Python to redrive AWS SQS events from source queue to destinat

null 1 Oct 19, 2021
AWS SQS event redrive Lambda

This repository contains the Lambda function to redrive sqs events from source to destination queue while controlling maxRetry per event.

null 1 Oct 19, 2021
AWS Lambda Fast API starter application

AWS Lambda Fast API Fast API starter application compatible with API Gateway and Lambda Function. How to deploy it? Terraform AWS Lambda API is a reus

OBytes 6 Apr 20, 2022
A Python AWS Lambda Webhook listener that generates a permanent URL when an asset is created in Contentstack.

Webhook Listener A Python Lambda Webhook Listener - Generates a permanent URL on created assets. See doc on Generating a Permanent URL: https://www.co

Contentstack Solutions 1 Nov 4, 2021