From 502ce6df8a11d8636815b4d3391eeb10d0b471ae Mon Sep 17 00:00:00 2001 From: Alan Ip Date: Tue, 17 Jan 2023 00:03:05 +0000 Subject: [PATCH 001/100] Introduce model for SQS-wrapped S3 event notifications Signed-off-by: Alan Ip --- .../utilities/parser/models/s3_event_notification.py | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 aws_lambda_powertools/utilities/parser/models/s3_event_notification.py diff --git a/aws_lambda_powertools/utilities/parser/models/s3_event_notification.py b/aws_lambda_powertools/utilities/parser/models/s3_event_notification.py new file mode 100644 index 00000000000..8f6b6d23180 --- /dev/null +++ b/aws_lambda_powertools/utilities/parser/models/s3_event_notification.py @@ -0,0 +1,7 @@ +from pydantic import Json + +from aws_lambda_powertools.utilities.parser.models.s3 import S3Model +from aws_lambda_powertools.utilities.parser.models.sqs import SqsRecordModel + +class SqsS3EventNotificationModel(SqsRecordModel): + body: Json[S3Model] From 72b127d298d9145c843f0fc032cd51c5b6a92313 Mon Sep 17 00:00:00 2001 From: Alan Ip Date: Tue, 17 Jan 2023 00:05:10 +0000 Subject: [PATCH 002/100] Export SqsS3EventNotificationModel Signed-off-by: Alan Ip --- aws_lambda_powertools/utilities/parser/models/__init__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/aws_lambda_powertools/utilities/parser/models/__init__.py b/aws_lambda_powertools/utilities/parser/models/__init__.py index 62e28a62374..45395ab3c7d 100644 --- a/aws_lambda_powertools/utilities/parser/models/__init__.py +++ b/aws_lambda_powertools/utilities/parser/models/__init__.py @@ -44,6 +44,7 @@ ) from .lambda_function_url import LambdaFunctionUrlModel from .s3 import S3Model, S3RecordModel +from .s3_event_notification import SqsS3EventNotificationModel from .s3_object_event import ( S3ObjectConfiguration, S3ObjectContext, @@ -97,6 +98,7 @@ "LambdaFunctionUrlModel", "S3Model", "S3RecordModel", + "SqsS3EventNotificationModel", "S3ObjectLambdaEvent", "S3ObjectUserIdentity", "S3ObjectSessionContext", From 665a99dc9b8a5636affb3590044afec5e440e327 Mon Sep 17 00:00:00 2001 From: Alan Ip Date: Tue, 11 Apr 2023 12:37:45 +0100 Subject: [PATCH 003/100] Re-order exports into (slightly more) alphabetical order Signed-off-by: Alan Ip --- aws_lambda_powertools/utilities/parser/models/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aws_lambda_powertools/utilities/parser/models/__init__.py b/aws_lambda_powertools/utilities/parser/models/__init__.py index 4d2c40abf40..d5b75e57b5b 100644 --- a/aws_lambda_powertools/utilities/parser/models/__init__.py +++ b/aws_lambda_powertools/utilities/parser/models/__init__.py @@ -104,7 +104,6 @@ "LambdaFunctionUrlModel", "S3Model", "S3RecordModel", - "SqsS3EventNotificationModel", "S3ObjectLambdaEvent", "S3ObjectUserIdentity", "S3ObjectSessionContext", @@ -132,6 +131,7 @@ "SqsRecordModel", "SqsMsgAttributeModel", "SqsAttributesModel", + "SqsS3EventNotificationModel", "APIGatewayProxyEventModel", "APIGatewayEventRequestContext", "APIGatewayEventAuthorizer", From 6c426dd3d79e0cc146ed666268089e4c38a115ef Mon Sep 17 00:00:00 2001 From: Alan Ip Date: Fri, 14 Apr 2023 02:03:08 +0100 Subject: [PATCH 004/100] Differentiate between *RecordModel vs *Model The latter represents an event payload, i.e. a list of records. --- .../utilities/parser/models/__init__.py | 6 +++++- .../utilities/parser/models/s3_event_notification.py | 9 +++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/aws_lambda_powertools/utilities/parser/models/__init__.py b/aws_lambda_powertools/utilities/parser/models/__init__.py index d5b75e57b5b..26b68359da3 100644 --- a/aws_lambda_powertools/utilities/parser/models/__init__.py +++ b/aws_lambda_powertools/utilities/parser/models/__init__.py @@ -50,7 +50,10 @@ S3Model, S3RecordModel, ) -from .s3_event_notification import SqsS3EventNotificationModel +from .s3_event_notification import ( + SqsS3EventNotificationModel, + SqsS3EventNotificationRecordModel, +) from .s3_object_event import ( S3ObjectConfiguration, S3ObjectContext, @@ -132,6 +135,7 @@ "SqsMsgAttributeModel", "SqsAttributesModel", "SqsS3EventNotificationModel", + "SqsS3EventNotificationRecordModel", "APIGatewayProxyEventModel", "APIGatewayEventRequestContext", "APIGatewayEventAuthorizer", diff --git a/aws_lambda_powertools/utilities/parser/models/s3_event_notification.py b/aws_lambda_powertools/utilities/parser/models/s3_event_notification.py index 8f6b6d23180..41edf0c4d46 100644 --- a/aws_lambda_powertools/utilities/parser/models/s3_event_notification.py +++ b/aws_lambda_powertools/utilities/parser/models/s3_event_notification.py @@ -1,7 +1,12 @@ +from typing import List + from pydantic import Json from aws_lambda_powertools.utilities.parser.models.s3 import S3Model -from aws_lambda_powertools.utilities.parser.models.sqs import SqsRecordModel +from aws_lambda_powertools.utilities.parser.models.sqs import SqsRecordModel, SqsModel -class SqsS3EventNotificationModel(SqsRecordModel): +class SqsS3EventNotificationRecordModel(SqsRecordModel): body: Json[S3Model] + +class SqsS3EventNotificationModel(SqsModel): + Records: List[SqsS3EventNotificationRecordModel] From be69e4ca27512c0383d5084bdd375d4e10a7c883 Mon Sep 17 00:00:00 2001 From: Alan Ip Date: Fri, 14 Apr 2023 02:34:48 +0100 Subject: [PATCH 005/100] Add positive functional tests for SqsS3EventNotificationModel Since the SqsS3EventNotificationModel is only responsible for chaining (rather than redefining) the existing SqsModel and S3Model models, let's re-use both the existing stubs and their corresponding assertions. --- tests/functional/parser/test_s3.py | 8 +++-- .../parser/test_sqs_s3_event_notification.py | 32 +++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 tests/functional/parser/test_sqs_s3_event_notification.py diff --git a/tests/functional/parser/test_s3.py b/tests/functional/parser/test_s3.py index cd903f3052c..f6ed3a5422e 100644 --- a/tests/functional/parser/test_s3.py +++ b/tests/functional/parser/test_s3.py @@ -6,8 +6,7 @@ from tests.functional.utils import load_event -@event_parser(model=S3Model) -def handle_s3(event: S3Model, _: LambdaContext): +def assert_s3(event: S3Model): records = list(event.Records) assert len(records) == 1 record: S3RecordModel = records[0] @@ -41,6 +40,11 @@ def handle_s3(event: S3Model, _: LambdaContext): assert record.glacierEventData is None +@event_parser(model=S3Model) +def handle_s3(event: S3Model, _: LambdaContext): + assert_s3(event) + + @event_parser(model=S3Model) def handle_s3_glacier(event: S3Model, _: LambdaContext): records = list(event.Records) diff --git a/tests/functional/parser/test_sqs_s3_event_notification.py b/tests/functional/parser/test_sqs_s3_event_notification.py new file mode 100644 index 00000000000..3aed584a150 --- /dev/null +++ b/tests/functional/parser/test_sqs_s3_event_notification.py @@ -0,0 +1,32 @@ +from aws_lambda_powertools.utilities.parser import event_parser +from aws_lambda_powertools.utilities.parser.models import ( + SqsS3EventNotificationModel, + S3Model, +) +from aws_lambda_powertools.utilities.typing import LambdaContext +from tests.functional.parser.schemas import MyAdvancedSqsBusiness +from tests.functional.utils import json_serialize, load_event + +@event_parser(model=SqsS3EventNotificationModel) +def handle_sqs_json_body_containing_s3_notifications(event: SqsS3EventNotificationModel, _: LambdaContext): + return event + +@event_parser(model=MyAdvancedSqsBusiness) +def generate_sqs_event() -> MyAdvancedSqsBusiness: + return load_event("sqsEvent.json") + +@event_parser(model=S3Model) +def generate_s3_event_notification() -> S3Model: + return load_event("s3Event.json") + +def test_handle_sqs_json_body_containing_s3_notifications(): + sqs_event = generate_sqs_event() + s3_event_notification = generate_s3_event_notification() + for record in sqs_event.Records: + record.body = json_serialize(s3_event_notification) + + parsed_event: SqsS3EventNotificationModel = handle_sqs_json_body_containing_s3_notifications(sqs_event, LambdaContext()) + + assert len(parsed_event.Records) == 2 + for parsed_sqs_record in parsed_event.Records: + assert_s3(parsed_sqs_record.body) From ad2ba2c276732c685e93ec79cbb3ae61cb379c04 Mon Sep 17 00:00:00 2001 From: Alan Ip Date: Fri, 14 Apr 2023 03:02:47 +0100 Subject: [PATCH 006/100] Silly me, I may have overcomplicated this... --- .../parser/test_sqs_s3_event_notification.py | 24 ++++++------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/tests/functional/parser/test_sqs_s3_event_notification.py b/tests/functional/parser/test_sqs_s3_event_notification.py index 3aed584a150..e8b36926caa 100644 --- a/tests/functional/parser/test_sqs_s3_event_notification.py +++ b/tests/functional/parser/test_sqs_s3_event_notification.py @@ -1,31 +1,21 @@ from aws_lambda_powertools.utilities.parser import event_parser -from aws_lambda_powertools.utilities.parser.models import ( - SqsS3EventNotificationModel, - S3Model, -) +from aws_lambda_powertools.utilities.parser.models import SqsS3EventNotificationModel from aws_lambda_powertools.utilities.typing import LambdaContext -from tests.functional.parser.schemas import MyAdvancedSqsBusiness from tests.functional.utils import json_serialize, load_event + @event_parser(model=SqsS3EventNotificationModel) def handle_sqs_json_body_containing_s3_notifications(event: SqsS3EventNotificationModel, _: LambdaContext): return event -@event_parser(model=MyAdvancedSqsBusiness) -def generate_sqs_event() -> MyAdvancedSqsBusiness: - return load_event("sqsEvent.json") - -@event_parser(model=S3Model) -def generate_s3_event_notification() -> S3Model: - return load_event("s3Event.json") def test_handle_sqs_json_body_containing_s3_notifications(): - sqs_event = generate_sqs_event() - s3_event_notification = generate_s3_event_notification() - for record in sqs_event.Records: - record.body = json_serialize(s3_event_notification) + sqs_event_dict = load_event("sqsEvent.json") + s3_event_notification_dict = load_event("s3Event.json") + for record in sqs_event_dict["Records"]: + record["body"] = json_serialize(s3_event_notification_dict) - parsed_event: SqsS3EventNotificationModel = handle_sqs_json_body_containing_s3_notifications(sqs_event, LambdaContext()) + parsed_event: SqsS3EventNotificationModel = handle_sqs_json_body_containing_s3_notifications(sqs_event_dict, LambdaContext()) assert len(parsed_event.Records) == 2 for parsed_sqs_record in parsed_event.Records: From 70e7b1c34b1c9d0f55b39f30f5ac5aa1b7f3b224 Mon Sep 17 00:00:00 2001 From: Alan Ip Date: Fri, 14 Apr 2023 03:04:52 +0100 Subject: [PATCH 007/100] Fix formatting --- .../utilities/parser/models/s3_event_notification.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/aws_lambda_powertools/utilities/parser/models/s3_event_notification.py b/aws_lambda_powertools/utilities/parser/models/s3_event_notification.py index 41edf0c4d46..37d77821099 100644 --- a/aws_lambda_powertools/utilities/parser/models/s3_event_notification.py +++ b/aws_lambda_powertools/utilities/parser/models/s3_event_notification.py @@ -4,9 +4,11 @@ from aws_lambda_powertools.utilities.parser.models.s3 import S3Model from aws_lambda_powertools.utilities.parser.models.sqs import SqsRecordModel, SqsModel - + + class SqsS3EventNotificationRecordModel(SqsRecordModel): - body: Json[S3Model] + body: Json[S3Model] + class SqsS3EventNotificationModel(SqsModel): - Records: List[SqsS3EventNotificationRecordModel] + Records: List[SqsS3EventNotificationRecordModel] From 251d8baa72c2550fc24fec010197887ec6577cf0 Mon Sep 17 00:00:00 2001 From: Alan Ip Date: Fri, 14 Apr 2023 03:22:27 +0100 Subject: [PATCH 008/100] Add negative functional tests for SqsS3EventNotificationModel --- .../parser/test_sqs_s3_event_notification.py | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/tests/functional/parser/test_sqs_s3_event_notification.py b/tests/functional/parser/test_sqs_s3_event_notification.py index e8b36926caa..3c71ee79cb1 100644 --- a/tests/functional/parser/test_sqs_s3_event_notification.py +++ b/tests/functional/parser/test_sqs_s3_event_notification.py @@ -1,4 +1,6 @@ -from aws_lambda_powertools.utilities.parser import event_parser +import pytest + +from aws_lambda_powertools.utilities.parser import ValidationError, event_parser from aws_lambda_powertools.utilities.parser.models import SqsS3EventNotificationModel from aws_lambda_powertools.utilities.typing import LambdaContext from tests.functional.utils import json_serialize, load_event @@ -20,3 +22,19 @@ def test_handle_sqs_json_body_containing_s3_notifications(): assert len(parsed_event.Records) == 2 for parsed_sqs_record in parsed_event.Records: assert_s3(parsed_sqs_record.body) + + +def test_handle_sqs_body_invalid_json(): + sqs_event_dict = load_event("sqsEvent.json") + + with pytest.raises(ValidationError): + handle_sqs_json_body_containing_s3_notifications(sqs_event_dict, LambdaContext()) + + +def test_handle_sqs_json_body_containing_arbitrary_json(): + sqs_event_dict = load_event("sqsEvent.json") + for record in sqs_event_dict["Records"]: + record["body"] = json_serialize({"foo": "bar"}) + + with pytest.raises(ValidationError): + handle_sqs_json_body_containing_s3_notifications(sqs_event_dict, LambdaContext()) From 915b376f63dc0fe3a842f82a7984652cf82e6078 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 14 Apr 2023 09:34:29 +0200 Subject: [PATCH 009/100] chore(deps-dev): bump aws-cdk from 2.73.0 to 2.74.0 (#2125) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 14 +++++++------- package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index 45fcd4fbfa6..3305a07d40f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,13 +8,13 @@ "name": "aws-lambda-powertools-python-e2e", "version": "1.0.0", "devDependencies": { - "aws-cdk": "^2.73.0" + "aws-cdk": "^2.74.0" } }, "node_modules/aws-cdk": { - "version": "2.73.0", - "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.73.0.tgz", - "integrity": "sha512-4ZnY+OS83goCzv+1sCEpNTNiXWjY6KBzic2RNUObzpHjUskRSwUCtaeiv6OyZ55DZoP0tneAmWIBXHfixJ7iQw==", + "version": "2.74.0", + "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.74.0.tgz", + "integrity": "sha512-pc6QO9uR7Ii0qQ74nujskkFqPCGoWTTMyt03CFaGW0CwxMfpduGC0+bvlLBbJISAe5ZGuRuYIIxxDMkNi3AIcw==", "dev": true, "bin": { "cdk": "bin/cdk" @@ -43,9 +43,9 @@ }, "dependencies": { "aws-cdk": { - "version": "2.73.0", - "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.73.0.tgz", - "integrity": "sha512-4ZnY+OS83goCzv+1sCEpNTNiXWjY6KBzic2RNUObzpHjUskRSwUCtaeiv6OyZ55DZoP0tneAmWIBXHfixJ7iQw==", + "version": "2.74.0", + "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.74.0.tgz", + "integrity": "sha512-pc6QO9uR7Ii0qQ74nujskkFqPCGoWTTMyt03CFaGW0CwxMfpduGC0+bvlLBbJISAe5ZGuRuYIIxxDMkNi3AIcw==", "dev": true, "requires": { "fsevents": "2.3.2" diff --git a/package.json b/package.json index 369f6854693..6eef515eb28 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,6 @@ "name": "aws-lambda-powertools-python-e2e", "version": "1.0.0", "devDependencies": { - "aws-cdk": "^2.73.0" + "aws-cdk": "^2.74.0" } } From 066fd82472bbbb63f6bfe8b351e4a41c1d1d095a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 14 Apr 2023 07:36:42 +0000 Subject: [PATCH 010/100] chore(deps-dev): bump flake8-comprehensions from 3.11.1 to 3.12.0 (#2124) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 8 ++++---- pyproject.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/poetry.lock b/poetry.lock index 705bb4e260d..399a8671da5 100644 --- a/poetry.lock +++ b/poetry.lock @@ -780,14 +780,14 @@ test = ["pytest"] [[package]] name = "flake8-comprehensions" -version = "3.11.1" +version = "3.12.0" description = "A flake8 plugin to help you write better list/set/dict comprehensions." category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "flake8_comprehensions-3.11.1-py3-none-any.whl", hash = "sha256:d1e27f4099900c61fb156cbb7461e0e49702385fd388326e1a892d04b069c48e"}, - {file = "flake8_comprehensions-3.11.1.tar.gz", hash = "sha256:31d6386c125e325d7c84290d71f5354295dbbf5a8d47259708fa349aa0969523"}, + {file = "flake8_comprehensions-3.12.0-py3-none-any.whl", hash = "sha256:013234637ec7dfcb7cd2900578fb53c512f81db909cefe371c019232695c362d"}, + {file = "flake8_comprehensions-3.12.0.tar.gz", hash = "sha256:419ef1a6e8de929203791a5e8ff5e3906caeba13eb3290eebdbf88a9078d502e"}, ] [package.dependencies] @@ -3035,4 +3035,4 @@ validation = ["fastjsonschema"] [metadata] lock-version = "2.0" python-versions = "^3.7.4" -content-hash = "1014e65f3df1e354dd5adb0f4facf0030247b8098f5462fde209f0942220b789" +content-hash = "02fa7bb284f7d689059624f5a30f9600f87e8c9c3929243f9a3db38b45386c7e" diff --git a/pyproject.toml b/pyproject.toml index 73791cc21e1..84fefea7072 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -44,7 +44,7 @@ flake8 = [ { version = ">=5", python= ">=3.8"}, ] flake8-builtins = "^2.1.0" -flake8-comprehensions = "^3.11.1" +flake8-comprehensions = "^3.12.0" flake8-debugger = "^4.0.0" flake8-fixme = "^1.1.1" flake8-variables-names = "^0.0.5" From ed73aefc0ca194e0ee98a53597d92b3f3bf924dd Mon Sep 17 00:00:00 2001 From: Leandro Damascena Date: Fri, 14 Apr 2023 09:05:58 +0100 Subject: [PATCH 011/100] feat(parameters): Configure max_age and decrypt parameters via environment variables (#2088) * feat(parameters) - environment default variables * feat(parameters) - environment default variables - maxage * feat(parameters) - environment default variables - refactor maxage code * feat(parameters) - addressing Ruben's feedback --- aws_lambda_powertools/shared/constants.py | 3 + aws_lambda_powertools/shared/functions.py | 5 + .../utilities/parameters/appconfig.py | 14 ++- .../utilities/parameters/base.py | 16 +++- .../utilities/parameters/secrets.py | 15 +-- .../utilities/parameters/ssm.py | 95 ++++++++++++++----- docs/index.md | 2 + docs/utilities/parameters.md | 5 +- tests/functional/test_utilities_parameters.py | 38 ++++++++ tests/unit/test_shared_functions.py | 35 +++++++ 10 files changed, 190 insertions(+), 38 deletions(-) diff --git a/aws_lambda_powertools/shared/constants.py b/aws_lambda_powertools/shared/constants.py index 2ec120e4d4a..0cde7582976 100644 --- a/aws_lambda_powertools/shared/constants.py +++ b/aws_lambda_powertools/shared/constants.py @@ -22,6 +22,9 @@ IDEMPOTENCY_DISABLED_ENV: str = "POWERTOOLS_IDEMPOTENCY_DISABLED" +PARAMETERS_SSM_DECRYPT_ENV: str = "POWERTOOLS_PARAMETERS_SSM_DECRYPT" +PARAMETERS_MAX_AGE_ENV: str = "POWERTOOLS_PARAMETERS_MAX_AGE" + LOGGER_LAMBDA_CONTEXT_KEYS = [ "function_arn", "function_memory_size", diff --git a/aws_lambda_powertools/shared/functions.py b/aws_lambda_powertools/shared/functions.py index 86ba74d5e78..20a4994e9be 100644 --- a/aws_lambda_powertools/shared/functions.py +++ b/aws_lambda_powertools/shared/functions.py @@ -51,6 +51,11 @@ def resolve_truthy_env_var_choice(env: str, choice: Optional[bool] = None) -> bo return choice if choice is not None else strtobool(env) +def resolve_max_age(env: str, choice: Optional[int]) -> int: + """Resolve max age value""" + return choice if choice is not None else int(env) + + @overload def resolve_env_var_choice(env: Optional[str], choice: float) -> float: ... diff --git a/aws_lambda_powertools/utilities/parameters/appconfig.py b/aws_lambda_powertools/utilities/parameters/appconfig.py index 7884728024e..297762628e1 100644 --- a/aws_lambda_powertools/utilities/parameters/appconfig.py +++ b/aws_lambda_powertools/utilities/parameters/appconfig.py @@ -14,8 +14,12 @@ if TYPE_CHECKING: from mypy_boto3_appconfigdata import AppConfigDataClient -from ...shared import constants -from ...shared.functions import resolve_env_var_choice +from aws_lambda_powertools.shared import constants +from aws_lambda_powertools.shared.functions import ( + resolve_env_var_choice, + resolve_max_age, +) + from .base import DEFAULT_MAX_AGE_SECS, DEFAULT_PROVIDERS, BaseProvider @@ -136,7 +140,7 @@ def get_app_config( application: Optional[str] = None, transform: TransformOptions = None, force_fetch: bool = False, - max_age: int = DEFAULT_MAX_AGE_SECS, + max_age: Optional[int] = None, **sdk_options ) -> Union[str, list, dict, bytes]: """ @@ -154,7 +158,7 @@ def get_app_config( Transforms the content from a JSON object ('json') or base64 binary string ('binary') force_fetch: bool, optional Force update even before a cached item has expired, defaults to False - max_age: int + max_age: int, optional Maximum age of the cached value sdk_options: dict, optional SDK options to propagate to `start_configuration_session` API call @@ -187,6 +191,8 @@ def get_app_config( >>> print(value) My configuration's JSON value """ + # If max_age is not set, resolve it from the environment variable, defaulting to DEFAULT_MAX_AGE_SECS + max_age = resolve_max_age(env=os.getenv(constants.PARAMETERS_MAX_AGE_ENV, DEFAULT_MAX_AGE_SECS), choice=max_age) # Only create the provider if this function is called at least once if "appconfig" not in DEFAULT_PROVIDERS: diff --git a/aws_lambda_powertools/utilities/parameters/base.py b/aws_lambda_powertools/utilities/parameters/base.py index 8587d3b5f3f..8ec1052ae37 100644 --- a/aws_lambda_powertools/utilities/parameters/base.py +++ b/aws_lambda_powertools/utilities/parameters/base.py @@ -5,6 +5,7 @@ import base64 import json +import os from abc import ABC, abstractmethod from datetime import datetime, timedelta from typing import ( @@ -24,6 +25,8 @@ import boto3 from botocore.config import Config +from aws_lambda_powertools.shared import constants +from aws_lambda_powertools.shared.functions import resolve_max_age from aws_lambda_powertools.utilities.parameters.types import TransformOptions from .exceptions import GetParameterError, TransformParameterError @@ -35,7 +38,8 @@ from mypy_boto3_ssm import SSMClient -DEFAULT_MAX_AGE_SECS = 5 +DEFAULT_MAX_AGE_SECS = "5" + # These providers will be dynamically initialized on first use of the helper functions DEFAULT_PROVIDERS: Dict[str, Any] = {} TRANSFORM_METHOD_JSON = "json" @@ -77,7 +81,7 @@ def has_not_expired_in_cache(self, key: Tuple[str, TransformOptions]) -> bool: def get( self, name: str, - max_age: int = DEFAULT_MAX_AGE_SECS, + max_age: Optional[int] = None, transform: TransformOptions = None, force_fetch: bool = False, **sdk_options, @@ -121,6 +125,9 @@ def get( value: Optional[Union[str, bytes, dict]] = None key = (name, transform) + # If max_age is not set, resolve it from the environment variable, defaulting to DEFAULT_MAX_AGE_SECS + max_age = resolve_max_age(env=os.getenv(constants.PARAMETERS_MAX_AGE_ENV, DEFAULT_MAX_AGE_SECS), choice=max_age) + if not force_fetch and self.has_not_expired_in_cache(key): return self.store[key].value @@ -149,7 +156,7 @@ def _get(self, name: str, **sdk_options) -> Union[str, bytes]: def get_multiple( self, path: str, - max_age: int = DEFAULT_MAX_AGE_SECS, + max_age: Optional[int] = None, transform: TransformOptions = None, raise_on_transform_error: bool = False, force_fetch: bool = False, @@ -186,6 +193,9 @@ def get_multiple( """ key = (path, transform) + # If max_age is not set, resolve it from the environment variable, defaulting to DEFAULT_MAX_AGE_SECS + max_age = resolve_max_age(env=os.getenv(constants.PARAMETERS_MAX_AGE_ENV, DEFAULT_MAX_AGE_SECS), choice=max_age) + if not force_fetch and self.has_not_expired_in_cache(key): return self.store[key].value # type: ignore # need to revisit entire typing here diff --git a/aws_lambda_powertools/utilities/parameters/secrets.py b/aws_lambda_powertools/utilities/parameters/secrets.py index 4a616fcf9f9..b11cb472012 100644 --- a/aws_lambda_powertools/utilities/parameters/secrets.py +++ b/aws_lambda_powertools/utilities/parameters/secrets.py @@ -3,6 +3,7 @@ """ +import os from typing import TYPE_CHECKING, Any, Dict, Optional, Union import boto3 @@ -11,6 +12,9 @@ if TYPE_CHECKING: from mypy_boto3_secretsmanager import SecretsManagerClient +from aws_lambda_powertools.shared import constants +from aws_lambda_powertools.shared.functions import resolve_max_age + from .base import DEFAULT_MAX_AGE_SECS, DEFAULT_PROVIDERS, BaseProvider @@ -111,11 +115,7 @@ def _get_multiple(self, path: str, **sdk_options) -> Dict[str, str]: def get_secret( - name: str, - transform: Optional[str] = None, - force_fetch: bool = False, - max_age: int = DEFAULT_MAX_AGE_SECS, - **sdk_options + name: str, transform: Optional[str] = None, force_fetch: bool = False, max_age: Optional[int] = None, **sdk_options ) -> Union[str, dict, bytes]: """ Retrieve a parameter value from AWS Secrets Manager @@ -128,7 +128,7 @@ def get_secret( Transforms the content from a JSON object ('json') or base64 binary string ('binary') force_fetch: bool, optional Force update even before a cached item has expired, defaults to False - max_age: int + max_age: int, optional Maximum age of the cached value sdk_options: dict, optional Dictionary of options that will be passed to the get_secret_value call @@ -162,6 +162,9 @@ def get_secret( >>> get_secret("my-secret", VersionId="f658cac0-98a5-41d9-b993-8a76a7799194") """ + # If max_age is not set, resolve it from the environment variable, defaulting to DEFAULT_MAX_AGE_SECS + max_age = resolve_max_age(env=os.getenv(constants.PARAMETERS_MAX_AGE_ENV, DEFAULT_MAX_AGE_SECS), choice=max_age) + # Only create the provider if this function is called at least once if "secrets" not in DEFAULT_PROVIDERS: DEFAULT_PROVIDERS["secrets"] = SecretsProvider() diff --git a/aws_lambda_powertools/utilities/parameters/ssm.py b/aws_lambda_powertools/utilities/parameters/ssm.py index ae4a76dac4a..26f225cfb28 100644 --- a/aws_lambda_powertools/utilities/parameters/ssm.py +++ b/aws_lambda_powertools/utilities/parameters/ssm.py @@ -3,13 +3,19 @@ """ from __future__ import annotations +import os from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple, Union, overload import boto3 from botocore.config import Config from typing_extensions import Literal -from aws_lambda_powertools.shared.functions import slice_dictionary +from aws_lambda_powertools.shared import constants +from aws_lambda_powertools.shared.functions import ( + resolve_max_age, + resolve_truthy_env_var_choice, + slice_dictionary, +) from .base import DEFAULT_MAX_AGE_SECS, DEFAULT_PROVIDERS, BaseProvider, transform_value from .exceptions import GetParameterError @@ -110,9 +116,9 @@ def __init__( def get( # type: ignore[override] self, name: str, - max_age: int = DEFAULT_MAX_AGE_SECS, + max_age: Optional[int] = None, transform: TransformOptions = None, - decrypt: bool = False, + decrypt: Optional[bool] = None, force_fetch: bool = False, **sdk_options, ) -> Optional[Union[str, dict, bytes]]: @@ -123,7 +129,7 @@ def get( # type: ignore[override] ---------- name: str Parameter name - max_age: int + max_age: int, optional Maximum age of the cached value transform: str Optional transformation of the parameter value. Supported values @@ -145,6 +151,14 @@ def get( # type: ignore[override] When the parameter provider fails to transform a parameter value. """ + # If max_age is not set, resolve it from the environment variable, defaulting to DEFAULT_MAX_AGE_SECS + max_age = resolve_max_age(env=os.getenv(constants.PARAMETERS_MAX_AGE_ENV, DEFAULT_MAX_AGE_SECS), choice=max_age) + + # If decrypt is not set, resolve it from the environment variable, defaulting to False + decrypt = resolve_truthy_env_var_choice( + env=os.getenv(constants.PARAMETERS_SSM_DECRYPT_ENV, "false"), choice=decrypt + ) + # Add to `decrypt` sdk_options to we can have an explicit option for this sdk_options["decrypt"] = decrypt @@ -212,8 +226,8 @@ def get_parameters_by_name( self, parameters: Dict[str, Dict], transform: TransformOptions = None, - decrypt: bool = False, - max_age: int = DEFAULT_MAX_AGE_SECS, + decrypt: Optional[bool] = None, + max_age: Optional[int] = None, raise_on_error: bool = True, ) -> Dict[str, str] | Dict[str, bytes] | Dict[str, dict]: """ @@ -247,7 +261,7 @@ def get_parameters_by_name( Transforms the content from a JSON object ('json') or base64 binary string ('binary') decrypt: bool, optional If the parameter values should be decrypted - max_age: int + max_age: int, optional Maximum age of the cached value raise_on_error: bool Whether to fail-fast or fail gracefully by including "_errors" key in the response, by default True @@ -259,6 +273,15 @@ def get_parameters_by_name( When "_errors" reserved key is in parameters to be fetched from SSM. """ + + # If max_age is not set, resolve it from the environment variable, defaulting to DEFAULT_MAX_AGE_SECS + max_age = resolve_max_age(env=os.getenv(constants.PARAMETERS_MAX_AGE_ENV, DEFAULT_MAX_AGE_SECS), choice=max_age) + + # If decrypt is not set, resolve it from the environment variable, defaulting to False + decrypt = resolve_truthy_env_var_choice( + env=os.getenv(constants.PARAMETERS_SSM_DECRYPT_ENV, "false"), choice=decrypt + ) + # Init potential batch/decrypt batch responses and errors batch_ret: Dict[str, Any] = {} decrypt_ret: Dict[str, Any] = {} @@ -487,9 +510,9 @@ def _raise_if_errors_key_is_present(parameters: Dict, reserved_parameter: str, r def get_parameter( name: str, transform: Optional[str] = None, - decrypt: bool = False, + decrypt: Optional[bool] = None, force_fetch: bool = False, - max_age: int = DEFAULT_MAX_AGE_SECS, + max_age: Optional[int] = None, **sdk_options, ) -> Union[str, dict, bytes]: """ @@ -505,7 +528,7 @@ def get_parameter( If the parameter values should be decrypted force_fetch: bool, optional Force update even before a cached item has expired, defaults to False - max_age: int + max_age: int, optional Maximum age of the cached value sdk_options: dict, optional Dictionary of options that will be passed to the Parameter Store get_parameter API call @@ -543,6 +566,14 @@ def get_parameter( if "ssm" not in DEFAULT_PROVIDERS: DEFAULT_PROVIDERS["ssm"] = SSMProvider() + # If max_age is not set, resolve it from the environment variable, defaulting to DEFAULT_MAX_AGE_SECS + max_age = resolve_max_age(env=os.getenv(constants.PARAMETERS_MAX_AGE_ENV, DEFAULT_MAX_AGE_SECS), choice=max_age) + + # If decrypt is not set, resolve it from the environment variable, defaulting to False + decrypt = resolve_truthy_env_var_choice( + env=os.getenv(constants.PARAMETERS_SSM_DECRYPT_ENV, "false"), choice=decrypt + ) + # Add to `decrypt` sdk_options to we can have an explicit option for this sdk_options["decrypt"] = decrypt @@ -555,9 +586,9 @@ def get_parameters( path: str, transform: Optional[str] = None, recursive: bool = True, - decrypt: bool = False, + decrypt: Optional[bool] = None, force_fetch: bool = False, - max_age: int = DEFAULT_MAX_AGE_SECS, + max_age: Optional[int] = None, raise_on_transform_error: bool = False, **sdk_options, ) -> Union[Dict[str, str], Dict[str, dict], Dict[str, bytes]]: @@ -576,7 +607,7 @@ def get_parameters( If the parameter values should be decrypted force_fetch: bool, optional Force update even before a cached item has expired, defaults to False - max_age: int + max_age: int, optional Maximum age of the cached value raise_on_transform_error: bool, optional Raises an exception if any transform fails, otherwise this will @@ -617,6 +648,14 @@ def get_parameters( if "ssm" not in DEFAULT_PROVIDERS: DEFAULT_PROVIDERS["ssm"] = SSMProvider() + # If max_age is not set, resolve it from the environment variable, defaulting to DEFAULT_MAX_AGE_SECS + max_age = resolve_max_age(env=os.getenv(constants.PARAMETERS_MAX_AGE_ENV, DEFAULT_MAX_AGE_SECS), choice=max_age) + + # If decrypt is not set, resolve it from the environment variable, defaulting to False + decrypt = resolve_truthy_env_var_choice( + env=os.getenv(constants.PARAMETERS_SSM_DECRYPT_ENV, "false"), choice=decrypt + ) + sdk_options["recursive"] = recursive sdk_options["decrypt"] = decrypt @@ -634,8 +673,8 @@ def get_parameters( def get_parameters_by_name( parameters: Dict[str, Dict], transform: None = None, - decrypt: bool = False, - max_age: int = DEFAULT_MAX_AGE_SECS, + decrypt: Optional[bool] = None, + max_age: Optional[int] = None, raise_on_error: bool = True, ) -> Dict[str, str]: ... @@ -645,8 +684,8 @@ def get_parameters_by_name( def get_parameters_by_name( parameters: Dict[str, Dict], transform: Literal["binary"], - decrypt: bool = False, - max_age: int = DEFAULT_MAX_AGE_SECS, + decrypt: Optional[bool] = None, + max_age: Optional[int] = None, raise_on_error: bool = True, ) -> Dict[str, bytes]: ... @@ -656,8 +695,8 @@ def get_parameters_by_name( def get_parameters_by_name( parameters: Dict[str, Dict], transform: Literal["json"], - decrypt: bool = False, - max_age: int = DEFAULT_MAX_AGE_SECS, + decrypt: Optional[bool] = None, + max_age: Optional[int] = None, raise_on_error: bool = True, ) -> Dict[str, Dict[str, Any]]: ... @@ -667,8 +706,8 @@ def get_parameters_by_name( def get_parameters_by_name( parameters: Dict[str, Dict], transform: Literal["auto"], - decrypt: bool = False, - max_age: int = DEFAULT_MAX_AGE_SECS, + decrypt: Optional[bool] = None, + max_age: Optional[int] = None, raise_on_error: bool = True, ) -> Union[Dict[str, str], Dict[str, dict]]: ... @@ -677,8 +716,8 @@ def get_parameters_by_name( def get_parameters_by_name( parameters: Dict[str, Any], transform: TransformOptions = None, - decrypt: bool = False, - max_age: int = DEFAULT_MAX_AGE_SECS, + decrypt: Optional[bool] = None, + max_age: Optional[int] = None, raise_on_error: bool = True, ) -> Union[Dict[str, str], Dict[str, bytes], Dict[str, dict]]: """ @@ -692,7 +731,7 @@ def get_parameters_by_name( Transforms the content from a JSON object ('json') or base64 binary string ('binary') decrypt: bool, optional If the parameter values should be decrypted - max_age: int + max_age: int, optional Maximum age of the cached value raise_on_error: bool, optional Whether to fail-fast or fail gracefully by including "_errors" key in the response, by default True @@ -732,6 +771,14 @@ def get_parameters_by_name( # NOTE: Decided against using multi-thread due to single-thread outperforming in 128M and 1G + timeout risk # see: https://github.com/awslabs/aws-lambda-powertools-python/issues/1040#issuecomment-1299954613 + # If max_age is not set, resolve it from the environment variable, defaulting to DEFAULT_MAX_AGE_SECS + max_age = resolve_max_age(env=os.getenv(constants.PARAMETERS_MAX_AGE_ENV, DEFAULT_MAX_AGE_SECS), choice=max_age) + + # If decrypt is not set, resolve it from the environment variable, defaulting to False + decrypt = resolve_truthy_env_var_choice( + env=os.getenv(constants.PARAMETERS_SSM_DECRYPT_ENV, "false"), choice=decrypt + ) + # Only create the provider if this function is called at least once if "ssm" not in DEFAULT_PROVIDERS: DEFAULT_PROVIDERS["ssm"] = SSMProvider() diff --git a/docs/index.md b/docs/index.md index 55d44ced65d..074d5e40809 100644 --- a/docs/index.md +++ b/docs/index.md @@ -706,6 +706,8 @@ Core utilities such as Tracing, Logging, Metrics, and Event Handler will be avai | **POWERTOOLS_LOGGER_LOG_EVENT** | Logs incoming event | [Logging](./core/logger) | `false` | | **POWERTOOLS_LOGGER_SAMPLE_RATE** | Debug log sampling | [Logging](./core/logger) | `0` | | **POWERTOOLS_LOG_DEDUPLICATION_DISABLED** | Disables log deduplication filter protection to use Pytest Live Log feature | [Logging](./core/logger) | `false` | +| **POWERTOOLS_PARAMETERS_MAX_AGE** | Adjust how long values are kept in cache (in seconds) | [Parameters](./utilities/parameters/#adjusting-cache-ttl) | `5` | +| **POWERTOOLS_PARAMETERS_SSM_DECRYPT** | Sets whether to decrypt or not values retrieved from AWS SSM Parameters Store | [Parameters](./utilities/parameters/#ssmprovider) | `false` | | **POWERTOOLS_DEV** | Increases verbosity across utilities | Multiple; see [POWERTOOLS_DEV effect below](#increasing-verbosity-across-utilities) | `false` | | **LOG_LEVEL** | Sets logging level | [Logging](./core/logger) | `INFO` | diff --git a/docs/utilities/parameters.md b/docs/utilities/parameters.md index e00851fbb8b..3e2fd37c8aa 100644 --- a/docs/utilities/parameters.md +++ b/docs/utilities/parameters.md @@ -103,7 +103,7 @@ The following will retrieve the latest version and store it in the cache. ???+ tip `max_age` parameter is also available in underlying provider functions like `get()`, `get_multiple()`, etc. -By default, we cache parameters retrieved in-memory for 5 seconds. +By default, we cache parameters retrieved in-memory for 5 seconds. If you want to change this default value and set the same TTL for all parameters, you can set the `POWERTOOLS_PARAMETERS_MAX_AGE` environment variable. **You can still set `max_age` for individual parameters**. You can adjust how long we should keep values in cache by using the param `max_age`, when using `get_parameter()`, `get_parameters()` and `get_secret()` methods across all providers. @@ -179,6 +179,9 @@ The AWS Systems Manager Parameter Store provider supports two additional argumen You can create `SecureString` parameters, which are parameters that have a plaintext parameter name and an encrypted parameter value. If you don't use the `decrypt` argument, you will get an encrypted value. Read [here](https://docs.aws.amazon.com/kms/latest/developerguide/services-parameter-store.html) about best practices using KMS to secure your parameters. +???+ tip + If you want to always decrypt parameters, you can set the `POWERTOOLS_PARAMETERS_SSM_DECRYPT=true` environment variable. **This will override the default value of `false` but you can still set the `decrypt` option for individual parameters**. + === "builtin_provider_ssm_with_decrypt.py" ```python hl_lines="6 10 16" --8<-- "examples/parameters/src/builtin_provider_ssm_with_decrypt.py" diff --git a/tests/functional/test_utilities_parameters.py b/tests/functional/test_utilities_parameters.py index f3d326fcd58..83b6440a50c 100644 --- a/tests/functional/test_utilities_parameters.py +++ b/tests/functional/test_utilities_parameters.py @@ -547,6 +547,44 @@ def test_ssm_provider_get_with_custom_client(mock_name, mock_value, mock_version stubber.deactivate() +def test_ssm_provider_get_with_decrypt_environment_variable(monkeypatch, mock_name, mock_value, mock_version, config): + """ + Test SSMProvider.get() with decrypt value replaced by environment variable + """ + + # Setting environment variable to override the default value + monkeypatch.setenv("POWERTOOLS_PARAMETERS_SSM_DECRYPT", "true") + + # Create a new provider + provider = parameters.SSMProvider(config=config) + + # Stub the boto3 client + stubber = stub.Stubber(provider.client) + response = { + "Parameter": { + "Name": mock_name, + "Type": "String", + "Value": mock_value, + "Version": mock_version, + "Selector": f"{mock_name}:{mock_version}", + "SourceResult": "string", + "LastModifiedDate": datetime(2015, 1, 1), + "ARN": f"arn:aws:ssm:us-east-2:111122223333:parameter/{mock_name}", + } + } + expected_params = {"Name": mock_name, "WithDecryption": True} + stubber.add_response("get_parameter", response, expected_params) + stubber.activate() + + try: + value = provider.get(mock_name) + + assert value == mock_value + stubber.assert_no_pending_responses() + finally: + stubber.deactivate() + + def test_ssm_provider_get_default_config(monkeypatch, mock_name, mock_value, mock_version): """ Test SSMProvider.get() without specifying the config diff --git a/tests/unit/test_shared_functions.py b/tests/unit/test_shared_functions.py index 00abe2c6e08..9232b72527b 100644 --- a/tests/unit/test_shared_functions.py +++ b/tests/unit/test_shared_functions.py @@ -1,3 +1,4 @@ +import os import warnings from dataclasses import dataclass @@ -10,10 +11,12 @@ powertools_debug_is_set, powertools_dev_is_set, resolve_env_var_choice, + resolve_max_age, resolve_truthy_env_var_choice, strtobool, ) from aws_lambda_powertools.utilities.data_classes.common import DictWrapper +from aws_lambda_powertools.utilities.parameters.base import DEFAULT_MAX_AGE_SECS def test_resolve_env_var_choice_explicit_wins_over_env_var(): @@ -103,3 +106,35 @@ class DummyDataclass: @pytest.mark.parametrize("data", [False, True, "", 10, [], {}, object]) def test_extract_event_any(data): assert extract_event_from_common_models(data) == data + + +def test_resolve_max_age_explicit_wins_over_env_var(monkeypatch: pytest.MonkeyPatch): + # GIVEN POWERTOOLS_PARAMETERS_MAX_AGE environment variable is set + monkeypatch.setenv(constants.PARAMETERS_MAX_AGE_ENV, "20") + + # WHEN the choice is set explicitly + max_age = resolve_max_age(env=os.getenv(constants.PARAMETERS_MAX_AGE_ENV, DEFAULT_MAX_AGE_SECS), choice=10) + + # THEN the result must be the choice + assert max_age == 10 + + +def test_resolve_max_age_with_default_value(): + # GIVEN POWERTOOLS_PARAMETERS_MAX_AGE is not set + + # WHEN the choice is set to None + max_age = resolve_max_age(env=os.getenv(constants.PARAMETERS_MAX_AGE_ENV, DEFAULT_MAX_AGE_SECS), choice=None) + + # THEN the result must be the default value (DEFAULT_MAX_AGE_SECS) + assert max_age == int(DEFAULT_MAX_AGE_SECS) + + +def test_resolve_max_age_env_var_wins_over_default_value(monkeypatch: pytest.MonkeyPatch): + # GIVEN POWERTOOLS_PARAMETERS_MAX_AGE environment variable is set + monkeypatch.setenv(constants.PARAMETERS_MAX_AGE_ENV, "20") + + # WHEN the choice is set to None + max_age = resolve_max_age(env=os.getenv(constants.PARAMETERS_MAX_AGE_ENV, DEFAULT_MAX_AGE_SECS), choice=None) + + # THEN the result must be the environment variable value + assert max_age == 20 From 22e28ae08291a86bb610370887519fb437483354 Mon Sep 17 00:00:00 2001 From: Release bot Date: Fri, 14 Apr 2023 08:06:26 +0000 Subject: [PATCH 012/100] update changelog with latest changes --- CHANGELOG.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d0b548188e7..eb66196cfd4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,16 +10,23 @@ * **ci:** update layer version on logger, tracer and metrics docs ([#2120](https://github.com/awslabs/aws-lambda-powertools-python/issues/2120)) * **event_sources:** Update CodePipeline event source to include optional encryption_key field and make user_parameters field optional ([#2113](https://github.com/awslabs/aws-lambda-powertools-python/issues/2113)) +## Features + +* **parameters:** Configure max_age and decrypt parameters via environment variables ([#2088](https://github.com/awslabs/aws-lambda-powertools-python/issues/2088)) + ## Maintenance * **ci:** bump the cdk-aws-lambda-powertools-layer version ([#2121](https://github.com/awslabs/aws-lambda-powertools-python/issues/2121)) * **deps:** bump codecov/codecov-action from 3.1.1 to 3.1.2 ([#2110](https://github.com/awslabs/aws-lambda-powertools-python/issues/2110)) -* **deps-dev:** bump importlib-metadata from 6.1.0 to 6.3.0 ([#2105](https://github.com/awslabs/aws-lambda-powertools-python/issues/2105)) +* **deps-dev:** bump flake8-comprehensions from 3.11.1 to 3.12.0 ([#2124](https://github.com/awslabs/aws-lambda-powertools-python/issues/2124)) +* **deps-dev:** bump aws-cdk-lib from 2.73.0 to 2.74.0 ([#2123](https://github.com/awslabs/aws-lambda-powertools-python/issues/2123)) +* **deps-dev:** bump mkdocs-material from 9.1.5 to 9.1.6 ([#2104](https://github.com/awslabs/aws-lambda-powertools-python/issues/2104)) +* **deps-dev:** bump aws-cdk from 2.73.0 to 2.74.0 ([#2125](https://github.com/awslabs/aws-lambda-powertools-python/issues/2125)) * **deps-dev:** bump httpx from 0.23.3 to 0.24.0 ([#2111](https://github.com/awslabs/aws-lambda-powertools-python/issues/2111)) * **deps-dev:** bump mypy from 1.1.1 to 1.2.0 ([#2096](https://github.com/awslabs/aws-lambda-powertools-python/issues/2096)) * **deps-dev:** bump cfn-lint from 0.76.2 to 0.77.0 ([#2107](https://github.com/awslabs/aws-lambda-powertools-python/issues/2107)) * **deps-dev:** bump pytest from 7.2.2 to 7.3.0 ([#2106](https://github.com/awslabs/aws-lambda-powertools-python/issues/2106)) -* **deps-dev:** bump mkdocs-material from 9.1.5 to 9.1.6 ([#2104](https://github.com/awslabs/aws-lambda-powertools-python/issues/2104)) +* **deps-dev:** bump importlib-metadata from 6.1.0 to 6.3.0 ([#2105](https://github.com/awslabs/aws-lambda-powertools-python/issues/2105)) * **deps-dev:** bump mypy-boto3-lambda from 1.26.80 to 1.26.109 ([#2103](https://github.com/awslabs/aws-lambda-powertools-python/issues/2103)) * **maintenance:** validate acknowledgement section is present ([#2112](https://github.com/awslabs/aws-lambda-powertools-python/issues/2112)) From 2a2f7a848dc1f5983b6c473148ec7fb7c6ab1700 Mon Sep 17 00:00:00 2001 From: Release bot Date: Fri, 14 Apr 2023 09:52:04 +0000 Subject: [PATCH 013/100] bump version to 2.13.0 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 84fefea7072..61a5246e4b2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "aws_lambda_powertools" -version = "2.12.0" +version = "2.13.0" description = "AWS Lambda Powertools is a developer toolkit to implement Serverless best practices and increase developer velocity." authors = ["Amazon Web Services"] include = ["aws_lambda_powertools/py.typed", "THIRD-PARTY-LICENSES"] From 8ba15fd46ef4839c320756f788f98124a2c7758e Mon Sep 17 00:00:00 2001 From: Ruben Fonseca Date: Fri, 14 Apr 2023 12:05:38 +0200 Subject: [PATCH 014/100] fix(ci): use project's CDK version when building layers --- .github/workflows/publish_v2_layer.yml | 7 ++++--- .github/workflows/reusable_deploy_v2_layer_stack.yml | 12 +++++------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/.github/workflows/publish_v2_layer.yml b/.github/workflows/publish_v2_layer.yml index 85d005ec5ae..0625ad07fb0 100644 --- a/.github/workflows/publish_v2_layer.yml +++ b/.github/workflows/publish_v2_layer.yml @@ -71,11 +71,12 @@ jobs: driver: docker platforms: linux/amd64,linux/arm64 - name: install cdk and deps + working-directory: ../ run: | - npm install -g aws-cdk@2.47.0 - cdk --version + npm install + npx cdk --version - name: CDK build - run: cdk synth --verbose --context version="${{ inputs.latest_published_version }}" -o cdk.out + run: npx cdk synth --verbose --context version="${{ inputs.latest_published_version }}" -o cdk.out - name: zip output run: zip -r cdk.out.zip cdk.out - name: Archive CDK artifacts diff --git a/.github/workflows/reusable_deploy_v2_layer_stack.yml b/.github/workflows/reusable_deploy_v2_layer_stack.yml index 74f02766932..0518e7ae328 100644 --- a/.github/workflows/reusable_deploy_v2_layer_stack.yml +++ b/.github/workflows/reusable_deploy_v2_layer_stack.yml @@ -1,8 +1,5 @@ name: Deploy CDK Layer v2 stack -env: - CDK_VERSION: 2.44.0 - permissions: id-token: write contents: write @@ -88,9 +85,10 @@ jobs: poetry export --format requirements.txt --output requirements.txt pip install -r requirements.txt - name: install cdk and deps + working-directory: ../ run: | - npm install -g "aws-cdk@$CDK_VERSION" - cdk --version + npm install + npx cdk --version - name: install deps run: poetry install - name: Download artifact @@ -101,7 +99,7 @@ jobs: - name: unzip artefact run: unzip cdk.out.zip - name: CDK Deploy Layer - run: cdk deploy --app cdk.out --context region=${{ matrix.region }} 'LayerV2Stack' --require-approval never --verbose --outputs-file cdk-outputs.json + run: npx cdk deploy --app cdk.out --context region=${{ matrix.region }} 'LayerV2Stack' --require-approval never --verbose --outputs-file cdk-outputs.json - name: Store latest Layer ARN if: ${{ inputs.stage == 'PROD' }} run: | @@ -118,7 +116,7 @@ jobs: if-no-files-found: error retention-days: 1 - name: CDK Deploy Canary - run: cdk deploy --app cdk.out --context region=${{ matrix.region}} --parameters DeployStage="${{ inputs.stage }}" 'CanaryV2Stack' --require-approval never --verbose + run: npx cdk deploy --app cdk.out --context region=${{ matrix.region}} --parameters DeployStage="${{ inputs.stage }}" 'CanaryV2Stack' --require-approval never --verbose update_v2_layer_arn_docs: needs: deploy-cdk-stack From 861b767cffcaf91db6295a46b8929be3397b87a6 Mon Sep 17 00:00:00 2001 From: Release bot Date: Fri, 14 Apr 2023 10:09:42 +0000 Subject: [PATCH 015/100] update changelog with latest changes --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index eb66196cfd4..b0609fde8d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ ## Bug Fixes +* **ci:** use project's CDK version when building layers * **ci:** add the rest of the changed docs * **ci:** update layer version on logger, tracer and metrics docs ([#2120](https://github.com/awslabs/aws-lambda-powertools-python/issues/2120)) * **event_sources:** Update CodePipeline event source to include optional encryption_key field and make user_parameters field optional ([#2113](https://github.com/awslabs/aws-lambda-powertools-python/issues/2113)) From 8c198aef4202910a0fea4a8c86a52ae19c17d680 Mon Sep 17 00:00:00 2001 From: Ruben Fonseca Date: Fri, 14 Apr 2023 12:12:39 +0200 Subject: [PATCH 016/100] fix(ci): add debug log to NPM install --- .github/workflows/publish_v2_layer.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/publish_v2_layer.yml b/.github/workflows/publish_v2_layer.yml index 0625ad07fb0..82078260f26 100644 --- a/.github/workflows/publish_v2_layer.yml +++ b/.github/workflows/publish_v2_layer.yml @@ -73,6 +73,7 @@ jobs: - name: install cdk and deps working-directory: ../ run: | + ls -la npm install npx cdk --version - name: CDK build From c9dddeac14bde43bb592c0408d69ce96d52ce62c Mon Sep 17 00:00:00 2001 From: Release bot Date: Fri, 14 Apr 2023 10:15:03 +0000 Subject: [PATCH 017/100] update changelog with latest changes --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b0609fde8d8..d5180600def 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ ## Bug Fixes +* **ci:** add debug log to NPM install * **ci:** use project's CDK version when building layers * **ci:** add the rest of the changed docs * **ci:** update layer version on logger, tracer and metrics docs ([#2120](https://github.com/awslabs/aws-lambda-powertools-python/issues/2120)) From cd0001630de5a64a4484f024eb8adc7ac3ff07ac Mon Sep 17 00:00:00 2001 From: Ruben Fonseca Date: Fri, 14 Apr 2023 12:17:04 +0200 Subject: [PATCH 018/100] fix(ci): fix working directory --- .github/workflows/publish_v2_layer.yml | 3 +-- .github/workflows/reusable_deploy_v2_layer_stack.yml | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/publish_v2_layer.yml b/.github/workflows/publish_v2_layer.yml index 82078260f26..9afd02d1465 100644 --- a/.github/workflows/publish_v2_layer.yml +++ b/.github/workflows/publish_v2_layer.yml @@ -71,9 +71,8 @@ jobs: driver: docker platforms: linux/amd64,linux/arm64 - name: install cdk and deps - working-directory: ../ + working-directory: ./ run: | - ls -la npm install npx cdk --version - name: CDK build diff --git a/.github/workflows/reusable_deploy_v2_layer_stack.yml b/.github/workflows/reusable_deploy_v2_layer_stack.yml index 0518e7ae328..0365f98b01d 100644 --- a/.github/workflows/reusable_deploy_v2_layer_stack.yml +++ b/.github/workflows/reusable_deploy_v2_layer_stack.yml @@ -85,7 +85,7 @@ jobs: poetry export --format requirements.txt --output requirements.txt pip install -r requirements.txt - name: install cdk and deps - working-directory: ../ + working-directory: ./ run: | npm install npx cdk --version From 2eac88afa8d77e53656621b23d221786df5807e5 Mon Sep 17 00:00:00 2001 From: Release bot Date: Fri, 14 Apr 2023 10:20:34 +0000 Subject: [PATCH 019/100] update changelog with latest changes --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d5180600def..34dd6ce6ec2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ ## Bug Fixes +* **ci:** fix working directory * **ci:** add debug log to NPM install * **ci:** use project's CDK version when building layers * **ci:** add the rest of the changed docs From 111655265c04d9ad15dea3bd6ffe763c779ef59e Mon Sep 17 00:00:00 2001 From: Alan Ip Date: Fri, 14 Apr 2023 11:25:42 +0100 Subject: [PATCH 020/100] Explicitly import local method Signed-off-by: Alan Ip --- tests/functional/parser/test_sqs_s3_event_notification.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/functional/parser/test_sqs_s3_event_notification.py b/tests/functional/parser/test_sqs_s3_event_notification.py index 3c71ee79cb1..75c35af7773 100644 --- a/tests/functional/parser/test_sqs_s3_event_notification.py +++ b/tests/functional/parser/test_sqs_s3_event_notification.py @@ -3,6 +3,7 @@ from aws_lambda_powertools.utilities.parser import ValidationError, event_parser from aws_lambda_powertools.utilities.parser.models import SqsS3EventNotificationModel from aws_lambda_powertools.utilities.typing import LambdaContext +from tests.functional.parser.test_s3 import assert_s3 from tests.functional.utils import json_serialize, load_event From 32b1c13811b40f5d0167693b384f7bff6fd74d2a Mon Sep 17 00:00:00 2001 From: Release bot Date: Fri, 14 Apr 2023 10:32:43 +0000 Subject: [PATCH 021/100] chore: update v2 layer ARN on documentation --- docs/index.md | 118 +++++++++++++++++++++++++------------------------- 1 file changed, 59 insertions(+), 59 deletions(-) diff --git a/docs/index.md b/docs/index.md index 074d5e40809..9bd8295837b 100644 --- a/docs/index.md +++ b/docs/index.md @@ -26,8 +26,8 @@ Powertools is a developer toolkit to implement Serverless best practices and inc You can install Powertools using one of the following options: -* **Lambda Layer (x86_64)**: [**arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:26**](#){: .copyMe}:clipboard: -* **Lambda Layer (arm64)**: [**arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:26**](#){: .copyMe}:clipboard: +* **Lambda Layer (x86_64)**: [**arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:27**](#){: .copyMe}:clipboard: +* **Lambda Layer (arm64)**: [**arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:27**](#){: .copyMe}:clipboard: * **Pip**: **[`pip install "aws-lambda-powertools"`](#){: .copyMe}:clipboard:** ??? question "Using Pip? You might need to install additional dependencies." @@ -78,55 +78,55 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. | Region | Layer ARN | | ---------------- | ---------------------------------------------------------------------------------------------------------- | - | `af-south-1` | [arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:26](#){: .copyMe}:clipboard: | - | `ap-east-1` | [arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:26](#){: .copyMe}:clipboard: | - | `ap-northeast-1` | [arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:26](#){: .copyMe}:clipboard: | - | `ap-northeast-2` | [arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:26](#){: .copyMe}:clipboard: | - | `ap-northeast-3` | [arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:26](#){: .copyMe}:clipboard: | - | `ap-south-1` | [arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:26](#){: .copyMe}:clipboard: | - | `ap-southeast-1` | [arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:26](#){: .copyMe}:clipboard: | - | `ap-southeast-2` | [arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:26](#){: .copyMe}:clipboard: | - | `ap-southeast-3` | [arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:26](#){: .copyMe}:clipboard: | - | `ca-central-1` | [arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:26](#){: .copyMe}:clipboard: | - | `eu-central-1` | [arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:26](#){: .copyMe}:clipboard: | - | `eu-north-1` | [arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:26](#){: .copyMe}:clipboard: | - | `eu-south-1` | [arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:26](#){: .copyMe}:clipboard: | - | `eu-west-1` | [arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:26](#){: .copyMe}:clipboard: | - | `eu-west-2` | [arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:26](#){: .copyMe}:clipboard: | - | `eu-west-3` | [arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:26](#){: .copyMe}:clipboard: | - | `me-south-1` | [arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:26](#){: .copyMe}:clipboard: | - | `sa-east-1` | [arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:26](#){: .copyMe}:clipboard: | - | `us-east-1` | [arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:26](#){: .copyMe}:clipboard: | - | `us-east-2` | [arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:26](#){: .copyMe}:clipboard: | - | `us-west-1` | [arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:26](#){: .copyMe}:clipboard: | - | `us-west-2` | [arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:26](#){: .copyMe}:clipboard: | + | `af-south-1` | [arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:27](#){: .copyMe}:clipboard: | + | `ap-east-1` | [arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:27](#){: .copyMe}:clipboard: | + | `ap-northeast-1` | [arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:27](#){: .copyMe}:clipboard: | + | `ap-northeast-2` | [arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:27](#){: .copyMe}:clipboard: | + | `ap-northeast-3` | [arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:27](#){: .copyMe}:clipboard: | + | `ap-south-1` | [arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:27](#){: .copyMe}:clipboard: | + | `ap-southeast-1` | [arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:27](#){: .copyMe}:clipboard: | + | `ap-southeast-2` | [arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:27](#){: .copyMe}:clipboard: | + | `ap-southeast-3` | [arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:27](#){: .copyMe}:clipboard: | + | `ca-central-1` | [arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:27](#){: .copyMe}:clipboard: | + | `eu-central-1` | [arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:27](#){: .copyMe}:clipboard: | + | `eu-north-1` | [arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:27](#){: .copyMe}:clipboard: | + | `eu-south-1` | [arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:27](#){: .copyMe}:clipboard: | + | `eu-west-1` | [arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:27](#){: .copyMe}:clipboard: | + | `eu-west-2` | [arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:27](#){: .copyMe}:clipboard: | + | `eu-west-3` | [arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:27](#){: .copyMe}:clipboard: | + | `me-south-1` | [arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:27](#){: .copyMe}:clipboard: | + | `sa-east-1` | [arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:27](#){: .copyMe}:clipboard: | + | `us-east-1` | [arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:27](#){: .copyMe}:clipboard: | + | `us-east-2` | [arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:27](#){: .copyMe}:clipboard: | + | `us-west-1` | [arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:27](#){: .copyMe}:clipboard: | + | `us-west-2` | [arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:27](#){: .copyMe}:clipboard: | === "arm64" | Region | Layer ARN | | ---------------- | ---------------------------------------------------------------------------------------------------------------- | - | `af-south-1` | [arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:26](#){: .copyMe}:clipboard: | - | `ap-east-1` | [arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:26](#){: .copyMe}:clipboard: | - | `ap-northeast-1` | [arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:26](#){: .copyMe}:clipboard: | - | `ap-northeast-2` | [arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:26](#){: .copyMe}:clipboard: | - | `ap-northeast-3` | [arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:26](#){: .copyMe}:clipboard: | - | `ap-south-1` | [arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:26](#){: .copyMe}:clipboard: | - | `ap-southeast-1` | [arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:26](#){: .copyMe}:clipboard: | - | `ap-southeast-2` | [arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:26](#){: .copyMe}:clipboard: | - | `ap-southeast-3` | [arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:26](#){: .copyMe}:clipboard: | - | `ca-central-1` | [arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:26](#){: .copyMe}:clipboard: | - | `eu-central-1` | [arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:26](#){: .copyMe}:clipboard: | - | `eu-north-1` | [arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:26](#){: .copyMe}:clipboard: | - | `eu-south-1` | [arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:26](#){: .copyMe}:clipboard: | - | `eu-west-1` | [arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:26](#){: .copyMe}:clipboard: | - | `eu-west-2` | [arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:26](#){: .copyMe}:clipboard: | - | `eu-west-3` | [arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:26](#){: .copyMe}:clipboard: | - | `me-south-1` | [arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:26](#){: .copyMe}:clipboard: | - | `sa-east-1` | [arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:26](#){: .copyMe}:clipboard: | - | `us-east-1` | [arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:26](#){: .copyMe}:clipboard: | - | `us-east-2` | [arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:26](#){: .copyMe}:clipboard: | - | `us-west-1` | [arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:26](#){: .copyMe}:clipboard: | - | `us-west-2` | [arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:26](#){: .copyMe}:clipboard: | + | `af-south-1` | [arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:27](#){: .copyMe}:clipboard: | + | `ap-east-1` | [arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:27](#){: .copyMe}:clipboard: | + | `ap-northeast-1` | [arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:27](#){: .copyMe}:clipboard: | + | `ap-northeast-2` | [arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:27](#){: .copyMe}:clipboard: | + | `ap-northeast-3` | [arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:27](#){: .copyMe}:clipboard: | + | `ap-south-1` | [arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:27](#){: .copyMe}:clipboard: | + | `ap-southeast-1` | [arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:27](#){: .copyMe}:clipboard: | + | `ap-southeast-2` | [arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:27](#){: .copyMe}:clipboard: | + | `ap-southeast-3` | [arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:27](#){: .copyMe}:clipboard: | + | `ca-central-1` | [arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:27](#){: .copyMe}:clipboard: | + | `eu-central-1` | [arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:27](#){: .copyMe}:clipboard: | + | `eu-north-1` | [arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:27](#){: .copyMe}:clipboard: | + | `eu-south-1` | [arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:27](#){: .copyMe}:clipboard: | + | `eu-west-1` | [arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:27](#){: .copyMe}:clipboard: | + | `eu-west-2` | [arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:27](#){: .copyMe}:clipboard: | + | `eu-west-3` | [arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:27](#){: .copyMe}:clipboard: | + | `me-south-1` | [arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:27](#){: .copyMe}:clipboard: | + | `sa-east-1` | [arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:27](#){: .copyMe}:clipboard: | + | `us-east-1` | [arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:27](#){: .copyMe}:clipboard: | + | `us-east-2` | [arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:27](#){: .copyMe}:clipboard: | + | `us-west-1` | [arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:27](#){: .copyMe}:clipboard: | + | `us-west-2` | [arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:27](#){: .copyMe}:clipboard: | ??? note "Note: Click to expand and copy code snippets for popular frameworks" @@ -139,7 +139,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. Type: AWS::Serverless::Function Properties: Layers: - - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:26 + - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:27 ``` === "Serverless framework" @@ -149,7 +149,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. hello: handler: lambda_function.lambda_handler layers: - - arn:aws:lambda:${aws:region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:26 + - arn:aws:lambda:${aws:region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:27 ``` === "CDK" @@ -165,7 +165,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. powertools_layer = aws_lambda.LayerVersion.from_layer_version_arn( self, id="lambda-powertools", - layer_version_arn=f"arn:aws:lambda:{env.region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:26" + layer_version_arn=f"arn:aws:lambda:{env.region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:27" ) aws_lambda.Function(self, 'sample-app-lambda', @@ -214,7 +214,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. role = aws_iam_role.iam_for_lambda.arn handler = "index.test" runtime = "python3.9" - layers = ["arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:26"] + layers = ["arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:27"] source_code_hash = filebase64sha256("lambda_function_payload.zip") } @@ -267,7 +267,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. ? Do you want to configure advanced settings? Yes ... ? Do you want to enable Lambda layers for this function? Yes - ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:26 + ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:27 ❯ amplify push -y @@ -278,7 +278,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. - Name: ? Which setting do you want to update? Lambda layers configuration ? Do you want to enable Lambda layers for this function? Yes - ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:26 + ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:27 ? Do you want to edit the local lambda function now? No ``` @@ -292,7 +292,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. Properties: Architectures: [arm64] Layers: - - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:26 + - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:27 ``` === "Serverless framework" @@ -303,7 +303,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. handler: lambda_function.lambda_handler architecture: arm64 layers: - - arn:aws:lambda:${aws:region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:26 + - arn:aws:lambda:${aws:region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:27 ``` === "CDK" @@ -319,7 +319,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. powertools_layer = aws_lambda.LayerVersion.from_layer_version_arn( self, id="lambda-powertools", - layer_version_arn=f"arn:aws:lambda:{env.region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:26" + layer_version_arn=f"arn:aws:lambda:{env.region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:27" ) aws_lambda.Function(self, 'sample-app-lambda', @@ -369,7 +369,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. role = aws_iam_role.iam_for_lambda.arn handler = "index.test" runtime = "python3.9" - layers = ["arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:26"] + layers = ["arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:27"] architectures = ["arm64"] source_code_hash = filebase64sha256("lambda_function_payload.zip") @@ -425,7 +425,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. ? Do you want to configure advanced settings? Yes ... ? Do you want to enable Lambda layers for this function? Yes - ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:26 + ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:27 ❯ amplify push -y @@ -436,7 +436,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. - Name: ? Which setting do you want to update? Lambda layers configuration ? Do you want to enable Lambda layers for this function? Yes - ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:26 + ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:27 ? Do you want to edit the local lambda function now? No ``` @@ -444,7 +444,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. Change {region} to your AWS region, e.g. `eu-west-1` ```bash title="AWS CLI" - aws lambda get-layer-version-by-arn --arn arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:26 --region {region} + aws lambda get-layer-version-by-arn --arn arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:27 --region {region} ``` The pre-signed URL to download this Lambda Layer will be within `Location` key. From a76a554ca89042e37c63caf3b39421310035d8ce Mon Sep 17 00:00:00 2001 From: Ruben Fonseca Date: Fri, 14 Apr 2023 12:40:46 +0200 Subject: [PATCH 022/100] fix(ci): replace the correct files for Layer ARN --- .github/workflows/reusable_update_v2_layer_arn_docs.yml | 2 +- layer/scripts/update_layer_arn.sh | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/reusable_update_v2_layer_arn_docs.yml b/.github/workflows/reusable_update_v2_layer_arn_docs.yml index 5e6a235654f..142d0a32e75 100644 --- a/.github/workflows/reusable_update_v2_layer_arn_docs.yml +++ b/.github/workflows/reusable_update_v2_layer_arn_docs.yml @@ -46,7 +46,7 @@ jobs: run: | HAS_CHANGE=$(git status --porcelain) test -z "${HAS_CHANGE}" && echo "Nothing to update" && exit 0 - git add docs/index.md docs/core/logger.md docs/core/tracer.md docs/core/metrics.md + git add docs/index.md examples git commit -m "chore: update v2 layer ARN on documentation" git pull origin "${BRANCH}" # prevents concurrent branch update failing push git push origin HEAD:refs/heads/"${BRANCH}" diff --git a/layer/scripts/update_layer_arn.sh b/layer/scripts/update_layer_arn.sh index 0ab86e58af4..55734941839 100755 --- a/layer/scripts/update_layer_arn.sh +++ b/layer/scripts/update_layer_arn.sh @@ -68,9 +68,9 @@ for file in $files; do sed -i -e "s/$prefix_pseudo_region:[[:digit:]][[:digit:]]*/$line_pseudo_region/g" docs/index.md # The same strings can also be found in examples on Logger, Tracer and Metrics - sed -i -e "s/$prefix_pseudo_region:[[:digit:]][[:digit:]]*/$line_pseudo_region/g" docs/core/logger.md - sed -i -e "s/$prefix_pseudo_region:[[:digit:]][[:digit:]]*/$line_pseudo_region/g" docs/core/metrics.md - sed -i -e "s/$prefix_pseudo_region:[[:digit:]][[:digit:]]*/$line_pseudo_region/g" docs/core/tracer.md + sed -i -e "s/$prefix_pseudo_region:[[:digit:]][[:digit:]]*/$line_pseudo_region/g" examples/logger/sam/template.yaml + sed -i -e "s/$prefix_pseudo_region:[[:digit:]][[:digit:]]*/$line_pseudo_region/g" examples/metrics/sam/template.yaml + sed -i -e "s/$prefix_pseudo_region:[[:digit:]][[:digit:]]*/$line_pseudo_region/g" examples/tracer/sam/template.yaml done fi done From 52b15547d291a52bb13c04d0f7202a6486f8678d Mon Sep 17 00:00:00 2001 From: Ruben Fonseca Date: Fri, 14 Apr 2023 13:24:21 +0200 Subject: [PATCH 023/100] chore(ci): add support for x86-64 regions only (#2122) --- .../reusable_deploy_v2_layer_stack.yml | 86 +++++++--- layer/app.py | 2 +- layer/layer/canary_stack.py | 49 +++++- layer/layer/layer_stack.py | 161 ++++++++++++++---- layer/poetry.lock | 160 +++++++---------- layer/pyproject.toml | 2 +- 6 files changed, 303 insertions(+), 157 deletions(-) diff --git a/.github/workflows/reusable_deploy_v2_layer_stack.yml b/.github/workflows/reusable_deploy_v2_layer_stack.yml index 0365f98b01d..f4b4fe73f24 100644 --- a/.github/workflows/reusable_deploy_v2_layer_stack.yml +++ b/.github/workflows/reusable_deploy_v2_layer_stack.yml @@ -34,31 +34,63 @@ jobs: strategy: fail-fast: false matrix: - region: - [ - "af-south-1", - "eu-central-1", - "us-east-1", - "us-east-2", - "us-west-1", - "us-west-2", - "ap-east-1", - "ap-south-1", - "ap-northeast-1", - "ap-northeast-2", - "ap-southeast-1", - "ap-southeast-2", - "ca-central-1", - "eu-west-1", - "eu-west-2", - "eu-west-3", - "eu-south-1", - "eu-north-1", - "sa-east-1", - "ap-southeast-3", - "ap-northeast-3", - "me-south-1", - ] + # To get a list of current regions, use: + # aws ec2 describe-regions --all-regions --query "Regions[].RegionName" --output text | tr "\t" "\n" | sort + include: + - region: "af-south-1" + has_arm64_support: "true" + - region: "ap-east-1" + has_arm64_support: "true" + - region: "ap-northeast-1" + has_arm64_support: "true" + - region: "ap-northeast-2" + has_arm64_support: "true" + - region: "ap-northeast-3" + has_arm64_support: "true" + - region: "ap-south-1" + has_arm64_support: "true" + - region: "ap-south-2" + has_arm64_support: "false" + - region: "ap-southeast-1" + has_arm64_support: "true" + - region: "ap-southeast-2" + has_arm64_support: "true" + - region: "ap-southeast-3" + has_arm64_support: "true" + - region: "ap-southeast-4" + has_arm64_support: "false" + - region: "ca-central-1" + has_arm64_support: "true" + - region: "eu-central-1" + has_arm64_support: "true" + - region: "eu-central-2" + has_arm64_support: "false" + - region: "eu-north-1" + has_arm64_support: "true" + - region: "eu-south-1" + has_arm64_support: "true" + - region: "eu-south-2" + has_arm64_support: "false" + - region: "eu-west-1" + has_arm64_support: "true" + - region: "eu-west-2" + has_arm64_support: "true" + - region: "eu-west-3" + has_arm64_support: "true" + - region: "me-central-1" + has_arm64_support: "false" + - region: "me-south-1" + has_arm64_support: "true" + - region: "sa-east-1" + has_arm64_support: "true" + - region: "us-east-1" + has_arm64_support: "true" + - region: "us-east-2" + has_arm64_support: "true" + - region: "us-west-1" + has_arm64_support: "true" + - region: "us-west-2" + has_arm64_support: "true" steps: - name: checkout uses: actions/checkout@v3 @@ -99,7 +131,7 @@ jobs: - name: unzip artefact run: unzip cdk.out.zip - name: CDK Deploy Layer - run: npx cdk deploy --app cdk.out --context region=${{ matrix.region }} 'LayerV2Stack' --require-approval never --verbose --outputs-file cdk-outputs.json + run: npx cdk deploy --app cdk.out --context region=${{ matrix.region }} --parameters HasARM64Support=${{ matrix.has_arm64_support }} 'LayerV2Stack' --require-approval never --verbose --outputs-file cdk-outputs.json - name: Store latest Layer ARN if: ${{ inputs.stage == 'PROD' }} run: | @@ -116,7 +148,7 @@ jobs: if-no-files-found: error retention-days: 1 - name: CDK Deploy Canary - run: npx cdk deploy --app cdk.out --context region=${{ matrix.region}} --parameters DeployStage="${{ inputs.stage }}" 'CanaryV2Stack' --require-approval never --verbose + run: npx cdk deploy --app cdk.out --context region=${{ matrix.region }} --parameters DeployStage="${{ inputs.stage }}" --parameters HasARM64Support=${{ matrix.has_arm64_support }} 'CanaryV2Stack' --require-approval never --verbose update_v2_layer_arn_docs: needs: deploy-cdk-stack diff --git a/layer/app.py b/layer/app.py index 59a35dfd300..f9d0f778df0 100644 --- a/layer/app.py +++ b/layer/app.py @@ -21,7 +21,7 @@ app, "LayerV2Stack", powertools_version=POWERTOOLS_VERSION, - ssm_paramter_layer_arn=SSM_PARAM_LAYER_ARN, + ssm_parameter_layer_arn=SSM_PARAM_LAYER_ARN, ssm_parameter_layer_arm64_arn=SSM_PARAM_LAYER_ARM64_ARN, ) diff --git a/layer/layer/canary_stack.py b/layer/layer/canary_stack.py index fda9ebff3ad..e7034439063 100644 --- a/layer/layer/canary_stack.py +++ b/layer/layer/canary_stack.py @@ -1,7 +1,24 @@ import uuid -from aws_cdk import CfnParameter, CustomResource, Duration, Stack -from aws_cdk.aws_iam import Effect, ManagedPolicy, PolicyStatement, Role, ServicePrincipal +import jsii +from aws_cdk import ( + Aspects, + CfnCondition, + CfnParameter, + CfnResource, + CustomResource, + Duration, + Fn, + IAspect, + Stack, +) +from aws_cdk.aws_iam import ( + Effect, + ManagedPolicy, + PolicyStatement, + Role, + ServicePrincipal, +) from aws_cdk.aws_lambda import Architecture, Code, Function, LayerVersion, Runtime from aws_cdk.aws_logs import RetentionDays from aws_cdk.aws_ssm import StringParameter @@ -13,6 +30,16 @@ ) +@jsii.implements(IAspect) +class ApplyCondition: + def __init__(self, condition: CfnCondition): + self.condition = condition + + def visit(self, node): + if isinstance(node, CfnResource): + node.cfn_options.condition = self.condition + + class CanaryStack(Stack): def __init__( self, @@ -29,6 +56,20 @@ def __init__( self, "DeployStage", description="Deployment stage for canary" ).value_as_string + has_arm64_support = CfnParameter( + self, + "HasARM64Support", + description="Has ARM64 Support Condition", + type="String", + allowed_values=["true", "false"], + ) + + has_arm64_condition = CfnCondition( + self, + "HasARM64SupportCondition", + expression=Fn.condition_equals(has_arm64_support, "true"), + ) + layer_arn = StringParameter.from_string_parameter_attributes( self, "LayerVersionArnParam", parameter_name=ssm_paramter_layer_arn ).string_value @@ -46,7 +87,8 @@ def __init__( "LayerArm64VersionArnParam", parameter_name=ssm_parameter_layer_arm64_arn, ).string_value - Canary( + + arm64_canary = Canary( self, "Canary-arm64", layer_arn=layer_arm64_arn, @@ -54,6 +96,7 @@ def __init__( architecture=Architecture.ARM_64, stage=deploy_stage, ) + Aspects.of(arm64_canary).add(ApplyCondition(has_arm64_condition)) class Canary(Construct): diff --git a/layer/layer/layer_stack.py b/layer/layer/layer_stack.py index 6a92e1fa408..48c526be5e2 100644 --- a/layer/layer/layer_stack.py +++ b/layer/layer/layer_stack.py @@ -1,18 +1,43 @@ -from aws_cdk import CfnOutput, RemovalPolicy, Stack +from typing import Optional + +import jsii +from aws_cdk import ( + Aspects, + CfnCondition, + CfnOutput, + CfnParameter, + CfnResource, + Fn, + IAspect, + RemovalPolicy, + Stack, +) from aws_cdk.aws_lambda import Architecture, CfnLayerVersionPermission from aws_cdk.aws_ssm import StringParameter from cdk_aws_lambda_powertools_layer import LambdaPowertoolsLayer from constructs import Construct -class LayerStack(Stack): +@jsii.implements(IAspect) +class ApplyCondition: + def __init__(self, condition: CfnCondition): + self.condition = condition + + def visit(self, node): + if isinstance(node, CfnResource): + node.cfn_options.condition = self.condition + if isinstance(node, CfnOutput): + node.condition = self.condition + + +class Layer(Construct): def __init__( self, scope: Construct, construct_id: str, + layer_version_name: str, powertools_version: str, - ssm_paramter_layer_arn: str, - ssm_parameter_layer_arm64_arn: str, + architecture: Optional[Architecture] = None, **kwargs ) -> None: super().__init__(scope, construct_id, **kwargs) @@ -20,20 +45,14 @@ def __init__( layer = LambdaPowertoolsLayer( self, "Layer", - layer_version_name="AWSLambdaPowertoolsPythonV2", + layer_version_name=layer_version_name, version=powertools_version, include_extras=True, - compatible_architectures=[Architecture.X86_64], + compatible_architectures=[architecture] if architecture else [], ) + layer.apply_removal_policy(RemovalPolicy.RETAIN) - layer_arm64 = LambdaPowertoolsLayer( - self, - "Layer-ARM64", - layer_version_name="AWSLambdaPowertoolsPythonV2-Arm64", - version=powertools_version, - include_extras=True, - compatible_architectures=[Architecture.ARM_64], - ) + self.layer_version_arn = layer.layer_version_arn layer_permission = CfnLayerVersionPermission( self, @@ -42,33 +61,115 @@ def __init__( layer_version_arn=layer.layer_version_arn, principal="*", ) + layer_permission.apply_removal_policy(RemovalPolicy.RETAIN) + + +class LayerStack(Stack): + def __init__( + self, + scope: Construct, + construct_id: str, + powertools_version: str, + ssm_parameter_layer_arn: str, + ssm_parameter_layer_arm64_arn: str, + **kwargs + ) -> None: + super().__init__(scope, construct_id, **kwargs) - layer_permission_arm64 = CfnLayerVersionPermission( + has_arm64_support = CfnParameter( self, - "PublicLayerAccessArm64", - action="lambda:GetLayerVersion", - layer_version_arn=layer_arm64.layer_version_arn, - principal="*", + "HasARM64Suppor", + description="Has ARM64 Support Condition", + type="String", + allowed_values=["true", "false"], ) - layer_permission.apply_removal_policy(RemovalPolicy.RETAIN) - layer_permission_arm64.apply_removal_policy(RemovalPolicy.RETAIN) + has_arm64_condition = CfnCondition( + self, + "HasARM64SupportCondition", + expression=Fn.condition_equals(has_arm64_support, "true"), + ) + has_no_arm64_condition = CfnCondition( + self, + "HasNOArm64SupportCondition", + expression=Fn.condition_equals(has_arm64_support, "false"), + ) - layer.apply_removal_policy(RemovalPolicy.RETAIN) - layer_arm64.apply_removal_policy(RemovalPolicy.RETAIN) + # The following code is used when the region does not support ARM64 Lambdas. We make sure to only create the + # X86_64 Layer without specifying any compatible architecture, which would result in a CloudFormation error. - StringParameter( + layer_single = Layer( + self, + "LayerSingle", + layer_version_name="AWSLambdaPowertoolsPythonV2", + powertools_version=powertools_version, + ) + Aspects.of(layer_single).add(ApplyCondition(has_no_arm64_condition)) + + Aspects.of( + StringParameter( + self, + "SingleVersionArn", + parameter_name=ssm_parameter_layer_arn, + string_value=layer_single.layer_version_arn, + ) + ).add(ApplyCondition(has_no_arm64_condition)) + + # The following code is used when the region has support for ARM64 Lambdas. In this case, we explicitly + # create a Layer for both X86_64 and ARM64, specifying the compatible architectures. + + # X86_64 layer + + layer = Layer( + self, + "Layer", + layer_version_name="AWSLambdaPowertoolsPythonV2", + powertools_version=powertools_version, + architecture=Architecture.X86_64, + ) + Aspects.of(layer).add(ApplyCondition(has_arm64_condition)) + + Aspects.of( + StringParameter( + self, + "VersionArn", + parameter_name=ssm_parameter_layer_arn, + string_value=layer.layer_version_arn, + ) + ).add(ApplyCondition(has_arm64_condition)) + + CfnOutput( self, - "VersionArn", - parameter_name=ssm_paramter_layer_arn, - string_value=layer.layer_version_arn, + "LatestLayerArn", + value=Fn.condition_if( + has_arm64_condition.logical_id, + layer.layer_version_arn, + layer_single.layer_version_arn, + ).to_string(), ) + + # ARM64 layer + + layer_arm64 = Layer( + self, + "Layer-ARM64", + layer_version_name="AWSLambdaPowertoolsPythonV2-Arm64", + powertools_version=powertools_version, + architecture=Architecture.ARM_64, + ) + Aspects.of(layer_arm64).add(ApplyCondition(has_arm64_condition)) + StringParameter( self, "Arm64VersionArn", parameter_name=ssm_parameter_layer_arm64_arn, - string_value=layer_arm64.layer_version_arn, + string_value=Fn.condition_if( + has_arm64_condition.logical_id, + layer_arm64.layer_version_arn, + "none", + ).to_string(), ) - CfnOutput(self, "LatestLayerArn", value=layer.layer_version_arn) - CfnOutput(self, "LatestLayerArm64Arn", value=layer_arm64.layer_version_arn) + Aspects.of( + CfnOutput(self, "LatestLayerArm64Arn", value=layer_arm64.layer_version_arn) + ).add(ApplyCondition(has_arm64_condition)) diff --git a/layer/poetry.lock b/layer/poetry.lock index c7e991e3db9..39faf15d289 100644 --- a/layer/poetry.lock +++ b/layer/poetry.lock @@ -2,32 +2,33 @@ [[package]] name = "attrs" -version = "22.1.0" +version = "22.2.0" description = "Classes Without Boilerplate" category = "main" optional = false -python-versions = ">=3.5" +python-versions = ">=3.6" files = [ - {file = "attrs-22.1.0-py2.py3-none-any.whl", hash = "sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c"}, - {file = "attrs-22.1.0.tar.gz", hash = "sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6"}, + {file = "attrs-22.2.0-py3-none-any.whl", hash = "sha256:29e95c7f6778868dbd49170f98f8818f78f3dc5e0e37c0b1f474e3561b240836"}, + {file = "attrs-22.2.0.tar.gz", hash = "sha256:c9227bfc2f01993c03f68db37d1d15c9690188323c067c641f1a35ca58185f99"}, ] [package.extras] -dev = ["cloudpickle", "coverage[toml] (>=5.0.2)", "furo", "hypothesis", "mypy (>=0.900,!=0.940)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "sphinx", "sphinx-notfound-page", "zope.interface"] -docs = ["furo", "sphinx", "sphinx-notfound-page", "zope.interface"] -tests = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "zope.interface"] -tests-no-zope = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins"] +cov = ["attrs[tests]", "coverage-enable-subprocess", "coverage[toml] (>=5.3)"] +dev = ["attrs[docs,tests]"] +docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope.interface"] +tests = ["attrs[tests-no-zope]", "zope.interface"] +tests-no-zope = ["cloudpickle", "cloudpickle", "hypothesis", "hypothesis", "mypy (>=0.971,<0.990)", "mypy (>=0.971,<0.990)", "pympler", "pympler", "pytest (>=4.3.0)", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-mypy-plugins", "pytest-xdist[psutil]", "pytest-xdist[psutil]"] [[package]] name = "aws-cdk-asset-awscli-v1" -version = "2.2.137" +version = "2.2.138" description = "A library that contains the AWS CLI for use in Lambda Layers" category = "main" optional = false python-versions = "~=3.7" files = [ - {file = "aws-cdk.asset-awscli-v1-2.2.137.tar.gz", hash = "sha256:699e17416635f82d3a92ff5edc99725b4d473b1be2b22b38e060d4aa2153683e"}, - {file = "aws_cdk.asset_awscli_v1-2.2.137-py3-none-any.whl", hash = "sha256:cbd931a07c817c0cced3431a6d19f8169a7d95ec0dbb15d7b28ad8e11f3cdf1a"}, + {file = "aws-cdk.asset-awscli-v1-2.2.138.tar.gz", hash = "sha256:0a6880aa02399f74102e120aee96db75ec122a199b0735494c3dbcd09bd89c9c"}, + {file = "aws_cdk.asset_awscli_v1-2.2.138-py3-none-any.whl", hash = "sha256:d1f4e1b6a4bf5e9f1a7380a6141a3bf55d6fb6f1abfb0e1450bb258de3702f01"}, ] [package.dependencies] @@ -54,14 +55,14 @@ typeguard = ">=2.13.3,<2.14.0" [[package]] name = "aws-cdk-asset-node-proxy-agent-v5" -version = "2.0.113" +version = "2.0.114" description = "@aws-cdk/asset-node-proxy-agent-v5" category = "main" optional = false python-versions = "~=3.7" files = [ - {file = "aws-cdk.asset-node-proxy-agent-v5-2.0.113.tar.gz", hash = "sha256:bdd26ce3689940373af73739f01b8e4a12fb701a64976c30e2532d481e0e7b35"}, - {file = "aws_cdk.asset_node_proxy_agent_v5-2.0.113-py3-none-any.whl", hash = "sha256:179264ce2ad15fb4252995b2320f75ae1b3472881f1d5371137d4f6549137db8"}, + {file = "aws-cdk.asset-node-proxy-agent-v5-2.0.114.tar.gz", hash = "sha256:5f8a0ecb4128617ef8321dd1b3501b52e4a071e7481a7d1498775897299f7349"}, + {file = "aws_cdk.asset_node_proxy_agent_v5-2.0.114-py3-none-any.whl", hash = "sha256:3b034917bd15f84c710b031dbd29d7fbbb665ce16a609eaabd890fa47949df40"}, ] [package.dependencies] @@ -92,18 +93,18 @@ typeguard = ">=2.13.3,<2.14.0" [[package]] name = "boto3" -version = "1.24.89" +version = "1.26.112" description = "The AWS SDK for Python" category = "dev" optional = false python-versions = ">= 3.7" files = [ - {file = "boto3-1.24.89-py3-none-any.whl", hash = "sha256:346f8f0d101a4261dac146a959df18d024feda6431e1d9d84f94efd24d086cae"}, - {file = "boto3-1.24.89.tar.gz", hash = "sha256:d0d8ffcdc10821c4562bc7f935cdd840033bbc342ac0e14b6bdd348b3adf4c04"}, + {file = "boto3-1.26.112-py3-none-any.whl", hash = "sha256:03c2e1ddd29d993a6ab9b8a8fe184027957fc32bd405c496ad0c30311445925f"}, + {file = "boto3-1.26.112.tar.gz", hash = "sha256:4ea3319bba2e8ff7cd9560259ae64f073c7fb6312158aa375777687231cabe69"}, ] [package.dependencies] -botocore = ">=1.27.89,<1.28.0" +botocore = ">=1.29.112,<1.30.0" jmespath = ">=0.7.1,<2.0.0" s3transfer = ">=0.6.0,<0.7.0" @@ -112,14 +113,14 @@ crt = ["botocore[crt] (>=1.21.0,<2.0a0)"] [[package]] name = "botocore" -version = "1.27.89" +version = "1.29.112" description = "Low-level, data-driven core of boto 3." category = "dev" optional = false python-versions = ">= 3.7" files = [ - {file = "botocore-1.27.89-py3-none-any.whl", hash = "sha256:238f1dfdb8d8d017c2aea082609a3764f3161d32745900f41bcdcf290d95a048"}, - {file = "botocore-1.27.89.tar.gz", hash = "sha256:621f5413be8f97712b7e36c1b075a8791d1d1b9971a7ee060cdcdf5e2debf6c1"}, + {file = "botocore-1.29.112-py3-none-any.whl", hash = "sha256:2cbaddb09b46dcb0a05490724d51acb224d3a8df433c347f995b4d78bfb02c8a"}, + {file = "botocore-1.29.112.tar.gz", hash = "sha256:1f52d9371d7b5ee30a53dcef7954c3cf22e04b131cfab5268035f3299ccde9e1"}, ] [package.dependencies] @@ -128,34 +129,34 @@ python-dateutil = ">=2.1,<3.0.0" urllib3 = ">=1.25.4,<1.27" [package.extras] -crt = ["awscrt (==0.14.0)"] +crt = ["awscrt (==0.16.9)"] [[package]] name = "cattrs" -version = "22.1.0" +version = "22.2.0" description = "Composable complex class support for attrs and dataclasses." category = "main" optional = false -python-versions = ">=3.7,<4.0" +python-versions = ">=3.7" files = [ - {file = "cattrs-22.1.0-py3-none-any.whl", hash = "sha256:d55c477b4672f93606e992049f15d526dc7867e6c756cd6256d4af92e2b1e364"}, - {file = "cattrs-22.1.0.tar.gz", hash = "sha256:94b67b64cf92c994f8784c40c082177dc916e0489a73a9a36b24eb18a9db40c6"}, + {file = "cattrs-22.2.0-py3-none-any.whl", hash = "sha256:bc12b1f0d000b9f9bee83335887d532a1d3e99a833d1bf0882151c97d3e68c21"}, + {file = "cattrs-22.2.0.tar.gz", hash = "sha256:f0eed5642399423cf656e7b66ce92cdc5b963ecafd041d1b24d136fdde7acf6d"}, ] [package.dependencies] attrs = ">=20" -exceptiongroup = {version = "*", markers = "python_version <= \"3.10\""} +exceptiongroup = {version = "*", markers = "python_version < \"3.11\""} [[package]] name = "cdk-aws-lambda-powertools-layer" -version = "3.3.1" +version = "3.4.0" description = "A lambda layer for AWS Powertools for python and typescript" category = "main" optional = false python-versions = "~=3.7" files = [ - {file = "cdk-aws-lambda-powertools-layer-3.3.1.tar.gz", hash = "sha256:6cc48ec407a351bed40af64fc810eb51c6b619baa66fe1d6457c1d5ba195a632"}, - {file = "cdk_aws_lambda_powertools_layer-3.3.1-py3-none-any.whl", hash = "sha256:9c050a8edf787538cd802cf67bfb5a6843c4b00e11584cfa5f9d359c8a46c946"}, + {file = "cdk-aws-lambda-powertools-layer-3.4.0.tar.gz", hash = "sha256:3d3e89cb3b0f201f6f96473208e66b18279688049317d9c9849584a03c5d54a0"}, + {file = "cdk_aws_lambda_powertools_layer-3.4.0-py3-none-any.whl", hash = "sha256:bb3c157de17d3fbdcbdc33e5ee967cc80606bbb7a14f46e4f1f6cc8c28db5c86"}, ] [package.dependencies] @@ -167,43 +168,43 @@ typeguard = ">=2.13.3,<2.14.0" [[package]] name = "colorama" -version = "0.4.5" +version = "0.4.6" description = "Cross-platform colored terminal text." category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" files = [ - {file = "colorama-0.4.5-py2.py3-none-any.whl", hash = "sha256:854bf444933e37f5824ae7bfc1e98d5bce2ebe4160d46b5edf346a89358e99da"}, - {file = "colorama-0.4.5.tar.gz", hash = "sha256:e6c6b4334fc50988a639d9b98aa429a0b57da6e17b9a44f0451f930b6967b7a4"}, + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] [[package]] name = "constructs" -version = "10.1.128" +version = "10.1.309" description = "A programming model for software-defined state" category = "main" optional = false python-versions = "~=3.7" files = [ - {file = "constructs-10.1.128-py3-none-any.whl", hash = "sha256:d6fbc88de4c2517b59e28a9d0bc3663e75decbe3464030b5bc53809868b52c9e"}, - {file = "constructs-10.1.128.tar.gz", hash = "sha256:6789412823ae27b39f659537337f688a9d555cad5845d4b821c7be02a061be1e"}, + {file = "constructs-10.1.309-py3-none-any.whl", hash = "sha256:3127067e99151d1094b05443452bc9f84c685a719c00031c7b5e55e294e0deb7"}, + {file = "constructs-10.1.309.tar.gz", hash = "sha256:cbc36a68187d4c9dd33b46b87aac2dda469bfda95c37d4c198bd98911064dce8"}, ] [package.dependencies] -jsii = ">=1.69.0,<2.0.0" +jsii = ">=1.80.0,<2.0.0" publication = ">=0.0.3" typeguard = ">=2.13.3,<2.14.0" [[package]] name = "exceptiongroup" -version = "1.0.0rc9" +version = "1.1.1" description = "Backport of PEP 654 (exception groups)" category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "exceptiongroup-1.0.0rc9-py3-none-any.whl", hash = "sha256:2e3c3fc1538a094aab74fad52d6c33fc94de3dfee3ee01f187c0e0c72aec5337"}, - {file = "exceptiongroup-1.0.0rc9.tar.gz", hash = "sha256:9086a4a21ef9b31c72181c77c040a074ba0889ee56a7b289ff0afb0d97655f96"}, + {file = "exceptiongroup-1.1.1-py3-none-any.whl", hash = "sha256:232c37c63e4f682982c8b6459f33a8981039e5fb8756b2074364e5055c498c9e"}, + {file = "exceptiongroup-1.1.1.tar.gz", hash = "sha256:d484c3090ba2889ae2928419117447a14daf3c1231d5e30d0aae34f354f01785"}, ] [package.extras] @@ -230,14 +231,14 @@ testing = ["flake8 (<5)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-chec [[package]] name = "iniconfig" -version = "1.1.1" -description = "iniconfig: brain-dead simple config-ini parsing" +version = "2.0.0" +description = "brain-dead simple config-ini parsing" category = "dev" optional = false -python-versions = "*" +python-versions = ">=3.7" files = [ - {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, - {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, + {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, + {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, ] [[package]] @@ -275,19 +276,16 @@ typing-extensions = ">=3.7,<5.0" [[package]] name = "packaging" -version = "21.3" +version = "23.1" description = "Core utilities for Python packages" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"}, - {file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"}, + {file = "packaging-23.1-py3-none-any.whl", hash = "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61"}, + {file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"}, ] -[package.dependencies] -pyparsing = ">=2.0.2,<3.0.5 || >3.0.5" - [[package]] name = "pluggy" version = "1.0.0" @@ -316,56 +314,28 @@ files = [ {file = "publication-0.0.3.tar.gz", hash = "sha256:68416a0de76dddcdd2930d1c8ef853a743cc96c82416c4e4d3b5d901c6276dc4"}, ] -[[package]] -name = "py" -version = "1.11.0" -description = "library with cross-python path, ini-parsing, io, code, log facilities" -category = "dev" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -files = [ - {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, - {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, -] - -[[package]] -name = "pyparsing" -version = "3.0.9" -description = "pyparsing module - Classes and methods to define and execute parsing grammars" -category = "dev" -optional = false -python-versions = ">=3.6.8" -files = [ - {file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"}, - {file = "pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb"}, -] - -[package.extras] -diagrams = ["jinja2", "railroad-diagrams"] - [[package]] name = "pytest" -version = "7.1.3" +version = "7.3.0" description = "pytest: simple powerful testing with Python" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "pytest-7.1.3-py3-none-any.whl", hash = "sha256:1377bda3466d70b55e3f5cecfa55bb7cfcf219c7964629b967c37cf0bda818b7"}, - {file = "pytest-7.1.3.tar.gz", hash = "sha256:4f365fec2dff9c1162f834d9f18af1ba13062db0c708bf7b946f8a5c76180c39"}, + {file = "pytest-7.3.0-py3-none-any.whl", hash = "sha256:933051fa1bfbd38a21e73c3960cebdad4cf59483ddba7696c48509727e17f201"}, + {file = "pytest-7.3.0.tar.gz", hash = "sha256:58ecc27ebf0ea643ebfdf7fb1249335da761a00c9f955bcd922349bcb68ee57d"}, ] [package.dependencies] -attrs = ">=19.2.0" colorama = {version = "*", markers = "sys_platform == \"win32\""} +exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} iniconfig = "*" packaging = "*" pluggy = ">=0.12,<2.0" -py = ">=1.8.2" -tomli = ">=1.0.0" +tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} [package.extras] -testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "xmlschema"] +testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "xmlschema"] [[package]] name = "python-dateutil" @@ -442,26 +412,26 @@ test = ["mypy", "pytest", "typing-extensions"] [[package]] name = "typing-extensions" -version = "4.4.0" +version = "4.5.0" description = "Backported and Experimental Type Hints for Python 3.7+" category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "typing_extensions-4.4.0-py3-none-any.whl", hash = "sha256:16fa4864408f655d35ec496218b85f79b3437c829e93320c7c9215ccfd92489e"}, - {file = "typing_extensions-4.4.0.tar.gz", hash = "sha256:1511434bb92bf8dd198c12b1cc812e800d4181cfcb867674e0f8279cc93087aa"}, + {file = "typing_extensions-4.5.0-py3-none-any.whl", hash = "sha256:fb33085c39dd998ac16d1431ebc293a8b3eedd00fd4a32de0ff79002c19511b4"}, + {file = "typing_extensions-4.5.0.tar.gz", hash = "sha256:5cb5f4a79139d699607b3ef622a1dedafa84e115ab0024e0d9c044a9479ca7cb"}, ] [[package]] name = "urllib3" -version = "1.26.12" +version = "1.26.15" description = "HTTP library with thread-safe connection pooling, file post, and more." category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, <4" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" files = [ - {file = "urllib3-1.26.12-py2.py3-none-any.whl", hash = "sha256:b930dd878d5a8afb066a637fbb35144fe7901e3b209d1cd4f524bd0e9deee997"}, - {file = "urllib3-1.26.12.tar.gz", hash = "sha256:3fa96cf423e6987997fc326ae8df396db2a8b7c667747d47ddd8ecba91f4a74e"}, + {file = "urllib3-1.26.15-py2.py3-none-any.whl", hash = "sha256:aa751d169e23c7479ce47a0cb0da579e3ede798f994f5816a74e4f4500dcea42"}, + {file = "urllib3-1.26.15.tar.gz", hash = "sha256:8a388717b9476f934a21484e8c8e61875ab60644d29b9b39e11e4b9dc1c6b305"}, ] [package.extras] @@ -488,4 +458,4 @@ testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more [metadata] lock-version = "2.0" python-versions = "^3.9" -content-hash = "8e77638e46b8fc0affe4fc283c80bf17846ccdfd357832343bb9fc07f47a8f77" +content-hash = "ade085b1989174ee03e7f27a781b580e2f7199441da6d8f60b3bf7891f6ca66e" diff --git a/layer/pyproject.toml b/layer/pyproject.toml index 4c46e7b4412..5f10af27b94 100644 --- a/layer/pyproject.toml +++ b/layer/pyproject.toml @@ -7,7 +7,7 @@ license = "MIT" [tool.poetry.dependencies] python = "^3.9" -cdk-aws-lambda-powertools-layer = "^3.3.1" +cdk-aws-lambda-powertools-layer = "^3.4.0" [tool.poetry.dev-dependencies] pytest = "^7.1.2" From 77dd07e433f1b043f1c2e6210472264b89318994 Mon Sep 17 00:00:00 2001 From: Ruben Fonseca Date: Fri, 14 Apr 2023 13:35:29 +0200 Subject: [PATCH 024/100] fix(ci): typo --- layer/layer/layer_stack.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/layer/layer/layer_stack.py b/layer/layer/layer_stack.py index 48c526be5e2..a2a08437051 100644 --- a/layer/layer/layer_stack.py +++ b/layer/layer/layer_stack.py @@ -78,7 +78,7 @@ def __init__( has_arm64_support = CfnParameter( self, - "HasARM64Suppor", + "HasARM64Support", description="Has ARM64 Support Condition", type="String", allowed_values=["true", "false"], From cf3185cb8abe4ac08ea5c6855e95f3c33353f580 Mon Sep 17 00:00:00 2001 From: Release bot Date: Fri, 14 Apr 2023 11:50:16 +0000 Subject: [PATCH 025/100] chore: update v2 layer ARN on documentation --- docs/index.md | 118 +++++++++++++++++++++++++------------------------- 1 file changed, 59 insertions(+), 59 deletions(-) diff --git a/docs/index.md b/docs/index.md index 9bd8295837b..d44c1dc40f2 100644 --- a/docs/index.md +++ b/docs/index.md @@ -26,8 +26,8 @@ Powertools is a developer toolkit to implement Serverless best practices and inc You can install Powertools using one of the following options: -* **Lambda Layer (x86_64)**: [**arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:27**](#){: .copyMe}:clipboard: -* **Lambda Layer (arm64)**: [**arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:27**](#){: .copyMe}:clipboard: +* **Lambda Layer (x86_64)**: [**arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:28**](#){: .copyMe}:clipboard: +* **Lambda Layer (arm64)**: [**arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:28**](#){: .copyMe}:clipboard: * **Pip**: **[`pip install "aws-lambda-powertools"`](#){: .copyMe}:clipboard:** ??? question "Using Pip? You might need to install additional dependencies." @@ -78,55 +78,55 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. | Region | Layer ARN | | ---------------- | ---------------------------------------------------------------------------------------------------------- | - | `af-south-1` | [arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:27](#){: .copyMe}:clipboard: | - | `ap-east-1` | [arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:27](#){: .copyMe}:clipboard: | - | `ap-northeast-1` | [arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:27](#){: .copyMe}:clipboard: | - | `ap-northeast-2` | [arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:27](#){: .copyMe}:clipboard: | - | `ap-northeast-3` | [arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:27](#){: .copyMe}:clipboard: | - | `ap-south-1` | [arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:27](#){: .copyMe}:clipboard: | - | `ap-southeast-1` | [arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:27](#){: .copyMe}:clipboard: | - | `ap-southeast-2` | [arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:27](#){: .copyMe}:clipboard: | - | `ap-southeast-3` | [arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:27](#){: .copyMe}:clipboard: | - | `ca-central-1` | [arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:27](#){: .copyMe}:clipboard: | - | `eu-central-1` | [arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:27](#){: .copyMe}:clipboard: | - | `eu-north-1` | [arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:27](#){: .copyMe}:clipboard: | - | `eu-south-1` | [arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:27](#){: .copyMe}:clipboard: | - | `eu-west-1` | [arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:27](#){: .copyMe}:clipboard: | - | `eu-west-2` | [arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:27](#){: .copyMe}:clipboard: | - | `eu-west-3` | [arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:27](#){: .copyMe}:clipboard: | - | `me-south-1` | [arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:27](#){: .copyMe}:clipboard: | - | `sa-east-1` | [arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:27](#){: .copyMe}:clipboard: | - | `us-east-1` | [arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:27](#){: .copyMe}:clipboard: | - | `us-east-2` | [arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:27](#){: .copyMe}:clipboard: | - | `us-west-1` | [arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:27](#){: .copyMe}:clipboard: | - | `us-west-2` | [arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:27](#){: .copyMe}:clipboard: | + | `af-south-1` | [arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | + | `ap-east-1` | [arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | + | `ap-northeast-1` | [arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | + | `ap-northeast-2` | [arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | + | `ap-northeast-3` | [arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | + | `ap-south-1` | [arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | + | `ap-southeast-1` | [arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | + | `ap-southeast-2` | [arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | + | `ap-southeast-3` | [arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | + | `ca-central-1` | [arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | + | `eu-central-1` | [arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | + | `eu-north-1` | [arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | + | `eu-south-1` | [arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | + | `eu-west-1` | [arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | + | `eu-west-2` | [arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | + | `eu-west-3` | [arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | + | `me-south-1` | [arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | + | `sa-east-1` | [arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | + | `us-east-1` | [arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | + | `us-east-2` | [arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | + | `us-west-1` | [arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | + | `us-west-2` | [arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | === "arm64" | Region | Layer ARN | | ---------------- | ---------------------------------------------------------------------------------------------------------------- | - | `af-south-1` | [arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:27](#){: .copyMe}:clipboard: | - | `ap-east-1` | [arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:27](#){: .copyMe}:clipboard: | - | `ap-northeast-1` | [arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:27](#){: .copyMe}:clipboard: | - | `ap-northeast-2` | [arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:27](#){: .copyMe}:clipboard: | - | `ap-northeast-3` | [arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:27](#){: .copyMe}:clipboard: | - | `ap-south-1` | [arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:27](#){: .copyMe}:clipboard: | - | `ap-southeast-1` | [arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:27](#){: .copyMe}:clipboard: | - | `ap-southeast-2` | [arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:27](#){: .copyMe}:clipboard: | - | `ap-southeast-3` | [arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:27](#){: .copyMe}:clipboard: | - | `ca-central-1` | [arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:27](#){: .copyMe}:clipboard: | - | `eu-central-1` | [arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:27](#){: .copyMe}:clipboard: | - | `eu-north-1` | [arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:27](#){: .copyMe}:clipboard: | - | `eu-south-1` | [arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:27](#){: .copyMe}:clipboard: | - | `eu-west-1` | [arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:27](#){: .copyMe}:clipboard: | - | `eu-west-2` | [arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:27](#){: .copyMe}:clipboard: | - | `eu-west-3` | [arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:27](#){: .copyMe}:clipboard: | - | `me-south-1` | [arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:27](#){: .copyMe}:clipboard: | - | `sa-east-1` | [arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:27](#){: .copyMe}:clipboard: | - | `us-east-1` | [arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:27](#){: .copyMe}:clipboard: | - | `us-east-2` | [arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:27](#){: .copyMe}:clipboard: | - | `us-west-1` | [arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:27](#){: .copyMe}:clipboard: | - | `us-west-2` | [arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:27](#){: .copyMe}:clipboard: | + | `af-south-1` | [arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:28](#){: .copyMe}:clipboard: | + | `ap-east-1` | [arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:28](#){: .copyMe}:clipboard: | + | `ap-northeast-1` | [arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:28](#){: .copyMe}:clipboard: | + | `ap-northeast-2` | [arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:28](#){: .copyMe}:clipboard: | + | `ap-northeast-3` | [arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:28](#){: .copyMe}:clipboard: | + | `ap-south-1` | [arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:28](#){: .copyMe}:clipboard: | + | `ap-southeast-1` | [arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:28](#){: .copyMe}:clipboard: | + | `ap-southeast-2` | [arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:28](#){: .copyMe}:clipboard: | + | `ap-southeast-3` | [arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:28](#){: .copyMe}:clipboard: | + | `ca-central-1` | [arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:28](#){: .copyMe}:clipboard: | + | `eu-central-1` | [arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:28](#){: .copyMe}:clipboard: | + | `eu-north-1` | [arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:28](#){: .copyMe}:clipboard: | + | `eu-south-1` | [arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:28](#){: .copyMe}:clipboard: | + | `eu-west-1` | [arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:28](#){: .copyMe}:clipboard: | + | `eu-west-2` | [arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:28](#){: .copyMe}:clipboard: | + | `eu-west-3` | [arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:28](#){: .copyMe}:clipboard: | + | `me-south-1` | [arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:28](#){: .copyMe}:clipboard: | + | `sa-east-1` | [arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:28](#){: .copyMe}:clipboard: | + | `us-east-1` | [arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:28](#){: .copyMe}:clipboard: | + | `us-east-2` | [arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:28](#){: .copyMe}:clipboard: | + | `us-west-1` | [arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:28](#){: .copyMe}:clipboard: | + | `us-west-2` | [arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:28](#){: .copyMe}:clipboard: | ??? note "Note: Click to expand and copy code snippets for popular frameworks" @@ -139,7 +139,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. Type: AWS::Serverless::Function Properties: Layers: - - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:27 + - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:28 ``` === "Serverless framework" @@ -149,7 +149,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. hello: handler: lambda_function.lambda_handler layers: - - arn:aws:lambda:${aws:region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:27 + - arn:aws:lambda:${aws:region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:28 ``` === "CDK" @@ -165,7 +165,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. powertools_layer = aws_lambda.LayerVersion.from_layer_version_arn( self, id="lambda-powertools", - layer_version_arn=f"arn:aws:lambda:{env.region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:27" + layer_version_arn=f"arn:aws:lambda:{env.region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:28" ) aws_lambda.Function(self, 'sample-app-lambda', @@ -214,7 +214,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. role = aws_iam_role.iam_for_lambda.arn handler = "index.test" runtime = "python3.9" - layers = ["arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:27"] + layers = ["arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:28"] source_code_hash = filebase64sha256("lambda_function_payload.zip") } @@ -267,7 +267,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. ? Do you want to configure advanced settings? Yes ... ? Do you want to enable Lambda layers for this function? Yes - ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:27 + ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28 ❯ amplify push -y @@ -278,7 +278,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. - Name: ? Which setting do you want to update? Lambda layers configuration ? Do you want to enable Lambda layers for this function? Yes - ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:27 + ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28 ? Do you want to edit the local lambda function now? No ``` @@ -292,7 +292,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. Properties: Architectures: [arm64] Layers: - - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:27 + - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:28 ``` === "Serverless framework" @@ -303,7 +303,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. handler: lambda_function.lambda_handler architecture: arm64 layers: - - arn:aws:lambda:${aws:region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:27 + - arn:aws:lambda:${aws:region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:28 ``` === "CDK" @@ -319,7 +319,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. powertools_layer = aws_lambda.LayerVersion.from_layer_version_arn( self, id="lambda-powertools", - layer_version_arn=f"arn:aws:lambda:{env.region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:27" + layer_version_arn=f"arn:aws:lambda:{env.region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:28" ) aws_lambda.Function(self, 'sample-app-lambda', @@ -369,7 +369,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. role = aws_iam_role.iam_for_lambda.arn handler = "index.test" runtime = "python3.9" - layers = ["arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:27"] + layers = ["arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:28"] architectures = ["arm64"] source_code_hash = filebase64sha256("lambda_function_payload.zip") @@ -425,7 +425,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. ? Do you want to configure advanced settings? Yes ... ? Do you want to enable Lambda layers for this function? Yes - ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:27 + ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:28 ❯ amplify push -y @@ -436,7 +436,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. - Name: ? Which setting do you want to update? Lambda layers configuration ? Do you want to enable Lambda layers for this function? Yes - ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:27 + ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:28 ? Do you want to edit the local lambda function now? No ``` @@ -444,7 +444,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. Change {region} to your AWS region, e.g. `eu-west-1` ```bash title="AWS CLI" - aws lambda get-layer-version-by-arn --arn arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:27 --region {region} + aws lambda get-layer-version-by-arn --arn arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:28 --region {region} ``` The pre-signed URL to download this Lambda Layer will be within `Location` key. From 7501dbf518c742647b9f229f71efaf3ee8a67ec8 Mon Sep 17 00:00:00 2001 From: Ruben Fonseca Date: Fri, 14 Apr 2023 15:32:54 +0200 Subject: [PATCH 026/100] chore(layer): change layer-balance script to support new regions --- layer/scripts/layer-balancer/go.mod | 1 + layer/scripts/layer-balancer/go.sum | 2 + layer/scripts/layer-balancer/main.go | 80 ++++++++++++++++++++-------- 3 files changed, 62 insertions(+), 21 deletions(-) diff --git a/layer/scripts/layer-balancer/go.mod b/layer/scripts/layer-balancer/go.mod index 219d4d46736..fba6faafc2f 100644 --- a/layer/scripts/layer-balancer/go.mod +++ b/layer/scripts/layer-balancer/go.mod @@ -21,4 +21,5 @@ require ( github.com/aws/aws-sdk-go-v2/service/sts v1.16.19 // indirect github.com/aws/smithy-go v1.13.3 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect + golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // indirect ) diff --git a/layer/scripts/layer-balancer/go.sum b/layer/scripts/layer-balancer/go.sum index 9bcb7428e79..a23150519d8 100644 --- a/layer/scripts/layer-balancer/go.sum +++ b/layer/scripts/layer-balancer/go.sum @@ -31,6 +31,8 @@ github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHW github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug= +golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/layer/scripts/layer-balancer/main.go b/layer/scripts/layer-balancer/main.go index 889675e5f71..cf2f0c1728e 100644 --- a/layer/scripts/layer-balancer/main.go +++ b/layer/scripts/layer-balancer/main.go @@ -15,6 +15,7 @@ import ( "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/service/lambda" "github.com/aws/aws-sdk-go-v2/service/lambda/types" + "golang.org/x/exp/slices" "golang.org/x/sync/errgroup" ) @@ -44,27 +45,40 @@ var canonicalLayers = []LayerInfo{ // regions are the regions that we want to keep in sync var regions = []string{ "af-south-1", - "eu-central-1", - "us-east-1", - "us-east-2", - "us-west-1", - "us-west-2", "ap-east-1", - "ap-south-1", "ap-northeast-1", "ap-northeast-2", + "ap-northeast-3", + "ap-south-1", + "ap-south-2", "ap-southeast-1", "ap-southeast-2", + "ap-southeast-3", + "ap-southeast-4", "ca-central-1", + "eu-central-1", + "eu-central-2", + "eu-north-1", + "eu-south-1", + "eu-south-2", "eu-west-1", "eu-west-2", "eu-west-3", - "eu-south-1", - "eu-north-1", - "sa-east-1", - "ap-southeast-3", - "ap-northeast-3", + "me-central-1", "me-south-1", + "sa-east-1", + "us-east-1", + "us-east-2", + "us-west-1", + "us-west-2", +} + +var singleArchitectureRegions = []string{ + "ap-south-2", + "ap-southeast-4", + "eu-central-2", + "eu-south-2", + "me-central-1", } // getLayerVersion returns the latest version of a layer in a region @@ -100,6 +114,11 @@ func getGreatestVersion(ctx context.Context) (int64, error) { layer := &canonicalLayers[idx] for _, region := range regions { + // Ignore regions that are excluded + if layer.Architecture == types.ArchitectureArm64 && slices.Contains(singleArchitectureRegions, region) { + continue + } + layerName := layer.Name ctx := ctx region := region @@ -149,16 +168,30 @@ func balanceRegionToVersion(ctx context.Context, region string, layer *LayerInfo return fmt.Errorf("error downloading canonical zip: %w", err) } - layerVersionResponse, err := lambdaSvc.PublishLayerVersion(ctx, &lambda.PublishLayerVersionInput{ - Content: &types.LayerVersionContentInput{ - ZipFile: payload, - }, - LayerName: aws.String(layer.Name), - CompatibleArchitectures: []types.Architecture{layer.Architecture}, - CompatibleRuntimes: []types.Runtime{types.RuntimePython37, types.RuntimePython38, types.RuntimePython39}, - Description: aws.String(layer.Description), - LicenseInfo: aws.String("MIT-0"), - }) + var layerVersionResponse *lambda.PublishLayerVersionOutput + + if slices.Contains(singleArchitectureRegions, region) { + layerVersionResponse, err = lambdaSvc.PublishLayerVersion(ctx, &lambda.PublishLayerVersionInput{ + Content: &types.LayerVersionContentInput{ + ZipFile: payload, + }, + LayerName: aws.String(layer.Name), + CompatibleRuntimes: []types.Runtime{types.RuntimePython37, types.RuntimePython38, types.RuntimePython39}, + Description: aws.String(layer.Description), + LicenseInfo: aws.String("MIT-0"), + }) + } else { + layerVersionResponse, err = lambdaSvc.PublishLayerVersion(ctx, &lambda.PublishLayerVersionInput{ + Content: &types.LayerVersionContentInput{ + ZipFile: payload, + }, + LayerName: aws.String(layer.Name), + CompatibleArchitectures: []types.Architecture{layer.Architecture}, + CompatibleRuntimes: []types.Runtime{types.RuntimePython37, types.RuntimePython38, types.RuntimePython39}, + Description: aws.String(layer.Description), + LicenseInfo: aws.String("MIT-0"), + }) + } if err != nil { return fmt.Errorf("error publishing layer version: %w", err) } @@ -186,6 +219,11 @@ func balanceRegions(ctx context.Context, maxVersion int64) error { layer := &canonicalLayers[idx] for _, region := range regions { + // Ignore regions that are excluded + if layer.Architecture == types.ArchitectureArm64 && slices.Contains(singleArchitectureRegions, region) { + continue + } + ctx := ctx region := region layer := layer From ef3ebe20da2ef9cb64ee677a3ef839a919064b03 Mon Sep 17 00:00:00 2001 From: Ruben Fonseca Date: Fri, 14 Apr 2023 15:36:24 +0200 Subject: [PATCH 027/100] fix(docs): add Layer ARN for new 5 regions --- docs/index.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/index.md b/docs/index.md index d44c1dc40f2..6b0db547dea 100644 --- a/docs/index.md +++ b/docs/index.md @@ -84,16 +84,21 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. | `ap-northeast-2` | [arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | | `ap-northeast-3` | [arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | | `ap-south-1` | [arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | + | `ap-south-2` | [arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | | `ap-southeast-1` | [arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | | `ap-southeast-2` | [arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | | `ap-southeast-3` | [arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | + | `ap-southeast-4` | [arn:aws:lambda:ap-southeast-4:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | | `ca-central-1` | [arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | | `eu-central-1` | [arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | + | `eu-central-2` | [arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | | `eu-north-1` | [arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | | `eu-south-1` | [arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | + | `eu-south-2` | [arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | | `eu-west-1` | [arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | | `eu-west-2` | [arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | | `eu-west-3` | [arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | + | `me-central-1` | [arn:aws:lambda:me-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | | `me-south-1` | [arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | | `sa-east-1` | [arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | | `us-east-1` | [arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | From 5e77874dfb25f330a5f4b58ab6928ad93362ad08 Mon Sep 17 00:00:00 2001 From: Release bot Date: Fri, 14 Apr 2023 13:37:05 +0000 Subject: [PATCH 028/100] update changelog with latest changes --- CHANGELOG.md | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 34dd6ce6ec2..45f98298f3b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,21 @@ ## Bug Fixes +* **ci:** typo +* **docs:** add Layer ARN for new 5 regions + +## Maintenance + +* update v2 layer ARN on documentation +* **ci:** add support for x86-64 regions only ([#2122](https://github.com/awslabs/aws-lambda-powertools-python/issues/2122)) +* **layer:** change layer-balance script to support new regions + + + +## [v2.13.0] - 2023-04-14 +## Bug Fixes + +* **ci:** replace the correct files for Layer ARN * **ci:** fix working directory * **ci:** add debug log to NPM install * **ci:** use project's CDK version when building layers @@ -19,13 +34,14 @@ ## Maintenance +* update v2 layer ARN on documentation * **ci:** bump the cdk-aws-lambda-powertools-layer version ([#2121](https://github.com/awslabs/aws-lambda-powertools-python/issues/2121)) * **deps:** bump codecov/codecov-action from 3.1.1 to 3.1.2 ([#2110](https://github.com/awslabs/aws-lambda-powertools-python/issues/2110)) -* **deps-dev:** bump flake8-comprehensions from 3.11.1 to 3.12.0 ([#2124](https://github.com/awslabs/aws-lambda-powertools-python/issues/2124)) +* **deps-dev:** bump httpx from 0.23.3 to 0.24.0 ([#2111](https://github.com/awslabs/aws-lambda-powertools-python/issues/2111)) * **deps-dev:** bump aws-cdk-lib from 2.73.0 to 2.74.0 ([#2123](https://github.com/awslabs/aws-lambda-powertools-python/issues/2123)) * **deps-dev:** bump mkdocs-material from 9.1.5 to 9.1.6 ([#2104](https://github.com/awslabs/aws-lambda-powertools-python/issues/2104)) * **deps-dev:** bump aws-cdk from 2.73.0 to 2.74.0 ([#2125](https://github.com/awslabs/aws-lambda-powertools-python/issues/2125)) -* **deps-dev:** bump httpx from 0.23.3 to 0.24.0 ([#2111](https://github.com/awslabs/aws-lambda-powertools-python/issues/2111)) +* **deps-dev:** bump flake8-comprehensions from 3.11.1 to 3.12.0 ([#2124](https://github.com/awslabs/aws-lambda-powertools-python/issues/2124)) * **deps-dev:** bump mypy from 1.1.1 to 1.2.0 ([#2096](https://github.com/awslabs/aws-lambda-powertools-python/issues/2096)) * **deps-dev:** bump cfn-lint from 0.76.2 to 0.77.0 ([#2107](https://github.com/awslabs/aws-lambda-powertools-python/issues/2107)) * **deps-dev:** bump pytest from 7.2.2 to 7.3.0 ([#2106](https://github.com/awslabs/aws-lambda-powertools-python/issues/2106)) @@ -3098,7 +3114,8 @@ * Merge pull request [#5](https://github.com/awslabs/aws-lambda-powertools-python/issues/5) from jfuss/feat/python38 -[Unreleased]: https://github.com/awslabs/aws-lambda-powertools-python/compare/v2.12.0...HEAD +[Unreleased]: https://github.com/awslabs/aws-lambda-powertools-python/compare/v2.13.0...HEAD +[v2.13.0]: https://github.com/awslabs/aws-lambda-powertools-python/compare/v2.12.0...v2.13.0 [v2.12.0]: https://github.com/awslabs/aws-lambda-powertools-python/compare/v2.11.0...v2.12.0 [v2.11.0]: https://github.com/awslabs/aws-lambda-powertools-python/compare/v2.10.0...v2.11.0 [v2.10.0]: https://github.com/awslabs/aws-lambda-powertools-python/compare/v2.9.1...v2.10.0 From 0f1c776e7cefe5cea29c8864deeed2c9597d01a4 Mon Sep 17 00:00:00 2001 From: Ruben Fonseca Date: Fri, 14 Apr 2023 15:48:11 +0200 Subject: [PATCH 029/100] fix(layers): add debug to update layer arn script --- layer/scripts/update_layer_arn.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/layer/scripts/update_layer_arn.sh b/layer/scripts/update_layer_arn.sh index 55734941839..0ad3e1617fe 100755 --- a/layer/scripts/update_layer_arn.sh +++ b/layer/scripts/update_layer_arn.sh @@ -7,6 +7,7 @@ # see .github/workflows/reusable_deploy_v2_layer_stack.yml set -eo pipefail +set -x if [[ $# -ne 1 ]]; then cat < Date: Fri, 14 Apr 2023 13:59:39 +0000 Subject: [PATCH 030/100] chore: update v2 layer ARN on documentation --- docs/index.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/index.md b/docs/index.md index 6b0db547dea..829a1e74618 100644 --- a/docs/index.md +++ b/docs/index.md @@ -84,21 +84,21 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. | `ap-northeast-2` | [arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | | `ap-northeast-3` | [arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | | `ap-south-1` | [arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | - | `ap-south-2` | [arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | + | `ap-south-2` | [arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:1](#){: .copyMe}:clipboard: | | `ap-southeast-1` | [arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | | `ap-southeast-2` | [arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | | `ap-southeast-3` | [arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | - | `ap-southeast-4` | [arn:aws:lambda:ap-southeast-4:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | + | `ap-southeast-4` | [arn:aws:lambda:ap-southeast-4:017000801446:layer:AWSLambdaPowertoolsPythonV2:1](#){: .copyMe}:clipboard: | | `ca-central-1` | [arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | | `eu-central-1` | [arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | - | `eu-central-2` | [arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | + | `eu-central-2` | [arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:1](#){: .copyMe}:clipboard: | | `eu-north-1` | [arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | | `eu-south-1` | [arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | - | `eu-south-2` | [arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | + | `eu-south-2` | [arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:1](#){: .copyMe}:clipboard: | | `eu-west-1` | [arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | | `eu-west-2` | [arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | | `eu-west-3` | [arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | - | `me-central-1` | [arn:aws:lambda:me-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | + | `me-central-1` | [arn:aws:lambda:me-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:1](#){: .copyMe}:clipboard: | | `me-south-1` | [arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | | `sa-east-1` | [arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | | `us-east-1` | [arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | From fbcd029c5c691dc6a3dbc233a2fb1635fcdaa587 Mon Sep 17 00:00:00 2001 From: Ruben Fonseca Date: Fri, 14 Apr 2023 16:06:35 +0200 Subject: [PATCH 031/100] fix(ci): fix layer version in tracer, logger and metrics --- examples/logger/sam/template.yaml | 2 +- examples/metrics/sam/template.yaml | 2 +- examples/tracer/sam/template.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/logger/sam/template.yaml b/examples/logger/sam/template.yaml index 3f702bfc041..3fdf5f2742d 100644 --- a/examples/logger/sam/template.yaml +++ b/examples/logger/sam/template.yaml @@ -14,7 +14,7 @@ Globals: Layers: # Find the latest Layer version in the official documentation # https://awslabs.github.io/aws-lambda-powertools-python/latest/#lambda-layer - - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPython:21 + - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:28 Resources: LoggerLambdaHandlerExample: diff --git a/examples/metrics/sam/template.yaml b/examples/metrics/sam/template.yaml index 154dacdfd9b..532de6cb335 100644 --- a/examples/metrics/sam/template.yaml +++ b/examples/metrics/sam/template.yaml @@ -15,7 +15,7 @@ Globals: Layers: # Find the latest Layer version in the official documentation # https://awslabs.github.io/aws-lambda-powertools-python/latest/#lambda-layer - - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPython:21 + - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:28 Resources: CaptureLambdaHandlerExample: diff --git a/examples/tracer/sam/template.yaml b/examples/tracer/sam/template.yaml index bda46d308b3..1b3f5d65338 100644 --- a/examples/tracer/sam/template.yaml +++ b/examples/tracer/sam/template.yaml @@ -13,7 +13,7 @@ Globals: Layers: # Find the latest Layer version in the official documentation # https://awslabs.github.io/aws-lambda-powertools-python/latest/#lambda-layer - - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPython:21 + - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:28 Resources: CaptureLambdaHandlerExample: From 86814a4cc8403fb2be454d2d7d6d1225376f084f Mon Sep 17 00:00:00 2001 From: Ruben Fonseca Date: Fri, 14 Apr 2023 16:07:11 +0200 Subject: [PATCH 032/100] Revert "chore: update v2 layer ARN on documentation" This reverts commit 3d9b9a975014b2f7a3033d41d1bf39a26cb750e6. --- docs/index.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/index.md b/docs/index.md index 829a1e74618..6b0db547dea 100644 --- a/docs/index.md +++ b/docs/index.md @@ -84,21 +84,21 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. | `ap-northeast-2` | [arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | | `ap-northeast-3` | [arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | | `ap-south-1` | [arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | - | `ap-south-2` | [arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:1](#){: .copyMe}:clipboard: | + | `ap-south-2` | [arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | | `ap-southeast-1` | [arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | | `ap-southeast-2` | [arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | | `ap-southeast-3` | [arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | - | `ap-southeast-4` | [arn:aws:lambda:ap-southeast-4:017000801446:layer:AWSLambdaPowertoolsPythonV2:1](#){: .copyMe}:clipboard: | + | `ap-southeast-4` | [arn:aws:lambda:ap-southeast-4:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | | `ca-central-1` | [arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | | `eu-central-1` | [arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | - | `eu-central-2` | [arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:1](#){: .copyMe}:clipboard: | + | `eu-central-2` | [arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | | `eu-north-1` | [arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | | `eu-south-1` | [arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | - | `eu-south-2` | [arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:1](#){: .copyMe}:clipboard: | + | `eu-south-2` | [arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | | `eu-west-1` | [arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | | `eu-west-2` | [arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | | `eu-west-3` | [arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | - | `me-central-1` | [arn:aws:lambda:me-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:1](#){: .copyMe}:clipboard: | + | `me-central-1` | [arn:aws:lambda:me-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | | `me-south-1` | [arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | | `sa-east-1` | [arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | | `us-east-1` | [arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | From eec569d5cfae2400e6b657b8d7fcb4d63714bcac Mon Sep 17 00:00:00 2001 From: Release bot Date: Fri, 14 Apr 2023 14:07:26 +0000 Subject: [PATCH 033/100] update changelog with latest changes --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 45f98298f3b..06d4813c17c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,11 +6,14 @@ ## Bug Fixes +* **ci:** fix layer version in tracer, logger and metrics * **ci:** typo * **docs:** add Layer ARN for new 5 regions +* **layers:** add debug to update layer arn script ## Maintenance +* update v2 layer ARN on documentation * update v2 layer ARN on documentation * **ci:** add support for x86-64 regions only ([#2122](https://github.com/awslabs/aws-lambda-powertools-python/issues/2122)) * **layer:** change layer-balance script to support new regions From 80b7d4e5e771aee79ef9c150f8d6b2493e360d02 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 14 Apr 2023 20:59:49 +0000 Subject: [PATCH 034/100] chore(deps-dev): bump mypy-boto3-lambda from 1.26.109 to 1.26.114 (#2126) Bumps [mypy-boto3-lambda](https://github.com/youtype/mypy_boto3_builder) from 1.26.109 to 1.26.114. - [Release notes](https://github.com/youtype/mypy_boto3_builder/releases) - [Commits](https://github.com/youtype/mypy_boto3_builder/commits) --- updated-dependencies: - dependency-name: mypy-boto3-lambda dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 10 +++++----- pyproject.toml | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/poetry.lock b/poetry.lock index 399a8671da5..04b411ac679 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1750,14 +1750,14 @@ typing-extensions = {version = ">=4.1.0", markers = "python_version < \"3.9\""} [[package]] name = "mypy-boto3-lambda" -version = "1.26.109" -description = "Type annotations for boto3.Lambda 1.26.109 service generated with mypy-boto3-builder 7.14.5" +version = "1.26.114" +description = "Type annotations for boto3.Lambda 1.26.114 service generated with mypy-boto3-builder 7.14.5" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "mypy-boto3-lambda-1.26.109.tar.gz", hash = "sha256:40c7773c33fca2bec4bb9ed7edb0506887e30247eb9b2da60d277214b1b020cb"}, - {file = "mypy_boto3_lambda-1.26.109-py3-none-any.whl", hash = "sha256:caa7eff782ff2fae3cab36721a75331c988b741d1b4152ee6cd0dcf9e1a60f38"}, + {file = "mypy-boto3-lambda-1.26.114.tar.gz", hash = "sha256:72ae6723717cf552e579e9e76380063f470f957481a64848a353fd7c568ef17d"}, + {file = "mypy_boto3_lambda-1.26.114-py3-none-any.whl", hash = "sha256:e6d10436b49331e0b4e78efd27354b832a3fee5936a154a85fd9733e0cd80e71"}, ] [package.dependencies] @@ -3035,4 +3035,4 @@ validation = ["fastjsonschema"] [metadata] lock-version = "2.0" python-versions = "^3.7.4" -content-hash = "02fa7bb284f7d689059624f5a30f9600f87e8c9c3929243f9a3db38b45386c7e" +content-hash = "6d47edb47d4ae1871df308d1548d994115c3efff60bc287a33e74ad81a758d89" diff --git a/pyproject.toml b/pyproject.toml index 61a5246e4b2..aaddf5db8ea 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -73,7 +73,7 @@ mypy-boto3-appconfig = "^1.26.71" mypy-boto3-cloudformation = "^1.26.108" mypy-boto3-cloudwatch = "^1.26.99" mypy-boto3-dynamodb = "^1.26.97" -mypy-boto3-lambda = "^1.26.109" +mypy-boto3-lambda = "^1.26.114" mypy-boto3-logs = "^1.26.53" mypy-boto3-secretsmanager = "^1.26.89" mypy-boto3-ssm = "^1.26.97" From c624658c74fed2b4265c1d6fd30a158801b158f0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 15 Apr 2023 08:44:50 +0100 Subject: [PATCH 035/100] chore(deps-dev): bump pytest from 7.3.0 to 7.3.1 (#2127) --- poetry.lock | 8 ++++---- pyproject.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/poetry.lock b/poetry.lock index 04b411ac679..e8cba83ba25 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2189,14 +2189,14 @@ files = [ [[package]] name = "pytest" -version = "7.3.0" +version = "7.3.1" description = "pytest: simple powerful testing with Python" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "pytest-7.3.0-py3-none-any.whl", hash = "sha256:933051fa1bfbd38a21e73c3960cebdad4cf59483ddba7696c48509727e17f201"}, - {file = "pytest-7.3.0.tar.gz", hash = "sha256:58ecc27ebf0ea643ebfdf7fb1249335da761a00c9f955bcd922349bcb68ee57d"}, + {file = "pytest-7.3.1-py3-none-any.whl", hash = "sha256:3799fa815351fea3a5e96ac7e503a96fa51cc9942c3753cda7651b93c1cfa362"}, + {file = "pytest-7.3.1.tar.gz", hash = "sha256:434afafd78b1d78ed0addf160ad2b77a30d35d4bdf8af234fe621919d9ed15e3"}, ] [package.dependencies] @@ -3035,4 +3035,4 @@ validation = ["fastjsonschema"] [metadata] lock-version = "2.0" python-versions = "^3.7.4" -content-hash = "6d47edb47d4ae1871df308d1548d994115c3efff60bc287a33e74ad81a758d89" +content-hash = "57627c2fe353a2d9e85db34c609b9215821fbfa203f62d0521d5781f41682a35" diff --git a/pyproject.toml b/pyproject.toml index aaddf5db8ea..727e9dfc73a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -35,7 +35,7 @@ typing-extensions = "^4.4.0" [tool.poetry.dev-dependencies] coverage = {extras = ["toml"], version = "^7.2"} -pytest = "^7.3.0" +pytest = "^7.3.1" black = "^23.3" boto3 = "^1.18" flake8 = [ From 453c9320f03f5ce0880058e4576d6749a6602bf7 Mon Sep 17 00:00:00 2001 From: Release bot Date: Mon, 17 Apr 2023 08:00:15 +0000 Subject: [PATCH 036/100] update changelog with latest changes --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 06d4813c17c..05bab17d15f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,8 @@ * update v2 layer ARN on documentation * update v2 layer ARN on documentation * **ci:** add support for x86-64 regions only ([#2122](https://github.com/awslabs/aws-lambda-powertools-python/issues/2122)) +* **deps-dev:** bump pytest from 7.3.0 to 7.3.1 ([#2127](https://github.com/awslabs/aws-lambda-powertools-python/issues/2127)) +* **deps-dev:** bump mypy-boto3-lambda from 1.26.109 to 1.26.114 ([#2126](https://github.com/awslabs/aws-lambda-powertools-python/issues/2126)) * **layer:** change layer-balance script to support new regions From 671af87d18b163504db228ca2b38f94401946695 Mon Sep 17 00:00:00 2001 From: Heitor Lessa Date: Mon, 17 Apr 2023 16:24:12 +0200 Subject: [PATCH 037/100] chore(github): new tech debt issue form (#2131) * chore: add new tech debt template Signed-off-by: heitorlessa * chore: sync up maintenance template with tech debt template Signed-off-by: heitorlessa * docs: add tech-debt label in maintainers playbook --------- Signed-off-by: heitorlessa --- .github/ISSUE_TEMPLATE/maintenance.yml | 16 ++---- .github/ISSUE_TEMPLATE/tech_debt.yml | 62 ++++++++++++++++++++++ MAINTAINERS.md | 71 +++++++++++++------------- 3 files changed, 102 insertions(+), 47 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/tech_debt.yml diff --git a/.github/ISSUE_TEMPLATE/maintenance.yml b/.github/ISSUE_TEMPLATE/maintenance.yml index 2f60a0f013a..95473ac1c61 100644 --- a/.github/ISSUE_TEMPLATE/maintenance.yml +++ b/.github/ISSUE_TEMPLATE/maintenance.yml @@ -1,5 +1,5 @@ name: Maintenance -description: Suggest an activity to help address tech debt, governance, and anything internal +description: Suggest an activity to help address governance and anything internal title: "Maintenance: TITLE" labels: ["internal", "triage"] body: @@ -9,13 +9,6 @@ body: Thank you for taking the time to help us improve operational excellence. *Future readers*: Please react with 👍 and your use case to help us understand customer demand. - - type: textarea - id: activity - attributes: - label: Summary - description: Please provide an overview in one or two paragraphs - validations: - required: true - type: textarea id: importance attributes: @@ -29,8 +22,6 @@ body: label: Which area does this relate to? multiple: true options: - - Automation - - Governance - Tests - Static typing - Tracer @@ -41,13 +32,14 @@ body: - Middleware factory - Parameters - Batch processing - - Typing - Validation - Event Source Data Classes - Parser - Idempotency - Feature flags - JMESPath functions + - Streaming + - Automation - Other - type: textarea id: suggestion @@ -63,7 +55,7 @@ body: options: - label: This request meets [Lambda Powertools Tenets](https://awslabs.github.io/aws-lambda-powertools-python/latest/#tenets) required: true - - label: Should this be considered in other Lambda Powertools languages? i.e. [Java](https://github.com/awslabs/aws-lambda-powertools-java/), [TypeScript](https://github.com/awslabs/aws-lambda-powertools-typescript/) + - label: Should this be considered in other Lambda Powertools languages? i.e. [TypeScript](https://github.com/awslabs/aws-lambda-powertools-typescript/) required: false - type: markdown attributes: diff --git a/.github/ISSUE_TEMPLATE/tech_debt.yml b/.github/ISSUE_TEMPLATE/tech_debt.yml new file mode 100644 index 00000000000..84b5cffe189 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/tech_debt.yml @@ -0,0 +1,62 @@ +name: Technical debt +description: Suggest an activity to help address technical debt. +title: "Tech debt: TITLE" +labels: ["tech-debt", "triage"] +body: + - type: markdown + attributes: + value: Thank you for taking the time to help us proactively improve delivery velocity, safely. + - type: textarea + id: importance + attributes: + label: Why is this needed? + description: Please help us understand the value so we can prioritize it accordingly + validations: + required: true + - type: dropdown + id: area + attributes: + label: Which area does this relate to? + multiple: true + options: + - Tests + - Static typing + - Tracer + - Logger + - Metrics + - Event Handler - REST API + - Event Handler - GraphQL API + - Middleware factory + - Parameters + - Batch processing + - Validation + - Event Source Data Classes + - Parser + - Idempotency + - Feature flags + - JMESPath functions + - Streaming + - Automation + - Other + - type: textarea + id: suggestion + attributes: + label: Suggestion + description: If available, please share what a good solution would look like + validations: + required: false + - type: checkboxes + id: acknowledgment + attributes: + label: Acknowledgment + options: + - label: This request meets [Lambda Powertools Tenets](https://awslabs.github.io/aws-lambda-powertools-python/latest/#tenets) + required: true + - label: Should this be considered in other Lambda Powertools languages? i.e. [TypeScript](https://github.com/awslabs/aws-lambda-powertools-typescript/) + required: false + - type: markdown + attributes: + value: | + --- + + **Disclaimer**: We value your time and bandwidth. As such, any pull requests created on non-triaged issues might not be successful. diff --git a/MAINTAINERS.md b/MAINTAINERS.md index 90e41eb6345..a82c160a58d 100644 --- a/MAINTAINERS.md +++ b/MAINTAINERS.md @@ -69,41 +69,42 @@ Previous active maintainers who contributed to this project. These are the most common labels used by maintainers to triage issues, pull requests (PR), and for project management: -| Label | Usage | Notes | -| ---------------------- | --------------------------------------------------------------------------- | --------------------------------------------------------------- | -| triage | New issues that require maintainers review | Issue template | -| bug | Unexpected, reproducible and unintended software behavior | PR/Release automation; Doc snippets are excluded; | -| not-a-bug | New and existing bug reports incorrectly submitted as bug | Analytics | -| documentation | Documentation improvements | PR/Release automation; Doc additions, fixes, etc.; | -| feature-request | New or enhancements to existing features | Issue template | -| typing | New or enhancements to static typing | Issue template | -| RFC | Technical design documents related to a feature request | Issue template | -| bug-upstream | Bug caused by upstream dependency | | -| help wanted | Tasks you want help from anyone to move forward | Bandwidth, complex topics, etc. | -| need-customer-feedback | Tasks that need more feedback before proceeding | 80/20% rule, uncertain, etc. | -| need-more-information | Missing information before making any calls | | -| need-documentation | PR is missing or has incomplete documentation | | -| need-issue | PR is missing a related issue for tracking change | Needs to be automated | -| need-rfc | Feature request requires a RFC to improve discussion | | -| pending-release | Merged changes that will be available soon | Release automation auto-closes/notifies it | -| revisit-in-3-months | Blocked issues/PRs that need to be revisited | Often related to `need-customer-feedback`, prioritization, etc. | -| breaking-change | Changes that will cause customer impact and need careful triage | | -| do-not-merge | PRs that are blocked for varying reasons | Timeline is uncertain | -| size/XS | PRs between 0-9 LOC | PR automation | -| size/S | PRs between 10-29 LOC | PR automation | -| size/M | PRs between 30-99 LOC | PR automation | -| size/L | PRs between 100-499 LOC | PR automation | -| size/XL | PRs between 500-999 LOC, often PRs that grown with feedback | PR automation | -| size/XXL | PRs with 1K+ LOC, largely documentation related | PR automation | -| tests | PRs that add or change tests | PR automation | -| `` | PRs related to a Powertools utility, e.g. `parameters`, `tracer` | PR automation | -| feature | New features or minor changes | PR/Release automation | -| dependencies | Changes that touch dependencies, e.g. Dependabot, etc. | PR/ automation | -| github-actions | Changes in GitHub workflows | PR automation | -| github-templates | Changes in GitHub issue/PR templates | PR automation | -| internal | Changes in governance, tech debt and chores (linting setup, baseline, etc.) | PR automation | -| customer-reference | Authorization to use company name in our documentation | Public Relations | -| community-content | Suggested content to feature in our documentation | Public Relations | +| Label | Usage | Notes | +| ---------------------- | ---------------------------------------------------------------- | --------------------------------------------------------------- | +| triage | New issues that require maintainers review | Issue template | +| bug | Unexpected, reproducible and unintended software behavior | PR/Release automation; Doc snippets are excluded; | +| not-a-bug | New and existing bug reports incorrectly submitted as bug | Analytics | +| documentation | Documentation improvements | PR/Release automation; Doc additions, fixes, etc.; | +| feature-request | New or enhancements to existing features | Issue template | +| typing | New or enhancements to static typing | Issue template | +| RFC | Technical design documents related to a feature request | Issue template | +| bug-upstream | Bug caused by upstream dependency | | +| help wanted | Tasks you want help from anyone to move forward | Bandwidth, complex topics, etc. | +| need-customer-feedback | Tasks that need more feedback before proceeding | 80/20% rule, uncertain, etc. | +| need-more-information | Missing information before making any calls | | +| need-documentation | PR is missing or has incomplete documentation | | +| need-issue | PR is missing a related issue for tracking change | PR automation | +| need-rfc | Feature request requires a RFC to improve discussion | | +| pending-release | Merged changes that will be available soon | Release automation auto-closes/notifies it | +| revisit-in-3-months | Blocked issues/PRs that need to be revisited | Often related to `need-customer-feedback`, prioritization, etc. | +| breaking-change | Changes that will cause customer impact and need careful triage | | +| do-not-merge | PRs that are blocked for varying reasons | Timeline is uncertain | +| size/XS | PRs between 0-9 LOC | PR automation | +| size/S | PRs between 10-29 LOC | PR automation | +| size/M | PRs between 30-99 LOC | PR automation | +| size/L | PRs between 100-499 LOC | PR automation | +| size/XL | PRs between 500-999 LOC, often PRs that grown with feedback | PR automation | +| size/XXL | PRs with 1K+ LOC, largely documentation related | PR automation | +| tests | PRs that add or change tests | PR automation | +| `` | PRs related to a Powertools utility, e.g. `parameters`, `tracer` | PR automation | +| feature | New features or minor changes | PR/Release automation | +| dependencies | Changes that touch dependencies, e.g. Dependabot, etc. | PR/ automation | +| github-actions | Changes in GitHub workflows | PR automation | +| github-templates | Changes in GitHub issue/PR templates | PR automation | +| internal | Changes in governance and chores (linting setup, baseline, etc.) | PR automation | +| tech-debt | Changes in tech debt | | +| customer-reference | Authorization to use company name in our documentation | Public Relations | +| community-content | Suggested content to feature in our documentation | Public Relations | ## Maintainer Responsibilities From 58617abfde3aea44cfd214785ce48d2e1dadcada Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Apr 2023 21:02:16 +0000 Subject: [PATCH 038/100] chore(deps-dev): bump mypy-boto3-dynamodb from 1.26.97.post1 to 1.26.115 (#2132) Bumps [mypy-boto3-dynamodb](https://github.com/youtype/mypy_boto3_builder) from 1.26.97.post1 to 1.26.115. - [Release notes](https://github.com/youtype/mypy_boto3_builder/releases) - [Commits](https://github.com/youtype/mypy_boto3_builder/commits) --- updated-dependencies: - dependency-name: mypy-boto3-dynamodb dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 10 +++++----- pyproject.toml | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/poetry.lock b/poetry.lock index e8cba83ba25..3fbcec685ea 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1735,14 +1735,14 @@ typing-extensions = {version = ">=4.1.0", markers = "python_version < \"3.9\""} [[package]] name = "mypy-boto3-dynamodb" -version = "1.26.97.post1" -description = "Type annotations for boto3.DynamoDB 1.26.97 service generated with mypy-boto3-builder 7.14.1" +version = "1.26.115" +description = "Type annotations for boto3.DynamoDB 1.26.115 service generated with mypy-boto3-builder 7.14.5" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "mypy-boto3-dynamodb-1.26.97.post1.tar.gz", hash = "sha256:d7a53eda6b185737ad7718d3b46fd0cb0b4cf1b854c0b259754cd9060baef7d2"}, - {file = "mypy_boto3_dynamodb-1.26.97.post1-py3-none-any.whl", hash = "sha256:291700151a786e5ecb7274a9f7dbfda326419bab990b88e6299f4b8ee62473f6"}, + {file = "mypy-boto3-dynamodb-1.26.115.tar.gz", hash = "sha256:b94d69617d118421d625120d38b81772ef3aa2ba2d98e771008f9c72388f60f1"}, + {file = "mypy_boto3_dynamodb-1.26.115-py3-none-any.whl", hash = "sha256:280d4b71b716e221887cfbd8aeb27699efb2ed5f5ac98621878dbe99492dcd8c"}, ] [package.dependencies] @@ -3035,4 +3035,4 @@ validation = ["fastjsonschema"] [metadata] lock-version = "2.0" python-versions = "^3.7.4" -content-hash = "57627c2fe353a2d9e85db34c609b9215821fbfa203f62d0521d5781f41682a35" +content-hash = "54a605ed5e060e23c900dff54366b4d1f7062989c2198ae40d51ec4878b11cee" diff --git a/pyproject.toml b/pyproject.toml index 727e9dfc73a..7ce46ec7b10 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -72,7 +72,7 @@ python-snappy = "^0.6.1" mypy-boto3-appconfig = "^1.26.71" mypy-boto3-cloudformation = "^1.26.108" mypy-boto3-cloudwatch = "^1.26.99" -mypy-boto3-dynamodb = "^1.26.97" +mypy-boto3-dynamodb = "^1.26.115" mypy-boto3-lambda = "^1.26.114" mypy-boto3-logs = "^1.26.53" mypy-boto3-secretsmanager = "^1.26.89" From bf0bae24b9da7f87f3e5634142a847e09631823d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 18 Apr 2023 06:06:28 +0000 Subject: [PATCH 039/100] chore(deps-dev): bump cfn-lint from 0.77.0 to 0.77.1 (#2133) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 8 ++++---- pyproject.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/poetry.lock b/poetry.lock index 3fbcec685ea..6aba07546cc 100644 --- a/poetry.lock +++ b/poetry.lock @@ -370,14 +370,14 @@ files = [ [[package]] name = "cfn-lint" -version = "0.77.0" +version = "0.77.1" description = "Checks CloudFormation templates for practices and behaviour that could potentially be improved" category = "dev" optional = false python-versions = ">=3.7, <=4.0, !=4.0" files = [ - {file = "cfn-lint-0.77.0.tar.gz", hash = "sha256:a1cf0499a0a17028431d2728cb41fe196e7d4365984a4a42002774ff5c1706c6"}, - {file = "cfn_lint-0.77.0-py3-none-any.whl", hash = "sha256:a85b70a6ee281c1aac473aee9da0e0f8ff104e66f1669d684caddf3df8ce5cb7"}, + {file = "cfn-lint-0.77.1.tar.gz", hash = "sha256:f2861748ef8ba4bcb9f47bd12ea396f11b0f29ff50ca98fec39de52695544b61"}, + {file = "cfn_lint-0.77.1-py3-none-any.whl", hash = "sha256:19ae30984d3538c14439b39f9488fa0d4ea5d15d2398e011209ae97300228652"}, ] [package.dependencies] @@ -3035,4 +3035,4 @@ validation = ["fastjsonschema"] [metadata] lock-version = "2.0" python-versions = "^3.7.4" -content-hash = "54a605ed5e060e23c900dff54366b4d1f7062989c2198ae40d51ec4878b11cee" +content-hash = "609f93966055a3a2723f018ca7022221dee66718a98f6844364522db649902e5" diff --git a/pyproject.toml b/pyproject.toml index 7ce46ec7b10..e37b9b89b82 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -100,7 +100,7 @@ all = ["pydantic", "aws-xray-sdk", "fastjsonschema"] aws-sdk = ["boto3"] [tool.poetry.group.dev.dependencies] -cfn-lint = "0.77.0" +cfn-lint = "0.77.1" mypy = "^1.1.1" types-python-dateutil = "^2.8.19.6" httpx = ">=0.23.3,<0.25.0" From 9a9a5033a584ae22e5d1531b34740db4c1b50589 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 18 Apr 2023 06:10:03 +0000 Subject: [PATCH 040/100] chore(deps-dev): bump mypy-boto3-lambda from 1.26.114 to 1.26.115 (#2135) Bumps [mypy-boto3-lambda](https://github.com/youtype/mypy_boto3_builder) from 1.26.114 to 1.26.115. - [Release notes](https://github.com/youtype/mypy_boto3_builder/releases) - [Commits](https://github.com/youtype/mypy_boto3_builder/commits) --- updated-dependencies: - dependency-name: mypy-boto3-lambda dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 10 +++++----- pyproject.toml | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/poetry.lock b/poetry.lock index 6aba07546cc..fa2ba28fb57 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1750,14 +1750,14 @@ typing-extensions = {version = ">=4.1.0", markers = "python_version < \"3.9\""} [[package]] name = "mypy-boto3-lambda" -version = "1.26.114" -description = "Type annotations for boto3.Lambda 1.26.114 service generated with mypy-boto3-builder 7.14.5" +version = "1.26.115" +description = "Type annotations for boto3.Lambda 1.26.115 service generated with mypy-boto3-builder 7.14.5" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "mypy-boto3-lambda-1.26.114.tar.gz", hash = "sha256:72ae6723717cf552e579e9e76380063f470f957481a64848a353fd7c568ef17d"}, - {file = "mypy_boto3_lambda-1.26.114-py3-none-any.whl", hash = "sha256:e6d10436b49331e0b4e78efd27354b832a3fee5936a154a85fd9733e0cd80e71"}, + {file = "mypy-boto3-lambda-1.26.115.tar.gz", hash = "sha256:f612eca8f0e418e66d577b5609f0119c4934a7637ce1342d3c1cfc0d065cd42d"}, + {file = "mypy_boto3_lambda-1.26.115-py3-none-any.whl", hash = "sha256:0d418bb0d6c16c6a83e159dae71f8c6dff663c50dab125bb1518bf6c29f2ed83"}, ] [package.dependencies] @@ -3035,4 +3035,4 @@ validation = ["fastjsonschema"] [metadata] lock-version = "2.0" python-versions = "^3.7.4" -content-hash = "609f93966055a3a2723f018ca7022221dee66718a98f6844364522db649902e5" +content-hash = "9178cee32b9c766077ce20b83e5ae08a0b7e5f3a2cd4752f21727c5da6d67cef" diff --git a/pyproject.toml b/pyproject.toml index e37b9b89b82..7b8d1984f45 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -73,7 +73,7 @@ mypy-boto3-appconfig = "^1.26.71" mypy-boto3-cloudformation = "^1.26.108" mypy-boto3-cloudwatch = "^1.26.99" mypy-boto3-dynamodb = "^1.26.115" -mypy-boto3-lambda = "^1.26.114" +mypy-boto3-lambda = "^1.26.115" mypy-boto3-logs = "^1.26.53" mypy-boto3-secretsmanager = "^1.26.89" mypy-boto3-ssm = "^1.26.97" From 365aa7c5c3f52894e3f675d05eb61197e08f086f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 18 Apr 2023 06:12:43 +0000 Subject: [PATCH 041/100] chore(deps-dev): bump importlib-metadata from 6.3.0 to 6.4.1 (#2134) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 8 ++++---- pyproject.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/poetry.lock b/poetry.lock index fa2ba28fb57..57023b09068 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1091,14 +1091,14 @@ files = [ [[package]] name = "importlib-metadata" -version = "6.3.0" +version = "6.4.1" description = "Read metadata from Python packages" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "importlib_metadata-6.3.0-py3-none-any.whl", hash = "sha256:8f8bd2af397cf33bd344d35cfe7f489219b7d14fc79a3f854b75b8417e9226b0"}, - {file = "importlib_metadata-6.3.0.tar.gz", hash = "sha256:23c2bcae4762dfb0bbe072d358faec24957901d75b6c4ab11172c0c982532402"}, + {file = "importlib_metadata-6.4.1-py3-none-any.whl", hash = "sha256:63ace321e24167d12fbb176b6015f4dbe06868c54a2af4f15849586afb9027fd"}, + {file = "importlib_metadata-6.4.1.tar.gz", hash = "sha256:eb1a7933041f0f85c94cd130258df3fb0dec060ad8c1c9318892ef4192c47ce1"}, ] [package.dependencies] @@ -3035,4 +3035,4 @@ validation = ["fastjsonschema"] [metadata] lock-version = "2.0" python-versions = "^3.7.4" -content-hash = "9178cee32b9c766077ce20b83e5ae08a0b7e5f3a2cd4752f21727c5da6d67cef" +content-hash = "7d512bca260ee0a5f8e74c7e71f230973f9c34864f1a501661ead575068098e2" diff --git a/pyproject.toml b/pyproject.toml index 7b8d1984f45..2d824125577 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -85,7 +85,7 @@ mkdocs-material = "^9.1.6" filelock = "^3.11.0" checksumdir = "^1.2.0" mypy-boto3-appconfigdata = "^1.26.70" -importlib-metadata = "^6.3" +importlib-metadata = "^6.4" ijson = "^3.2.0" typed-ast = { version = "^1.5.4", python = "< 3.8"} hvac = "^1.1.0" From a77832c278b9ac656091dd92c03785d1625b89d2 Mon Sep 17 00:00:00 2001 From: Ruben Fonseca Date: Tue, 18 Apr 2023 20:04:04 +0200 Subject: [PATCH 042/100] feat(runtime): add support for python 3.10 (#2137) * feat: add support for python 3.10 * fix: add 3.10 to all workflows * fix: workflow version * fix: python version * fix: bump performance SLA * revert: reverting metrics sla values * fix: bump cdk layer version to support Python 3.10 * fix: addressed comments on PR --------- Co-authored-by: Leandro Damascena --- .github/ISSUE_TEMPLATE/bug_report.yml | 2 +- .github/ISSUE_TEMPLATE/static_typing.yml | 2 +- .github/workflows/publish_v2_layer.yml | 2 +- .github/workflows/python_build.yml | 4 +- .github/workflows/release.yml | 2 +- .../reusable_deploy_v2_layer_stack.yml | 2 +- .github/workflows/reusable_publish_docs.yml | 2 +- .github/workflows/run-e2e-tests.yml | 2 +- layer/poetry.lock | 54 +++---- layer/pyproject.toml | 4 +- package-lock.json | 120 ++++++++-------- package.json | 2 +- poetry.lock | 134 +++++++++--------- pyproject.toml | 2 +- .../function_thread_safety_handler.py | 2 +- tests/e2e/utils/infrastructure.py | 21 ++- 16 files changed, 186 insertions(+), 171 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 6d441bf0c64..e3dd2c17667 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -58,10 +58,10 @@ body: attributes: label: AWS Lambda function runtime options: - - 3.6 - 3.7 - 3.8 - 3.9 + - 3.10 validations: required: true - type: dropdown diff --git a/.github/ISSUE_TEMPLATE/static_typing.yml b/.github/ISSUE_TEMPLATE/static_typing.yml index 863dde7d33f..3bd302e7e1c 100644 --- a/.github/ISSUE_TEMPLATE/static_typing.yml +++ b/.github/ISSUE_TEMPLATE/static_typing.yml @@ -25,10 +25,10 @@ body: attributes: label: AWS Lambda function runtime options: - - 3.6 - 3.7 - 3.8 - 3.9 + - 3.10 validations: required: true - type: input diff --git a/.github/workflows/publish_v2_layer.yml b/.github/workflows/publish_v2_layer.yml index 9afd02d1465..8d8a8c34aae 100644 --- a/.github/workflows/publish_v2_layer.yml +++ b/.github/workflows/publish_v2_layer.yml @@ -50,7 +50,7 @@ jobs: - name: Setup python uses: actions/setup-python@v4 with: - python-version: "3.9" + python-version: "3.10" cache: "pip" - name: Resolve and install project dependencies # CDK spawns system python when compiling stack diff --git a/.github/workflows/python_build.yml b/.github/workflows/python_build.yml index 00a152e82d0..b126c285918 100644 --- a/.github/workflows/python_build.yml +++ b/.github/workflows/python_build.yml @@ -28,9 +28,9 @@ jobs: strategy: max-parallel: 4 matrix: - python-version: [3.7, 3.8, 3.9] + python-version: ["3.7", "3.8", "3.9", "3.10"] env: - PYTHON: ${{ matrix.python-version }} + PYTHON: "${{ matrix.python-version }}" steps: - uses: actions/checkout@v3 - name: Install poetry diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index bb35c5917f6..a3f05dc15e0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -65,7 +65,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v4 with: - python-version: "3.9" + python-version: "3.10" cache: "poetry" - name: Set release notes tag id: release_version diff --git a/.github/workflows/reusable_deploy_v2_layer_stack.yml b/.github/workflows/reusable_deploy_v2_layer_stack.yml index f4b4fe73f24..5af5d6385d0 100644 --- a/.github/workflows/reusable_deploy_v2_layer_stack.yml +++ b/.github/workflows/reusable_deploy_v2_layer_stack.yml @@ -108,7 +108,7 @@ jobs: - name: Setup python uses: actions/setup-python@v4 with: - python-version: "3.9" + python-version: "3.10" cache: "pip" - name: Resolve and install project dependencies # CDK spawns system python when compiling stack diff --git a/.github/workflows/reusable_publish_docs.yml b/.github/workflows/reusable_publish_docs.yml index aad83c0cddb..9be91b212bf 100644 --- a/.github/workflows/reusable_publish_docs.yml +++ b/.github/workflows/reusable_publish_docs.yml @@ -41,7 +41,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v4 with: - python-version: "3.8" + python-version: "3.10" cache: "poetry" - name: Install dependencies run: make dev diff --git a/.github/workflows/run-e2e-tests.yml b/.github/workflows/run-e2e-tests.yml index 73e39e28d79..2f7b2f494ea 100644 --- a/.github/workflows/run-e2e-tests.yml +++ b/.github/workflows/run-e2e-tests.yml @@ -30,7 +30,7 @@ jobs: strategy: fail-fast: false # needed so if a version fails, the others will still be able to complete and cleanup matrix: - version: ["3.7", "3.8", "3.9"] + version: ["3.7", "3.8", "3.9", "3.10"] if: ${{ github.actor != 'dependabot[bot]' }} steps: - name: "Checkout" diff --git a/layer/poetry.lock b/layer/poetry.lock index 39faf15d289..e0dab1f3647 100644 --- a/layer/poetry.lock +++ b/layer/poetry.lock @@ -21,14 +21,14 @@ tests-no-zope = ["cloudpickle", "cloudpickle", "hypothesis", "hypothesis", "mypy [[package]] name = "aws-cdk-asset-awscli-v1" -version = "2.2.138" +version = "2.2.144" description = "A library that contains the AWS CLI for use in Lambda Layers" category = "main" optional = false python-versions = "~=3.7" files = [ - {file = "aws-cdk.asset-awscli-v1-2.2.138.tar.gz", hash = "sha256:0a6880aa02399f74102e120aee96db75ec122a199b0735494c3dbcd09bd89c9c"}, - {file = "aws_cdk.asset_awscli_v1-2.2.138-py3-none-any.whl", hash = "sha256:d1f4e1b6a4bf5e9f1a7380a6141a3bf55d6fb6f1abfb0e1450bb258de3702f01"}, + {file = "aws-cdk.asset-awscli-v1-2.2.144.tar.gz", hash = "sha256:2953dbaa0dae2a1893318452a6d681a975cb73f160d61eb197a6b47b293c6371"}, + {file = "aws_cdk.asset_awscli_v1-2.2.144-py3-none-any.whl", hash = "sha256:cf9fd74fc56b4333ffb3631ce38ca585ec722fd59bd06f5f9b61c7f838ba1dd4"}, ] [package.dependencies] @@ -55,14 +55,14 @@ typeguard = ">=2.13.3,<2.14.0" [[package]] name = "aws-cdk-asset-node-proxy-agent-v5" -version = "2.0.114" +version = "2.0.119" description = "@aws-cdk/asset-node-proxy-agent-v5" category = "main" optional = false python-versions = "~=3.7" files = [ - {file = "aws-cdk.asset-node-proxy-agent-v5-2.0.114.tar.gz", hash = "sha256:5f8a0ecb4128617ef8321dd1b3501b52e4a071e7481a7d1498775897299f7349"}, - {file = "aws_cdk.asset_node_proxy_agent_v5-2.0.114-py3-none-any.whl", hash = "sha256:3b034917bd15f84c710b031dbd29d7fbbb665ce16a609eaabd890fa47949df40"}, + {file = "aws-cdk.asset-node-proxy-agent-v5-2.0.119.tar.gz", hash = "sha256:2a93b5a0870c0914771a0591a82aa44134f25e0236f94d05d4a558465caff385"}, + {file = "aws_cdk.asset_node_proxy_agent_v5-2.0.119-py3-none-any.whl", hash = "sha256:ea59cc9f924fc9c566819b7106b330e7632e4b5f9c1d3bee3d3d494615bc680d"}, ] [package.dependencies] @@ -72,14 +72,14 @@ typeguard = ">=2.13.3,<2.14.0" [[package]] name = "aws-cdk-lib" -version = "2.73.0" +version = "2.75.0" description = "Version 2 of the AWS Cloud Development Kit library" category = "main" optional = false python-versions = "~=3.7" files = [ - {file = "aws-cdk-lib-2.73.0.tar.gz", hash = "sha256:9e93044d19ae26ef4303b39cbd4b083f8b183bb9211bc2f9b76698a8c765d8ad"}, - {file = "aws_cdk_lib-2.73.0-py3-none-any.whl", hash = "sha256:60271826f4d53267b39c43aaba93eecbcd2b85c1a1ae206ce56f347344903554"}, + {file = "aws-cdk-lib-2.75.0.tar.gz", hash = "sha256:e81e328906577a79d8bb2980403e37a83645f8a883ba5c1309b399b5e0d1baae"}, + {file = "aws_cdk_lib-2.75.0-py3-none-any.whl", hash = "sha256:eb11341f2dc7134a354087396b2efcd952f54f3cff18c5c55a281cd6c45fc821"}, ] [package.dependencies] @@ -93,18 +93,18 @@ typeguard = ">=2.13.3,<2.14.0" [[package]] name = "boto3" -version = "1.26.112" +version = "1.26.115" description = "The AWS SDK for Python" category = "dev" optional = false python-versions = ">= 3.7" files = [ - {file = "boto3-1.26.112-py3-none-any.whl", hash = "sha256:03c2e1ddd29d993a6ab9b8a8fe184027957fc32bd405c496ad0c30311445925f"}, - {file = "boto3-1.26.112.tar.gz", hash = "sha256:4ea3319bba2e8ff7cd9560259ae64f073c7fb6312158aa375777687231cabe69"}, + {file = "boto3-1.26.115-py3-none-any.whl", hash = "sha256:deb53ad15ff0e75ae0be6d7115a2d34e4bafb0541484485f0feb61dabdfb5513"}, + {file = "boto3-1.26.115.tar.gz", hash = "sha256:2272a060005bf8299f7342cbf1344304eb44b7060cddba6784f676e3bc737bb8"}, ] [package.dependencies] -botocore = ">=1.29.112,<1.30.0" +botocore = ">=1.29.115,<1.30.0" jmespath = ">=0.7.1,<2.0.0" s3transfer = ">=0.6.0,<0.7.0" @@ -113,14 +113,14 @@ crt = ["botocore[crt] (>=1.21.0,<2.0a0)"] [[package]] name = "botocore" -version = "1.29.112" +version = "1.29.115" description = "Low-level, data-driven core of boto 3." category = "dev" optional = false python-versions = ">= 3.7" files = [ - {file = "botocore-1.29.112-py3-none-any.whl", hash = "sha256:2cbaddb09b46dcb0a05490724d51acb224d3a8df433c347f995b4d78bfb02c8a"}, - {file = "botocore-1.29.112.tar.gz", hash = "sha256:1f52d9371d7b5ee30a53dcef7954c3cf22e04b131cfab5268035f3299ccde9e1"}, + {file = "botocore-1.29.115-py3-none-any.whl", hash = "sha256:dff327977d7c9f98f2dc54b51b8f70326952dd50ae23b885fdfa8bfeec014b76"}, + {file = "botocore-1.29.115.tar.gz", hash = "sha256:58eee8cf8f4f3e515df29f6dc535dd86ed3f4cea40999c5bc74640ff40bdc71f"}, ] [package.dependencies] @@ -149,18 +149,18 @@ exceptiongroup = {version = "*", markers = "python_version < \"3.11\""} [[package]] name = "cdk-aws-lambda-powertools-layer" -version = "3.4.0" +version = "3.5.0" description = "A lambda layer for AWS Powertools for python and typescript" category = "main" optional = false python-versions = "~=3.7" files = [ - {file = "cdk-aws-lambda-powertools-layer-3.4.0.tar.gz", hash = "sha256:3d3e89cb3b0f201f6f96473208e66b18279688049317d9c9849584a03c5d54a0"}, - {file = "cdk_aws_lambda_powertools_layer-3.4.0-py3-none-any.whl", hash = "sha256:bb3c157de17d3fbdcbdc33e5ee967cc80606bbb7a14f46e4f1f6cc8c28db5c86"}, + {file = "cdk-aws-lambda-powertools-layer-3.5.0.tar.gz", hash = "sha256:801dd0f3decc918ab1225ff9b6de2d0f979c492004b66511c76b70cee472c4ba"}, + {file = "cdk_aws_lambda_powertools_layer-3.5.0-py3-none-any.whl", hash = "sha256:71427de2e99f41afde2cfaf2d2cf80d0e13cdc0d9ec392f9f5a60277812471cd"}, ] [package.dependencies] -aws-cdk-lib = ">=2.70.0,<3.0.0" +aws-cdk-lib = ">=2.75.0,<3.0.0" constructs = ">=10.0.5,<11.0.0" jsii = ">=1.80.0,<2.0.0" publication = ">=0.0.3" @@ -180,14 +180,14 @@ files = [ [[package]] name = "constructs" -version = "10.1.309" +version = "10.2.0" description = "A programming model for software-defined state" category = "main" optional = false python-versions = "~=3.7" files = [ - {file = "constructs-10.1.309-py3-none-any.whl", hash = "sha256:3127067e99151d1094b05443452bc9f84c685a719c00031c7b5e55e294e0deb7"}, - {file = "constructs-10.1.309.tar.gz", hash = "sha256:cbc36a68187d4c9dd33b46b87aac2dda469bfda95c37d4c198bd98911064dce8"}, + {file = "constructs-10.2.0-py3-none-any.whl", hash = "sha256:b915d4447c008b8e259d3565a8507f71014a40fdb8f31dfc3fb008c5190eef8a"}, + {file = "constructs-10.2.0.tar.gz", hash = "sha256:30c234f7c3be28200a433b47a43d584fb5c5684e67e316b495ec059b1e0dfaef"}, ] [package.dependencies] @@ -316,14 +316,14 @@ files = [ [[package]] name = "pytest" -version = "7.3.0" +version = "7.3.1" description = "pytest: simple powerful testing with Python" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "pytest-7.3.0-py3-none-any.whl", hash = "sha256:933051fa1bfbd38a21e73c3960cebdad4cf59483ddba7696c48509727e17f201"}, - {file = "pytest-7.3.0.tar.gz", hash = "sha256:58ecc27ebf0ea643ebfdf7fb1249335da761a00c9f955bcd922349bcb68ee57d"}, + {file = "pytest-7.3.1-py3-none-any.whl", hash = "sha256:3799fa815351fea3a5e96ac7e503a96fa51cc9942c3753cda7651b93c1cfa362"}, + {file = "pytest-7.3.1.tar.gz", hash = "sha256:434afafd78b1d78ed0addf160ad2b77a30d35d4bdf8af234fe621919d9ed15e3"}, ] [package.dependencies] @@ -458,4 +458,4 @@ testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more [metadata] lock-version = "2.0" python-versions = "^3.9" -content-hash = "ade085b1989174ee03e7f27a781b580e2f7199441da6d8f60b3bf7891f6ca66e" +content-hash = "dc47627a359b35b4080bcb1243d5fb814dc93086442c7a393560a2ba92633acd" diff --git a/layer/pyproject.toml b/layer/pyproject.toml index 5f10af27b94..5be2628e825 100644 --- a/layer/pyproject.toml +++ b/layer/pyproject.toml @@ -3,11 +3,11 @@ name = "aws-lambda-powertools-python-layer" version = "1.1.0" description = "AWS Lambda Powertools for Python Lambda Layers" authors = ["DevAx "] -license = "MIT" +license = "MIT" [tool.poetry.dependencies] python = "^3.9" -cdk-aws-lambda-powertools-layer = "^3.4.0" +cdk-aws-lambda-powertools-layer = "^3.5.0" [tool.poetry.dev-dependencies] pytest = "^7.1.2" diff --git a/package-lock.json b/package-lock.json index 3305a07d40f..ee0c802acc4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,62 +1,62 @@ { - "name": "aws-lambda-powertools-python-e2e", - "version": "1.0.0", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "name": "aws-lambda-powertools-python-e2e", - "version": "1.0.0", - "devDependencies": { - "aws-cdk": "^2.74.0" - } - }, - "node_modules/aws-cdk": { - "version": "2.74.0", - "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.74.0.tgz", - "integrity": "sha512-pc6QO9uR7Ii0qQ74nujskkFqPCGoWTTMyt03CFaGW0CwxMfpduGC0+bvlLBbJISAe5ZGuRuYIIxxDMkNi3AIcw==", - "dev": true, - "bin": { - "cdk": "bin/cdk" - }, - "engines": { - "node": ">= 14.15.0" - }, - "optionalDependencies": { - "fsevents": "2.3.2" - } - }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - } - }, - "dependencies": { - "aws-cdk": { - "version": "2.74.0", - "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.74.0.tgz", - "integrity": "sha512-pc6QO9uR7Ii0qQ74nujskkFqPCGoWTTMyt03CFaGW0CwxMfpduGC0+bvlLBbJISAe5ZGuRuYIIxxDMkNi3AIcw==", - "dev": true, - "requires": { - "fsevents": "2.3.2" - } - }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "optional": true - } - } + "name": "aws-lambda-powertools-python-e2e", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "aws-lambda-powertools-python-e2e", + "version": "1.0.0", + "devDependencies": { + "aws-cdk": "^2.75.0" + } + }, + "node_modules/aws-cdk": { + "version": "2.75.0", + "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.75.0.tgz", + "integrity": "sha512-BkyWNpYZz66Ewoi7rBPYZnW+0BAKbWYawhQ1v7KQWmGB0cFlQmvIfoOFklF5EOyAKOltUVRQF6KJf1/AIedkmg==", + "dev": true, + "bin": { + "cdk": "bin/cdk" + }, + "engines": { + "node": ">= 14.15.0" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + } + }, + "dependencies": { + "aws-cdk": { + "version": "2.75.0", + "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.75.0.tgz", + "integrity": "sha512-BkyWNpYZz66Ewoi7rBPYZnW+0BAKbWYawhQ1v7KQWmGB0cFlQmvIfoOFklF5EOyAKOltUVRQF6KJf1/AIedkmg==", + "dev": true, + "requires": { + "fsevents": "2.3.2" + } + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + } + } } diff --git a/package.json b/package.json index 6eef515eb28..1d08fc890ac 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,6 @@ "name": "aws-lambda-powertools-python-e2e", "version": "1.0.0", "devDependencies": { - "aws-cdk": "^2.74.0" + "aws-cdk": "^2.75.0" } } diff --git a/poetry.lock b/poetry.lock index 57023b09068..c27b98cd655 100644 --- a/poetry.lock +++ b/poetry.lock @@ -43,18 +43,18 @@ tests-no-zope = ["cloudpickle", "cloudpickle", "hypothesis", "hypothesis", "mypy [[package]] name = "aws-cdk-asset-awscli-v1" -version = "2.2.112" +version = "2.2.144" description = "A library that contains the AWS CLI for use in Lambda Layers" category = "dev" optional = false python-versions = "~=3.7" files = [ - {file = "aws-cdk.asset-awscli-v1-2.2.112.tar.gz", hash = "sha256:ffa513beb5dee9475473467301f56b1b28e371932a9dd3de1957ac13696f20c0"}, - {file = "aws_cdk.asset_awscli_v1-2.2.112-py3-none-any.whl", hash = "sha256:17521d316d400aa80759db7d815f44282413b818e032f75800d707540c939952"}, + {file = "aws-cdk.asset-awscli-v1-2.2.144.tar.gz", hash = "sha256:2953dbaa0dae2a1893318452a6d681a975cb73f160d61eb197a6b47b293c6371"}, + {file = "aws_cdk.asset_awscli_v1-2.2.144-py3-none-any.whl", hash = "sha256:cf9fd74fc56b4333ffb3631ce38ca585ec722fd59bd06f5f9b61c7f838ba1dd4"}, ] [package.dependencies] -jsii = ">=1.78.1,<2.0.0" +jsii = ">=1.80.0,<2.0.0" publication = ">=0.0.3" typeguard = ">=2.13.3,<2.14.0" @@ -77,90 +77,90 @@ typeguard = ">=2.13.3,<2.14.0" [[package]] name = "aws-cdk-asset-node-proxy-agent-v5" -version = "2.0.90" +version = "2.0.119" description = "@aws-cdk/asset-node-proxy-agent-v5" category = "dev" optional = false python-versions = "~=3.7" files = [ - {file = "aws-cdk.asset-node-proxy-agent-v5-2.0.90.tar.gz", hash = "sha256:84bfd073116c2b84d24d2a600a4d22ffdca46a2e2d2373eab81616e1e030229b"}, - {file = "aws_cdk.asset_node_proxy_agent_v5-2.0.90-py3-none-any.whl", hash = "sha256:d9f2ac7e41e1b1eb7b59af36414b441cda393b6735a6c8967159b9a60b36c2a0"}, + {file = "aws-cdk.asset-node-proxy-agent-v5-2.0.119.tar.gz", hash = "sha256:2a93b5a0870c0914771a0591a82aa44134f25e0236f94d05d4a558465caff385"}, + {file = "aws_cdk.asset_node_proxy_agent_v5-2.0.119-py3-none-any.whl", hash = "sha256:ea59cc9f924fc9c566819b7106b330e7632e4b5f9c1d3bee3d3d494615bc680d"}, ] [package.dependencies] -jsii = ">=1.78.1,<2.0.0" +jsii = ">=1.80.0,<2.0.0" publication = ">=0.0.3" typeguard = ">=2.13.3,<2.14.0" [[package]] name = "aws-cdk-aws-apigatewayv2-alpha" -version = "2.69.0a0" +version = "2.75.0a0" description = "The CDK Construct Library for AWS::APIGatewayv2" category = "dev" optional = false python-versions = "~=3.7" files = [ - {file = "aws-cdk.aws-apigatewayv2-alpha-2.69.0a0.tar.gz", hash = "sha256:f61aa37d839ce685bd8daa0c5058b664ab374b6e1d67582c2846c2b0230f4903"}, - {file = "aws_cdk.aws_apigatewayv2_alpha-2.69.0a0-py3-none-any.whl", hash = "sha256:07500b7c0c7919f75ee24a67eef3fc0c3107e8b1dbb4b5fa6888ce284fcbb53b"}, + {file = "aws-cdk.aws-apigatewayv2-alpha-2.75.0a0.tar.gz", hash = "sha256:1348c29ab83cccfe82ba0e34b97153a81f09391cdfab22b83d7d6390444bc551"}, + {file = "aws_cdk.aws_apigatewayv2_alpha-2.75.0a0-py3-none-any.whl", hash = "sha256:42e2ecb3b1ec6da1bed0ee3be8dab29b10e92e17fcebfa8cf8a44bb487102332"}, ] [package.dependencies] -aws-cdk-lib = ">=2.69.0,<3.0.0" +aws-cdk-lib = "2.75.0" constructs = ">=10.0.0,<11.0.0" -jsii = ">=1.77.0,<2.0.0" +jsii = ">=1.78.1,<2.0.0" publication = ">=0.0.3" typeguard = ">=2.13.3,<2.14.0" [[package]] name = "aws-cdk-aws-apigatewayv2-authorizers-alpha" -version = "2.69.0a0" +version = "2.75.0a0" description = "Authorizers for AWS APIGateway V2" category = "dev" optional = false python-versions = "~=3.7" files = [ - {file = "aws-cdk.aws-apigatewayv2-authorizers-alpha-2.69.0a0.tar.gz", hash = "sha256:c27207a38219ccf1b3cac6b9939d9a18aaa7cc195f80e74c553a2a3704034a02"}, - {file = "aws_cdk.aws_apigatewayv2_authorizers_alpha-2.69.0a0-py3-none-any.whl", hash = "sha256:3c31c4308f0a596f3320ed80d9b9c48f4660b3afc0479690c646ecce4344b653"}, + {file = "aws-cdk.aws-apigatewayv2-authorizers-alpha-2.75.0a0.tar.gz", hash = "sha256:0b9407cef4d46b41e44433952ed4ca00cae651437f3f532bf942f1d719abe43e"}, + {file = "aws_cdk.aws_apigatewayv2_authorizers_alpha-2.75.0a0-py3-none-any.whl", hash = "sha256:306e1ff0c919fc528ff1b69a6210870958f6e028266f5aba842ffcf74c3728ac"}, ] [package.dependencies] -"aws-cdk.aws-apigatewayv2-alpha" = "2.69.0.a0" -aws-cdk-lib = ">=2.69.0,<3.0.0" +"aws-cdk.aws-apigatewayv2-alpha" = "2.75.0.a0" +aws-cdk-lib = "2.75.0" constructs = ">=10.0.0,<11.0.0" -jsii = ">=1.77.0,<2.0.0" +jsii = ">=1.78.1,<2.0.0" publication = ">=0.0.3" typeguard = ">=2.13.3,<2.14.0" [[package]] name = "aws-cdk-aws-apigatewayv2-integrations-alpha" -version = "2.69.0a0" +version = "2.75.0a0" description = "Integrations for AWS APIGateway V2" category = "dev" optional = false python-versions = "~=3.7" files = [ - {file = "aws-cdk.aws-apigatewayv2-integrations-alpha-2.69.0a0.tar.gz", hash = "sha256:04d3a24da2bee46e4eac70fd0bfb0e4d8a5e9eca1da459dd21d163d0858c72f6"}, - {file = "aws_cdk.aws_apigatewayv2_integrations_alpha-2.69.0a0-py3-none-any.whl", hash = "sha256:20d3950c1eb57652173b9b1d4a0641941ae76c5458e06eae0b8ecc97b3d6e81f"}, + {file = "aws-cdk.aws-apigatewayv2-integrations-alpha-2.75.0a0.tar.gz", hash = "sha256:355e8980d886f50c37395b022647d31c0d071943f181de1d1f0c162055a3af39"}, + {file = "aws_cdk.aws_apigatewayv2_integrations_alpha-2.75.0a0-py3-none-any.whl", hash = "sha256:75c442ee356e782d81613266efcd2520cee2abed482928ada2d16f457f829692"}, ] [package.dependencies] -"aws-cdk.aws-apigatewayv2-alpha" = "2.69.0.a0" -aws-cdk-lib = ">=2.69.0,<3.0.0" +"aws-cdk.aws-apigatewayv2-alpha" = "2.75.0.a0" +aws-cdk-lib = "2.75.0" constructs = ">=10.0.0,<11.0.0" -jsii = ">=1.77.0,<2.0.0" +jsii = ">=1.78.1,<2.0.0" publication = ">=0.0.3" typeguard = ">=2.13.3,<2.14.0" [[package]] name = "aws-cdk-lib" -version = "2.74.0" +version = "2.75.0" description = "Version 2 of the AWS Cloud Development Kit library" category = "dev" optional = false python-versions = "~=3.7" files = [ - {file = "aws-cdk-lib-2.74.0.tar.gz", hash = "sha256:4cf4fe1c1278ae52d0faec4ef9ba34ea2d936045513fd61e63f58d20391a5805"}, - {file = "aws_cdk_lib-2.74.0-py3-none-any.whl", hash = "sha256:1ef84ae12a711298bfc0c14189284114466b0f14672f38a934a900120dbb6db7"}, + {file = "aws-cdk-lib-2.75.0.tar.gz", hash = "sha256:e81e328906577a79d8bb2980403e37a83645f8a883ba5c1309b399b5e0d1baae"}, + {file = "aws_cdk_lib-2.75.0-py3-none-any.whl", hash = "sha256:eb11341f2dc7134a354087396b2efcd952f54f3cff18c5c55a281cd6c45fc821"}, ] [package.dependencies] @@ -301,18 +301,18 @@ uvloop = ["uvloop (>=0.15.2)"] [[package]] name = "boto3" -version = "1.26.94" +version = "1.26.115" description = "The AWS SDK for Python" category = "main" optional = false python-versions = ">= 3.7" files = [ - {file = "boto3-1.26.94-py3-none-any.whl", hash = "sha256:619022059e255731f33cd9fe083b8fd62406efcbc07dc15660037bcaa1ba1255"}, - {file = "boto3-1.26.94.tar.gz", hash = "sha256:9f156f4da4b0a15924196e1a8e3439d1b99cd4a463588e4bb103d1cfaf5618fa"}, + {file = "boto3-1.26.115-py3-none-any.whl", hash = "sha256:deb53ad15ff0e75ae0be6d7115a2d34e4bafb0541484485f0feb61dabdfb5513"}, + {file = "boto3-1.26.115.tar.gz", hash = "sha256:2272a060005bf8299f7342cbf1344304eb44b7060cddba6784f676e3bc737bb8"}, ] [package.dependencies] -botocore = ">=1.29.94,<1.30.0" +botocore = ">=1.29.115,<1.30.0" jmespath = ">=0.7.1,<2.0.0" s3transfer = ">=0.6.0,<0.7.0" @@ -321,14 +321,14 @@ crt = ["botocore[crt] (>=1.21.0,<2.0a0)"] [[package]] name = "botocore" -version = "1.29.94" +version = "1.29.115" description = "Low-level, data-driven core of boto 3." category = "main" optional = false python-versions = ">= 3.7" files = [ - {file = "botocore-1.29.94-py3-none-any.whl", hash = "sha256:01b9e066b9eea719ee852e91841b92c7371f6bd388cf6186b5d55508e0f7fa1b"}, - {file = "botocore-1.29.94.tar.gz", hash = "sha256:3748b79e6fc95c19d890aa7439a53b9d468a4c4918439b2ba5cc3c13bfaff817"}, + {file = "botocore-1.29.115-py3-none-any.whl", hash = "sha256:dff327977d7c9f98f2dc54b51b8f70326952dd50ae23b885fdfa8bfeec014b76"}, + {file = "botocore-1.29.115.tar.gz", hash = "sha256:58eee8cf8f4f3e515df29f6dc535dd86ed3f4cea40999c5bc74640ff40bdc71f"}, ] [package.dependencies] @@ -519,18 +519,18 @@ files = [ [[package]] name = "constructs" -version = "10.1.283" +version = "10.1.314" description = "A programming model for software-defined state" category = "dev" optional = false python-versions = "~=3.7" files = [ - {file = "constructs-10.1.283-py3-none-any.whl", hash = "sha256:cb045cda84777e2288a053463685c8b453039029370e85beb778e94655b288d7"}, - {file = "constructs-10.1.283.tar.gz", hash = "sha256:fd41f311a94d36671cd731cfdfaeadd8e939c7c2d169e1983f374444e7e7171f"}, + {file = "constructs-10.1.314-py3-none-any.whl", hash = "sha256:852faf1acbb74355f172f4f4ead8029d085c0ad46e4a131203d216917a588daa"}, + {file = "constructs-10.1.314.tar.gz", hash = "sha256:389c336c0f91471232dee07e3dbd7a218d85f99b07423c3f93e326d68fb2d857"}, ] [package.dependencies] -jsii = ">=1.78.1,<2.0.0" +jsii = ">=1.80.0,<2.0.0" publication = ">=0.0.3" typeguard = ">=2.13.3,<2.14.0" @@ -929,14 +929,14 @@ typing-extensions = {version = "*", markers = "python_version < \"3.8\""} [[package]] name = "httpcore" -version = "0.16.3" +version = "0.17.0" description = "A minimal low-level HTTP client." category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "httpcore-0.16.3-py3-none-any.whl", hash = "sha256:da1fb708784a938aa084bde4feb8317056c55037247c787bd7e19eb2c2949dc0"}, - {file = "httpcore-0.16.3.tar.gz", hash = "sha256:c5d6f04e2fc530f39e0c077e6a30caa53f1451096120f1f38b954afd0b17c0cb"}, + {file = "httpcore-0.17.0-py3-none-any.whl", hash = "sha256:0fdfea45e94f0c9fd96eab9286077f9ff788dd186635ae61b312693e4d943599"}, + {file = "httpcore-0.17.0.tar.gz", hash = "sha256:cc045a3241afbf60ce056202301b4d8b6af08845e3294055eb26b09913ef903c"}, ] [package.dependencies] @@ -1208,14 +1208,14 @@ pbr = "*" [[package]] name = "jsii" -version = "1.78.1" +version = "1.80.0" description = "Python client for jsii runtime" category = "dev" optional = false python-versions = "~=3.7" files = [ - {file = "jsii-1.78.1-py3-none-any.whl", hash = "sha256:63021b4465c56603f17c4c690cf4da55bf4cb26f0e59e085436ccbd72efe8dd0"}, - {file = "jsii-1.78.1.tar.gz", hash = "sha256:58f5d223e16efb8bc4b7911dbcaf6d6ac43fe2bd51ae7ec7db4bc7d79a333df3"}, + {file = "jsii-1.80.0-py3-none-any.whl", hash = "sha256:ea3cace063f6a47cdf0a74c929618d779efab426fedb7692a8ac1b9b29797f8c"}, + {file = "jsii-1.80.0.tar.gz", hash = "sha256:4da63ab99f2696cd063574460c94221f0a7de9d345e71dfb19dfbcecf8ca8355"}, ] [package.dependencies] @@ -1871,14 +1871,14 @@ test = ["codecov (>=2.1)", "pytest (>=6.2)", "pytest-cov (>=2.12)"] [[package]] name = "packaging" -version = "23.0" +version = "23.1" description = "Core utilities for Python packages" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "packaging-23.0-py3-none-any.whl", hash = "sha256:714ac14496c3e68c99c29b00845f7a2b85f3bb6f1078fd9f72fd20f0570002b2"}, - {file = "packaging-23.0.tar.gz", hash = "sha256:b6ad297f8907de0fa2fe1ccbd26fdaf387f5f47c7275fedf8cce89f99446cf97"}, + {file = "packaging-23.1-py3-none-any.whl", hash = "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61"}, + {file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"}, ] [[package]] @@ -1935,22 +1935,22 @@ files = [ [[package]] name = "platformdirs" -version = "3.1.1" +version = "3.2.0" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "platformdirs-3.1.1-py3-none-any.whl", hash = "sha256:e5986afb596e4bb5bde29a79ac9061aa955b94fca2399b7aaac4090860920dd8"}, - {file = "platformdirs-3.1.1.tar.gz", hash = "sha256:024996549ee88ec1a9aa99ff7f8fc819bb59e2c3477b410d90a16d32d6e707aa"}, + {file = "platformdirs-3.2.0-py3-none-any.whl", hash = "sha256:ebe11c0d7a805086e99506aa331612429a72ca7cd52a1f0d277dc4adc20cb10e"}, + {file = "platformdirs-3.2.0.tar.gz", hash = "sha256:d5b638ca397f25f979350ff789db335903d7ea010ab28903f57b27e1b16c2b08"}, ] [package.dependencies] -typing-extensions = {version = ">=4.4", markers = "python_version < \"3.8\""} +typing-extensions = {version = ">=4.5", markers = "python_version < \"3.8\""} [package.extras] docs = ["furo (>=2022.12.7)", "proselint (>=0.13)", "sphinx (>=6.1.3)", "sphinx-autodoc-typehints (>=1.22,!=1.23.4)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.2.2)", "pytest (>=7.2.1)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.2.2)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"] [[package]] name = "pluggy" @@ -2110,14 +2110,14 @@ files = [ [[package]] name = "pygments" -version = "2.14.0" +version = "2.15.0" description = "Pygments is a syntax highlighting package written in Python." category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "Pygments-2.14.0-py3-none-any.whl", hash = "sha256:fa7bd7bd2771287c0de303af8bfdfc731f51bd2c6a47ab69d117138893b82717"}, - {file = "Pygments-2.14.0.tar.gz", hash = "sha256:b3ed06a9e8ac9a9aae5a6f5dbe78a8a58655d17b43b93c078f094ddc476ae297"}, + {file = "Pygments-2.15.0-py3-none-any.whl", hash = "sha256:77a3299119af881904cd5ecd1ac6a66214b6e9bed1f2db16993b54adede64094"}, + {file = "Pygments-2.15.0.tar.gz", hash = "sha256:f7e36cffc4c517fbc252861b9a6e4644ca0e5abadf9a113c72d1358ad09b9500"}, ] [package.extras] @@ -2136,14 +2136,14 @@ files = [ [[package]] name = "pymdown-extensions" -version = "9.10" +version = "9.11" description = "Extension pack for Python Markdown." category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "pymdown_extensions-9.10-py3-none-any.whl", hash = "sha256:31eaa76ce6f96aabfcea98787c2fff2c5c0611b20a53a94213970cfbf05f02b8"}, - {file = "pymdown_extensions-9.10.tar.gz", hash = "sha256:562c38eee4ce3f101ce631b804bfc2177a8a76c7e4dc908871fb6741a90257a7"}, + {file = "pymdown_extensions-9.11-py3-none-any.whl", hash = "sha256:a499191d8d869f30339de86fcf072a787e86c42b6f16f280f5c2cf174182b7f3"}, + {file = "pymdown_extensions-9.11.tar.gz", hash = "sha256:f7e86c1d3981f23d9dc43294488ecb54abadd05b0be4bf8f0e15efc90f7853ff"}, ] [package.dependencies] @@ -2603,14 +2603,14 @@ py = ">=1.4.26,<2.0.0" [[package]] name = "rich" -version = "13.3.2" +version = "13.3.4" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" category = "dev" optional = false python-versions = ">=3.7.0" files = [ - {file = "rich-13.3.2-py3-none-any.whl", hash = "sha256:a104f37270bf677148d8acb07d33be1569eeee87e2d1beb286a4e9113caf6f2f"}, - {file = "rich-13.3.2.tar.gz", hash = "sha256:91954fe80cfb7985727a467ca98a7618e5dd15178cc2da10f553b36a93859001"}, + {file = "rich-13.3.4-py3-none-any.whl", hash = "sha256:22b74cae0278fd5086ff44144d3813be1cedc9115bdfabbfefd86400cb88b20a"}, + {file = "rich-13.3.4.tar.gz", hash = "sha256:b5d573e13605423ec80bdd0cd5f8541f7844a0e71a13f74cf454ccb2f490708b"}, ] [package.dependencies] @@ -2813,14 +2813,14 @@ types-urllib3 = "<1.27" [[package]] name = "types-urllib3" -version = "1.26.25.8" +version = "1.26.25.10" description = "Typing stubs for urllib3" category = "dev" optional = false python-versions = "*" files = [ - {file = "types-urllib3-1.26.25.8.tar.gz", hash = "sha256:ecf43c42d8ee439d732a1110b4901e9017a79a38daca26f08e42c8460069392c"}, - {file = "types_urllib3-1.26.25.8-py3-none-any.whl", hash = "sha256:95ea847fbf0bf675f50c8ae19a665baedcf07e6b4641662c4c3c72e7b2edf1a9"}, + {file = "types-urllib3-1.26.25.10.tar.gz", hash = "sha256:c44881cde9fc8256d05ad6b21f50c4681eb20092552351570ab0a8a0653286d6"}, + {file = "types_urllib3-1.26.25.10-py3-none-any.whl", hash = "sha256:12c744609d588340a07e45d333bf870069fc8793bcf96bae7a96d4712a42591d"}, ] [[package]] @@ -3035,4 +3035,4 @@ validation = ["fastjsonschema"] [metadata] lock-version = "2.0" python-versions = "^3.7.4" -content-hash = "7d512bca260ee0a5f8e74c7e71f230973f9c34864f1a501661ead575068098e2" +content-hash = "ffe8a051efdfcacf7d64eee522f7e9c1a1260aa605e4ba68dec7e3d5330d0979" diff --git a/pyproject.toml b/pyproject.toml index 2d824125577..361ef7a6dae 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -63,7 +63,7 @@ mkdocs-git-revision-date-plugin = "^0.3.2" mike = "^1.1.2" retry = "^0.9.2" pytest-xdist = "^3.2.1" -aws-cdk-lib = "^2.74.0" +aws-cdk-lib = "^2.75.0" "aws-cdk.aws-apigatewayv2-alpha" = "^2.38.1-alpha.0" "aws-cdk.aws-apigatewayv2-integrations-alpha" = "^2.38.1-alpha.0" "aws-cdk.aws-apigatewayv2-authorizers-alpha" = "^2.38.1-alpha.0" diff --git a/tests/e2e/idempotency/handlers/function_thread_safety_handler.py b/tests/e2e/idempotency/handlers/function_thread_safety_handler.py index 6e23759b29e..a4644aa61c3 100644 --- a/tests/e2e/idempotency/handlers/function_thread_safety_handler.py +++ b/tests/e2e/idempotency/handlers/function_thread_safety_handler.py @@ -21,7 +21,7 @@ def record_handler(record): def lambda_handler(event, context): with ThreadPoolExecutor(max_workers=threads_count) as executor: - futures = [executor.submit(record_handler, **{"record": event}) for _ in range(threads_count)] + futures = [executor.submit(record_handler, **{"record": i}) for i in range(threads_count)] return [ {"state": future._state, "exception": future.exception(), "output": future.result()} diff --git a/tests/e2e/utils/infrastructure.py b/tests/e2e/utils/infrastructure.py index 29e45b83abf..e827841c52c 100644 --- a/tests/e2e/utils/infrastructure.py +++ b/tests/e2e/utils/infrastructure.py @@ -95,12 +95,12 @@ def create_lambda_functions( self.create_lambda_functions() ``` - Creating Lambda functions and override runtime to Python 3.7 + Creating Lambda functions and override runtime to Python 3.10 ```python from aws_cdk.aws_lambda import Runtime - self.create_lambda_functions(function_props={"runtime": Runtime.PYTHON_3_7) + self.create_lambda_functions(function_props={"runtime": Runtime.PYTHON_3_10) ``` """ if not self._handlers_dir.exists(): @@ -115,6 +115,7 @@ def create_lambda_functions( Runtime.PYTHON_3_7, Runtime.PYTHON_3_8, Runtime.PYTHON_3_9, + Runtime.PYTHON_3_10, ], compatible_architectures=[architecture], code=Code.from_asset(path=layer_build), @@ -138,7 +139,7 @@ def create_lambda_functions( "code": source, "handler": f"{fn_name}.lambda_handler", "tracing": Tracing.ACTIVE, - "runtime": Runtime.PYTHON_3_9, + "runtime": self._determine_runtime_version(), "layers": [layer], "architecture": architecture, **function_settings_override, @@ -243,6 +244,20 @@ def _create_temp_cdk_app(self): temp_file.chmod(0o755) return temp_file + def _determine_runtime_version(self) -> Runtime: + """Determine Python runtime version based on the current Python interpreter""" + version = sys.version_info + if version.major == 3 and version.minor == 7: + return Runtime.PYTHON_3_7 + elif version.major == 3 and version.minor == 8: + return Runtime.PYTHON_3_8 + elif version.major == 3 and version.minor == 9: + return Runtime.PYTHON_3_9 + elif version.major == 3 and version.minor == 10: + return Runtime.PYTHON_3_10 + else: + raise Exception(f"Unsupported Python version: {version}") + def create_resources(self) -> None: """Create any necessary CDK resources. It'll be called before deploy From b4704b43b65b50327e7a12ed9677d5e592da5bed Mon Sep 17 00:00:00 2001 From: Ruben Fonseca Date: Tue, 18 Apr 2023 20:17:04 +0200 Subject: [PATCH 043/100] fix: enable python 3.10 on SAR template --- layer/sar/template.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/layer/sar/template.txt b/layer/sar/template.txt index 9d0818b7980..a8a97fbfeae 100644 --- a/layer/sar/template.txt +++ b/layer/sar/template.txt @@ -14,7 +14,7 @@ Metadata: SourceCodeUrl: https://github.com/awslabs/aws-lambda-powertools-python Transform: AWS::Serverless-2016-10-31 -Description: AWS Lambda Layer for aws-lambda-powertools with python 3.9, 3.8 or 3.7 +Description: AWS Lambda Layer for aws-lambda-powertools with python 3.10, 3.9, 3.8 or 3.7 Resources: LambdaLayer: @@ -24,6 +24,7 @@ Resources: LayerName: ContentUri: CompatibleRuntimes: + - python3.10 - python3.9 - python3.8 - python3.7 From c44a45c80caea13efddf65a7fdbc9e8af2c0a1e3 Mon Sep 17 00:00:00 2001 From: Release bot Date: Tue, 18 Apr 2023 18:27:16 +0000 Subject: [PATCH 044/100] chore: update v2 layer ARN on documentation --- docs/index.md | 128 ++++++++++++++--------------- examples/logger/sam/template.yaml | 2 +- examples/metrics/sam/template.yaml | 2 +- examples/tracer/sam/template.yaml | 2 +- 4 files changed, 67 insertions(+), 67 deletions(-) diff --git a/docs/index.md b/docs/index.md index 6b0db547dea..4c193cd2f78 100644 --- a/docs/index.md +++ b/docs/index.md @@ -26,8 +26,8 @@ Powertools is a developer toolkit to implement Serverless best practices and inc You can install Powertools using one of the following options: -* **Lambda Layer (x86_64)**: [**arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:28**](#){: .copyMe}:clipboard: -* **Lambda Layer (arm64)**: [**arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:28**](#){: .copyMe}:clipboard: +* **Lambda Layer (x86_64)**: [**arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:29**](#){: .copyMe}:clipboard: +* **Lambda Layer (arm64)**: [**arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:29**](#){: .copyMe}:clipboard: * **Pip**: **[`pip install "aws-lambda-powertools"`](#){: .copyMe}:clipboard:** ??? question "Using Pip? You might need to install additional dependencies." @@ -78,60 +78,60 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. | Region | Layer ARN | | ---------------- | ---------------------------------------------------------------------------------------------------------- | - | `af-south-1` | [arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | - | `ap-east-1` | [arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | - | `ap-northeast-1` | [arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | - | `ap-northeast-2` | [arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | - | `ap-northeast-3` | [arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | - | `ap-south-1` | [arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | - | `ap-south-2` | [arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | - | `ap-southeast-1` | [arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | - | `ap-southeast-2` | [arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | - | `ap-southeast-3` | [arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | - | `ap-southeast-4` | [arn:aws:lambda:ap-southeast-4:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | - | `ca-central-1` | [arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | - | `eu-central-1` | [arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | - | `eu-central-2` | [arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | - | `eu-north-1` | [arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | - | `eu-south-1` | [arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | - | `eu-south-2` | [arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | - | `eu-west-1` | [arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | - | `eu-west-2` | [arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | - | `eu-west-3` | [arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | - | `me-central-1` | [arn:aws:lambda:me-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | - | `me-south-1` | [arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | - | `sa-east-1` | [arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | - | `us-east-1` | [arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | - | `us-east-2` | [arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | - | `us-west-1` | [arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | - | `us-west-2` | [arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:28](#){: .copyMe}:clipboard: | + | `af-south-1` | [arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:29](#){: .copyMe}:clipboard: | + | `ap-east-1` | [arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:29](#){: .copyMe}:clipboard: | + | `ap-northeast-1` | [arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:29](#){: .copyMe}:clipboard: | + | `ap-northeast-2` | [arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:29](#){: .copyMe}:clipboard: | + | `ap-northeast-3` | [arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:29](#){: .copyMe}:clipboard: | + | `ap-south-1` | [arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:29](#){: .copyMe}:clipboard: | + | `ap-south-2` | [arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:29](#){: .copyMe}:clipboard: | + | `ap-southeast-1` | [arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:29](#){: .copyMe}:clipboard: | + | `ap-southeast-2` | [arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:29](#){: .copyMe}:clipboard: | + | `ap-southeast-3` | [arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:29](#){: .copyMe}:clipboard: | + | `ap-southeast-4` | [arn:aws:lambda:ap-southeast-4:017000801446:layer:AWSLambdaPowertoolsPythonV2:29](#){: .copyMe}:clipboard: | + | `ca-central-1` | [arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:29](#){: .copyMe}:clipboard: | + | `eu-central-1` | [arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:29](#){: .copyMe}:clipboard: | + | `eu-central-2` | [arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:29](#){: .copyMe}:clipboard: | + | `eu-north-1` | [arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:29](#){: .copyMe}:clipboard: | + | `eu-south-1` | [arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:29](#){: .copyMe}:clipboard: | + | `eu-south-2` | [arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:29](#){: .copyMe}:clipboard: | + | `eu-west-1` | [arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:29](#){: .copyMe}:clipboard: | + | `eu-west-2` | [arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:29](#){: .copyMe}:clipboard: | + | `eu-west-3` | [arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:29](#){: .copyMe}:clipboard: | + | `me-central-1` | [arn:aws:lambda:me-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:29](#){: .copyMe}:clipboard: | + | `me-south-1` | [arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:29](#){: .copyMe}:clipboard: | + | `sa-east-1` | [arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:29](#){: .copyMe}:clipboard: | + | `us-east-1` | [arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:29](#){: .copyMe}:clipboard: | + | `us-east-2` | [arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:29](#){: .copyMe}:clipboard: | + | `us-west-1` | [arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:29](#){: .copyMe}:clipboard: | + | `us-west-2` | [arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:29](#){: .copyMe}:clipboard: | === "arm64" | Region | Layer ARN | | ---------------- | ---------------------------------------------------------------------------------------------------------------- | - | `af-south-1` | [arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:28](#){: .copyMe}:clipboard: | - | `ap-east-1` | [arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:28](#){: .copyMe}:clipboard: | - | `ap-northeast-1` | [arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:28](#){: .copyMe}:clipboard: | - | `ap-northeast-2` | [arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:28](#){: .copyMe}:clipboard: | - | `ap-northeast-3` | [arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:28](#){: .copyMe}:clipboard: | - | `ap-south-1` | [arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:28](#){: .copyMe}:clipboard: | - | `ap-southeast-1` | [arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:28](#){: .copyMe}:clipboard: | - | `ap-southeast-2` | [arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:28](#){: .copyMe}:clipboard: | - | `ap-southeast-3` | [arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:28](#){: .copyMe}:clipboard: | - | `ca-central-1` | [arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:28](#){: .copyMe}:clipboard: | - | `eu-central-1` | [arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:28](#){: .copyMe}:clipboard: | - | `eu-north-1` | [arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:28](#){: .copyMe}:clipboard: | - | `eu-south-1` | [arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:28](#){: .copyMe}:clipboard: | - | `eu-west-1` | [arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:28](#){: .copyMe}:clipboard: | - | `eu-west-2` | [arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:28](#){: .copyMe}:clipboard: | - | `eu-west-3` | [arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:28](#){: .copyMe}:clipboard: | - | `me-south-1` | [arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:28](#){: .copyMe}:clipboard: | - | `sa-east-1` | [arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:28](#){: .copyMe}:clipboard: | - | `us-east-1` | [arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:28](#){: .copyMe}:clipboard: | - | `us-east-2` | [arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:28](#){: .copyMe}:clipboard: | - | `us-west-1` | [arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:28](#){: .copyMe}:clipboard: | - | `us-west-2` | [arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:28](#){: .copyMe}:clipboard: | + | `af-south-1` | [arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:29](#){: .copyMe}:clipboard: | + | `ap-east-1` | [arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:29](#){: .copyMe}:clipboard: | + | `ap-northeast-1` | [arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:29](#){: .copyMe}:clipboard: | + | `ap-northeast-2` | [arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:29](#){: .copyMe}:clipboard: | + | `ap-northeast-3` | [arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:29](#){: .copyMe}:clipboard: | + | `ap-south-1` | [arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:29](#){: .copyMe}:clipboard: | + | `ap-southeast-1` | [arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:29](#){: .copyMe}:clipboard: | + | `ap-southeast-2` | [arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:29](#){: .copyMe}:clipboard: | + | `ap-southeast-3` | [arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:29](#){: .copyMe}:clipboard: | + | `ca-central-1` | [arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:29](#){: .copyMe}:clipboard: | + | `eu-central-1` | [arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:29](#){: .copyMe}:clipboard: | + | `eu-north-1` | [arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:29](#){: .copyMe}:clipboard: | + | `eu-south-1` | [arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:29](#){: .copyMe}:clipboard: | + | `eu-west-1` | [arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:29](#){: .copyMe}:clipboard: | + | `eu-west-2` | [arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:29](#){: .copyMe}:clipboard: | + | `eu-west-3` | [arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:29](#){: .copyMe}:clipboard: | + | `me-south-1` | [arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:29](#){: .copyMe}:clipboard: | + | `sa-east-1` | [arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:29](#){: .copyMe}:clipboard: | + | `us-east-1` | [arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:29](#){: .copyMe}:clipboard: | + | `us-east-2` | [arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:29](#){: .copyMe}:clipboard: | + | `us-west-1` | [arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:29](#){: .copyMe}:clipboard: | + | `us-west-2` | [arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:29](#){: .copyMe}:clipboard: | ??? note "Note: Click to expand and copy code snippets for popular frameworks" @@ -144,7 +144,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. Type: AWS::Serverless::Function Properties: Layers: - - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:28 + - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:29 ``` === "Serverless framework" @@ -154,7 +154,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. hello: handler: lambda_function.lambda_handler layers: - - arn:aws:lambda:${aws:region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:28 + - arn:aws:lambda:${aws:region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:29 ``` === "CDK" @@ -170,7 +170,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. powertools_layer = aws_lambda.LayerVersion.from_layer_version_arn( self, id="lambda-powertools", - layer_version_arn=f"arn:aws:lambda:{env.region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:28" + layer_version_arn=f"arn:aws:lambda:{env.region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:29" ) aws_lambda.Function(self, 'sample-app-lambda', @@ -219,7 +219,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. role = aws_iam_role.iam_for_lambda.arn handler = "index.test" runtime = "python3.9" - layers = ["arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:28"] + layers = ["arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:29"] source_code_hash = filebase64sha256("lambda_function_payload.zip") } @@ -272,7 +272,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. ? Do you want to configure advanced settings? Yes ... ? Do you want to enable Lambda layers for this function? Yes - ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28 + ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:29 ❯ amplify push -y @@ -283,7 +283,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. - Name: ? Which setting do you want to update? Lambda layers configuration ? Do you want to enable Lambda layers for this function? Yes - ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:28 + ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:29 ? Do you want to edit the local lambda function now? No ``` @@ -297,7 +297,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. Properties: Architectures: [arm64] Layers: - - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:28 + - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:29 ``` === "Serverless framework" @@ -308,7 +308,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. handler: lambda_function.lambda_handler architecture: arm64 layers: - - arn:aws:lambda:${aws:region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:28 + - arn:aws:lambda:${aws:region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:29 ``` === "CDK" @@ -324,7 +324,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. powertools_layer = aws_lambda.LayerVersion.from_layer_version_arn( self, id="lambda-powertools", - layer_version_arn=f"arn:aws:lambda:{env.region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:28" + layer_version_arn=f"arn:aws:lambda:{env.region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:29" ) aws_lambda.Function(self, 'sample-app-lambda', @@ -374,7 +374,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. role = aws_iam_role.iam_for_lambda.arn handler = "index.test" runtime = "python3.9" - layers = ["arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:28"] + layers = ["arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:29"] architectures = ["arm64"] source_code_hash = filebase64sha256("lambda_function_payload.zip") @@ -430,7 +430,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. ? Do you want to configure advanced settings? Yes ... ? Do you want to enable Lambda layers for this function? Yes - ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:28 + ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:29 ❯ amplify push -y @@ -441,7 +441,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. - Name: ? Which setting do you want to update? Lambda layers configuration ? Do you want to enable Lambda layers for this function? Yes - ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:28 + ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:29 ? Do you want to edit the local lambda function now? No ``` @@ -449,7 +449,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. Change {region} to your AWS region, e.g. `eu-west-1` ```bash title="AWS CLI" - aws lambda get-layer-version-by-arn --arn arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:28 --region {region} + aws lambda get-layer-version-by-arn --arn arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:29 --region {region} ``` The pre-signed URL to download this Lambda Layer will be within `Location` key. diff --git a/examples/logger/sam/template.yaml b/examples/logger/sam/template.yaml index 3fdf5f2742d..ebc81b95174 100644 --- a/examples/logger/sam/template.yaml +++ b/examples/logger/sam/template.yaml @@ -14,7 +14,7 @@ Globals: Layers: # Find the latest Layer version in the official documentation # https://awslabs.github.io/aws-lambda-powertools-python/latest/#lambda-layer - - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:28 + - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:29 Resources: LoggerLambdaHandlerExample: diff --git a/examples/metrics/sam/template.yaml b/examples/metrics/sam/template.yaml index 532de6cb335..e3254eead34 100644 --- a/examples/metrics/sam/template.yaml +++ b/examples/metrics/sam/template.yaml @@ -15,7 +15,7 @@ Globals: Layers: # Find the latest Layer version in the official documentation # https://awslabs.github.io/aws-lambda-powertools-python/latest/#lambda-layer - - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:28 + - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:29 Resources: CaptureLambdaHandlerExample: diff --git a/examples/tracer/sam/template.yaml b/examples/tracer/sam/template.yaml index 1b3f5d65338..0181c48a0e9 100644 --- a/examples/tracer/sam/template.yaml +++ b/examples/tracer/sam/template.yaml @@ -13,7 +13,7 @@ Globals: Layers: # Find the latest Layer version in the official documentation # https://awslabs.github.io/aws-lambda-powertools-python/latest/#lambda-layer - - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:28 + - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:29 Resources: CaptureLambdaHandlerExample: From a51e1917f97bc5b0a70e5b84946f915e67c24b19 Mon Sep 17 00:00:00 2001 From: Release bot Date: Tue, 18 Apr 2023 18:42:40 +0000 Subject: [PATCH 045/100] bump version to 2.14.0 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 361ef7a6dae..dfba2eddebf 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "aws_lambda_powertools" -version = "2.13.0" +version = "2.14.0" description = "AWS Lambda Powertools is a developer toolkit to implement Serverless best practices and increase developer velocity." authors = ["Amazon Web Services"] include = ["aws_lambda_powertools/py.typed", "THIRD-PARTY-LICENSES"] From 42378c5038ca22854bfb39f7c1424955c16a7c2e Mon Sep 17 00:00:00 2001 From: Release bot Date: Tue, 18 Apr 2023 18:43:01 +0000 Subject: [PATCH 046/100] update changelog with latest changes --- CHANGELOG.md | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 05bab17d15f..0dce26ef95d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,22 +4,39 @@ # Unreleased + + +## [v2.14.0] - 2023-04-18 ## Bug Fixes +* enable python 3.10 on SAR template * **ci:** fix layer version in tracer, logger and metrics * **ci:** typo * **docs:** add Layer ARN for new 5 regions * **layers:** add debug to update layer arn script +## Features + +* **runtime:** add support for python 3.10 ([#2137](https://github.com/awslabs/aws-lambda-powertools-python/issues/2137)) + ## Maintenance +* update v2 layer ARN on documentation * update v2 layer ARN on documentation * update v2 layer ARN on documentation * **ci:** add support for x86-64 regions only ([#2122](https://github.com/awslabs/aws-lambda-powertools-python/issues/2122)) +* **deps-dev:** bump importlib-metadata from 6.3.0 to 6.4.1 ([#2134](https://github.com/awslabs/aws-lambda-powertools-python/issues/2134)) +* **deps-dev:** bump cfn-lint from 0.77.0 to 0.77.1 ([#2133](https://github.com/awslabs/aws-lambda-powertools-python/issues/2133)) * **deps-dev:** bump pytest from 7.3.0 to 7.3.1 ([#2127](https://github.com/awslabs/aws-lambda-powertools-python/issues/2127)) * **deps-dev:** bump mypy-boto3-lambda from 1.26.109 to 1.26.114 ([#2126](https://github.com/awslabs/aws-lambda-powertools-python/issues/2126)) +* **deps-dev:** bump mypy-boto3-lambda from 1.26.114 to 1.26.115 ([#2135](https://github.com/awslabs/aws-lambda-powertools-python/issues/2135)) +* **deps-dev:** bump mypy-boto3-dynamodb from 1.26.97.post1 to 1.26.115 ([#2132](https://github.com/awslabs/aws-lambda-powertools-python/issues/2132)) +* **github:** new tech debt issue form ([#2131](https://github.com/awslabs/aws-lambda-powertools-python/issues/2131)) * **layer:** change layer-balance script to support new regions +## Reverts +* chore: update v2 layer ARN on documentation + ## [v2.13.0] - 2023-04-14 @@ -3119,7 +3136,8 @@ * Merge pull request [#5](https://github.com/awslabs/aws-lambda-powertools-python/issues/5) from jfuss/feat/python38 -[Unreleased]: https://github.com/awslabs/aws-lambda-powertools-python/compare/v2.13.0...HEAD +[Unreleased]: https://github.com/awslabs/aws-lambda-powertools-python/compare/v2.14.0...HEAD +[v2.14.0]: https://github.com/awslabs/aws-lambda-powertools-python/compare/v2.13.0...v2.14.0 [v2.13.0]: https://github.com/awslabs/aws-lambda-powertools-python/compare/v2.12.0...v2.13.0 [v2.12.0]: https://github.com/awslabs/aws-lambda-powertools-python/compare/v2.11.0...v2.12.0 [v2.11.0]: https://github.com/awslabs/aws-lambda-powertools-python/compare/v2.10.0...v2.11.0 From a05f1d203691e03fc1727949ed9eaf0782be4208 Mon Sep 17 00:00:00 2001 From: Release bot Date: Tue, 18 Apr 2023 18:55:27 +0000 Subject: [PATCH 047/100] chore: update v2 layer ARN on documentation --- docs/index.md | 128 ++++++++++++++--------------- examples/logger/sam/template.yaml | 2 +- examples/metrics/sam/template.yaml | 2 +- examples/tracer/sam/template.yaml | 2 +- 4 files changed, 67 insertions(+), 67 deletions(-) diff --git a/docs/index.md b/docs/index.md index 4c193cd2f78..a1ad0e0f2ad 100644 --- a/docs/index.md +++ b/docs/index.md @@ -26,8 +26,8 @@ Powertools is a developer toolkit to implement Serverless best practices and inc You can install Powertools using one of the following options: -* **Lambda Layer (x86_64)**: [**arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:29**](#){: .copyMe}:clipboard: -* **Lambda Layer (arm64)**: [**arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:29**](#){: .copyMe}:clipboard: +* **Lambda Layer (x86_64)**: [**arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:30**](#){: .copyMe}:clipboard: +* **Lambda Layer (arm64)**: [**arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:30**](#){: .copyMe}:clipboard: * **Pip**: **[`pip install "aws-lambda-powertools"`](#){: .copyMe}:clipboard:** ??? question "Using Pip? You might need to install additional dependencies." @@ -78,60 +78,60 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. | Region | Layer ARN | | ---------------- | ---------------------------------------------------------------------------------------------------------- | - | `af-south-1` | [arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:29](#){: .copyMe}:clipboard: | - | `ap-east-1` | [arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:29](#){: .copyMe}:clipboard: | - | `ap-northeast-1` | [arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:29](#){: .copyMe}:clipboard: | - | `ap-northeast-2` | [arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:29](#){: .copyMe}:clipboard: | - | `ap-northeast-3` | [arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:29](#){: .copyMe}:clipboard: | - | `ap-south-1` | [arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:29](#){: .copyMe}:clipboard: | - | `ap-south-2` | [arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:29](#){: .copyMe}:clipboard: | - | `ap-southeast-1` | [arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:29](#){: .copyMe}:clipboard: | - | `ap-southeast-2` | [arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:29](#){: .copyMe}:clipboard: | - | `ap-southeast-3` | [arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:29](#){: .copyMe}:clipboard: | - | `ap-southeast-4` | [arn:aws:lambda:ap-southeast-4:017000801446:layer:AWSLambdaPowertoolsPythonV2:29](#){: .copyMe}:clipboard: | - | `ca-central-1` | [arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:29](#){: .copyMe}:clipboard: | - | `eu-central-1` | [arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:29](#){: .copyMe}:clipboard: | - | `eu-central-2` | [arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:29](#){: .copyMe}:clipboard: | - | `eu-north-1` | [arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:29](#){: .copyMe}:clipboard: | - | `eu-south-1` | [arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:29](#){: .copyMe}:clipboard: | - | `eu-south-2` | [arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:29](#){: .copyMe}:clipboard: | - | `eu-west-1` | [arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:29](#){: .copyMe}:clipboard: | - | `eu-west-2` | [arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:29](#){: .copyMe}:clipboard: | - | `eu-west-3` | [arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:29](#){: .copyMe}:clipboard: | - | `me-central-1` | [arn:aws:lambda:me-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:29](#){: .copyMe}:clipboard: | - | `me-south-1` | [arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:29](#){: .copyMe}:clipboard: | - | `sa-east-1` | [arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:29](#){: .copyMe}:clipboard: | - | `us-east-1` | [arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:29](#){: .copyMe}:clipboard: | - | `us-east-2` | [arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:29](#){: .copyMe}:clipboard: | - | `us-west-1` | [arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:29](#){: .copyMe}:clipboard: | - | `us-west-2` | [arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:29](#){: .copyMe}:clipboard: | + | `af-south-1` | [arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:30](#){: .copyMe}:clipboard: | + | `ap-east-1` | [arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:30](#){: .copyMe}:clipboard: | + | `ap-northeast-1` | [arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:30](#){: .copyMe}:clipboard: | + | `ap-northeast-2` | [arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:30](#){: .copyMe}:clipboard: | + | `ap-northeast-3` | [arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:30](#){: .copyMe}:clipboard: | + | `ap-south-1` | [arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:30](#){: .copyMe}:clipboard: | + | `ap-south-2` | [arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:30](#){: .copyMe}:clipboard: | + | `ap-southeast-1` | [arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:30](#){: .copyMe}:clipboard: | + | `ap-southeast-2` | [arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:30](#){: .copyMe}:clipboard: | + | `ap-southeast-3` | [arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:30](#){: .copyMe}:clipboard: | + | `ap-southeast-4` | [arn:aws:lambda:ap-southeast-4:017000801446:layer:AWSLambdaPowertoolsPythonV2:30](#){: .copyMe}:clipboard: | + | `ca-central-1` | [arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:30](#){: .copyMe}:clipboard: | + | `eu-central-1` | [arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:30](#){: .copyMe}:clipboard: | + | `eu-central-2` | [arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:30](#){: .copyMe}:clipboard: | + | `eu-north-1` | [arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:30](#){: .copyMe}:clipboard: | + | `eu-south-1` | [arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:30](#){: .copyMe}:clipboard: | + | `eu-south-2` | [arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:30](#){: .copyMe}:clipboard: | + | `eu-west-1` | [arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:30](#){: .copyMe}:clipboard: | + | `eu-west-2` | [arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:30](#){: .copyMe}:clipboard: | + | `eu-west-3` | [arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:30](#){: .copyMe}:clipboard: | + | `me-central-1` | [arn:aws:lambda:me-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:30](#){: .copyMe}:clipboard: | + | `me-south-1` | [arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:30](#){: .copyMe}:clipboard: | + | `sa-east-1` | [arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:30](#){: .copyMe}:clipboard: | + | `us-east-1` | [arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:30](#){: .copyMe}:clipboard: | + | `us-east-2` | [arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:30](#){: .copyMe}:clipboard: | + | `us-west-1` | [arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:30](#){: .copyMe}:clipboard: | + | `us-west-2` | [arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:30](#){: .copyMe}:clipboard: | === "arm64" | Region | Layer ARN | | ---------------- | ---------------------------------------------------------------------------------------------------------------- | - | `af-south-1` | [arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:29](#){: .copyMe}:clipboard: | - | `ap-east-1` | [arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:29](#){: .copyMe}:clipboard: | - | `ap-northeast-1` | [arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:29](#){: .copyMe}:clipboard: | - | `ap-northeast-2` | [arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:29](#){: .copyMe}:clipboard: | - | `ap-northeast-3` | [arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:29](#){: .copyMe}:clipboard: | - | `ap-south-1` | [arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:29](#){: .copyMe}:clipboard: | - | `ap-southeast-1` | [arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:29](#){: .copyMe}:clipboard: | - | `ap-southeast-2` | [arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:29](#){: .copyMe}:clipboard: | - | `ap-southeast-3` | [arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:29](#){: .copyMe}:clipboard: | - | `ca-central-1` | [arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:29](#){: .copyMe}:clipboard: | - | `eu-central-1` | [arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:29](#){: .copyMe}:clipboard: | - | `eu-north-1` | [arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:29](#){: .copyMe}:clipboard: | - | `eu-south-1` | [arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:29](#){: .copyMe}:clipboard: | - | `eu-west-1` | [arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:29](#){: .copyMe}:clipboard: | - | `eu-west-2` | [arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:29](#){: .copyMe}:clipboard: | - | `eu-west-3` | [arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:29](#){: .copyMe}:clipboard: | - | `me-south-1` | [arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:29](#){: .copyMe}:clipboard: | - | `sa-east-1` | [arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:29](#){: .copyMe}:clipboard: | - | `us-east-1` | [arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:29](#){: .copyMe}:clipboard: | - | `us-east-2` | [arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:29](#){: .copyMe}:clipboard: | - | `us-west-1` | [arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:29](#){: .copyMe}:clipboard: | - | `us-west-2` | [arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:29](#){: .copyMe}:clipboard: | + | `af-south-1` | [arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:30](#){: .copyMe}:clipboard: | + | `ap-east-1` | [arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:30](#){: .copyMe}:clipboard: | + | `ap-northeast-1` | [arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:30](#){: .copyMe}:clipboard: | + | `ap-northeast-2` | [arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:30](#){: .copyMe}:clipboard: | + | `ap-northeast-3` | [arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:30](#){: .copyMe}:clipboard: | + | `ap-south-1` | [arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:30](#){: .copyMe}:clipboard: | + | `ap-southeast-1` | [arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:30](#){: .copyMe}:clipboard: | + | `ap-southeast-2` | [arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:30](#){: .copyMe}:clipboard: | + | `ap-southeast-3` | [arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:30](#){: .copyMe}:clipboard: | + | `ca-central-1` | [arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:30](#){: .copyMe}:clipboard: | + | `eu-central-1` | [arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:30](#){: .copyMe}:clipboard: | + | `eu-north-1` | [arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:30](#){: .copyMe}:clipboard: | + | `eu-south-1` | [arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:30](#){: .copyMe}:clipboard: | + | `eu-west-1` | [arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:30](#){: .copyMe}:clipboard: | + | `eu-west-2` | [arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:30](#){: .copyMe}:clipboard: | + | `eu-west-3` | [arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:30](#){: .copyMe}:clipboard: | + | `me-south-1` | [arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:30](#){: .copyMe}:clipboard: | + | `sa-east-1` | [arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:30](#){: .copyMe}:clipboard: | + | `us-east-1` | [arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:30](#){: .copyMe}:clipboard: | + | `us-east-2` | [arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:30](#){: .copyMe}:clipboard: | + | `us-west-1` | [arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:30](#){: .copyMe}:clipboard: | + | `us-west-2` | [arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:30](#){: .copyMe}:clipboard: | ??? note "Note: Click to expand and copy code snippets for popular frameworks" @@ -144,7 +144,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. Type: AWS::Serverless::Function Properties: Layers: - - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:29 + - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:30 ``` === "Serverless framework" @@ -154,7 +154,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. hello: handler: lambda_function.lambda_handler layers: - - arn:aws:lambda:${aws:region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:29 + - arn:aws:lambda:${aws:region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:30 ``` === "CDK" @@ -170,7 +170,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. powertools_layer = aws_lambda.LayerVersion.from_layer_version_arn( self, id="lambda-powertools", - layer_version_arn=f"arn:aws:lambda:{env.region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:29" + layer_version_arn=f"arn:aws:lambda:{env.region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:30" ) aws_lambda.Function(self, 'sample-app-lambda', @@ -219,7 +219,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. role = aws_iam_role.iam_for_lambda.arn handler = "index.test" runtime = "python3.9" - layers = ["arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:29"] + layers = ["arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:30"] source_code_hash = filebase64sha256("lambda_function_payload.zip") } @@ -272,7 +272,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. ? Do you want to configure advanced settings? Yes ... ? Do you want to enable Lambda layers for this function? Yes - ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:29 + ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:30 ❯ amplify push -y @@ -283,7 +283,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. - Name: ? Which setting do you want to update? Lambda layers configuration ? Do you want to enable Lambda layers for this function? Yes - ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:29 + ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:30 ? Do you want to edit the local lambda function now? No ``` @@ -297,7 +297,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. Properties: Architectures: [arm64] Layers: - - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:29 + - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:30 ``` === "Serverless framework" @@ -308,7 +308,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. handler: lambda_function.lambda_handler architecture: arm64 layers: - - arn:aws:lambda:${aws:region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:29 + - arn:aws:lambda:${aws:region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:30 ``` === "CDK" @@ -324,7 +324,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. powertools_layer = aws_lambda.LayerVersion.from_layer_version_arn( self, id="lambda-powertools", - layer_version_arn=f"arn:aws:lambda:{env.region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:29" + layer_version_arn=f"arn:aws:lambda:{env.region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:30" ) aws_lambda.Function(self, 'sample-app-lambda', @@ -374,7 +374,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. role = aws_iam_role.iam_for_lambda.arn handler = "index.test" runtime = "python3.9" - layers = ["arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:29"] + layers = ["arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:30"] architectures = ["arm64"] source_code_hash = filebase64sha256("lambda_function_payload.zip") @@ -430,7 +430,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. ? Do you want to configure advanced settings? Yes ... ? Do you want to enable Lambda layers for this function? Yes - ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:29 + ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:30 ❯ amplify push -y @@ -441,7 +441,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. - Name: ? Which setting do you want to update? Lambda layers configuration ? Do you want to enable Lambda layers for this function? Yes - ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:29 + ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:30 ? Do you want to edit the local lambda function now? No ``` @@ -449,7 +449,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. Change {region} to your AWS region, e.g. `eu-west-1` ```bash title="AWS CLI" - aws lambda get-layer-version-by-arn --arn arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:29 --region {region} + aws lambda get-layer-version-by-arn --arn arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:30 --region {region} ``` The pre-signed URL to download this Lambda Layer will be within `Location` key. diff --git a/examples/logger/sam/template.yaml b/examples/logger/sam/template.yaml index ebc81b95174..8921b950f6a 100644 --- a/examples/logger/sam/template.yaml +++ b/examples/logger/sam/template.yaml @@ -14,7 +14,7 @@ Globals: Layers: # Find the latest Layer version in the official documentation # https://awslabs.github.io/aws-lambda-powertools-python/latest/#lambda-layer - - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:29 + - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:30 Resources: LoggerLambdaHandlerExample: diff --git a/examples/metrics/sam/template.yaml b/examples/metrics/sam/template.yaml index e3254eead34..4378e9835f7 100644 --- a/examples/metrics/sam/template.yaml +++ b/examples/metrics/sam/template.yaml @@ -15,7 +15,7 @@ Globals: Layers: # Find the latest Layer version in the official documentation # https://awslabs.github.io/aws-lambda-powertools-python/latest/#lambda-layer - - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:29 + - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:30 Resources: CaptureLambdaHandlerExample: diff --git a/examples/tracer/sam/template.yaml b/examples/tracer/sam/template.yaml index 0181c48a0e9..0cf1ddbb4e8 100644 --- a/examples/tracer/sam/template.yaml +++ b/examples/tracer/sam/template.yaml @@ -13,7 +13,7 @@ Globals: Layers: # Find the latest Layer version in the official documentation # https://awslabs.github.io/aws-lambda-powertools-python/latest/#lambda-layer - - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:29 + - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:30 Resources: CaptureLambdaHandlerExample: From f5efe6f8c3c89c21c534ed11ec409d9aadf97d0e Mon Sep 17 00:00:00 2001 From: Heitor Lessa Date: Tue, 18 Apr 2023 21:00:58 +0200 Subject: [PATCH 048/100] docs(readme): update python version badge to 3.10 Signed-off-by: Heitor Lessa --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cb0aa00d83b..b79f43a85f3 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![Build](https://github.com/awslabs/aws-lambda-powertools-python/actions/workflows/python_build.yml/badge.svg)](https://github.com/awslabs/aws-lambda-powertools-python/actions/workflows/python_build.yml) [![codecov.io](https://codecov.io/github/awslabs/aws-lambda-powertools-python/branch/develop/graphs/badge.svg)](https://app.codecov.io/gh/awslabs/aws-lambda-powertools-python) -![PythonSupport](https://img.shields.io/static/v1?label=python&message=%203.7|%203.8|%203.9&color=blue?style=flat-square&logo=python) ![PyPI version](https://badge.fury.io/py/aws-lambda-powertools.svg) ![PyPi monthly downloads](https://img.shields.io/pypi/dm/aws-lambda-powertools) [![Join our Discord](https://dcbadge.vercel.app/api/server/B8zZKbbyET)](https://discord.gg/B8zZKbbyET) +![PythonSupport](https://img.shields.io/static/v1?label=python&message=%203.7|%203.8|%203.9|%203.10&color=blue?style=flat-square&logo=python) ![PyPI version](https://badge.fury.io/py/aws-lambda-powertools.svg) ![PyPi monthly downloads](https://img.shields.io/pypi/dm/aws-lambda-powertools) [![Join our Discord](https://dcbadge.vercel.app/api/server/B8zZKbbyET)](https://discord.gg/B8zZKbbyET) Powertools is a developer toolkit to implement Serverless [best practices and increase developer velocity](https://awslabs.github.io/aws-lambda-powertools-python/latest/#features). From 94db4ab4603ac4bd4028df47c6cfbb2a2140ac75 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 18 Apr 2023 22:44:16 +0100 Subject: [PATCH 049/100] chore(deps-dev): bump filelock from 3.11.0 to 3.12.0 (#2142) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 12 ++++++------ pyproject.toml | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/poetry.lock b/poetry.lock index c27b98cd655..f9fe73286fa 100644 --- a/poetry.lock +++ b/poetry.lock @@ -672,19 +672,19 @@ devel = ["colorama", "json-spec", "jsonschema", "pylint", "pytest", "pytest-benc [[package]] name = "filelock" -version = "3.11.0" +version = "3.12.0" description = "A platform independent file lock." category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "filelock-3.11.0-py3-none-any.whl", hash = "sha256:f08a52314748335c6460fc8fe40cd5638b85001225db78c2aa01c8c0db83b318"}, - {file = "filelock-3.11.0.tar.gz", hash = "sha256:3618c0da67adcc0506b015fd11ef7faf1b493f0b40d87728e19986b536890c37"}, + {file = "filelock-3.12.0-py3-none-any.whl", hash = "sha256:ad98852315c2ab702aeb628412cbf7e95b7ce8c3bf9565670b4eaecf1db370a9"}, + {file = "filelock-3.12.0.tar.gz", hash = "sha256:fc03ae43288c013d2ea83c8597001b1129db351aad9c57fe2409327916b8e718"}, ] [package.extras] -docs = ["furo (>=2023.3.27)", "sphinx (>=6.1.3)", "sphinx-autodoc-typehints (>=1.22,!=1.23.4)"] -testing = ["covdefaults (>=2.3)", "coverage (>=7.2.2)", "diff-cover (>=7.5)", "pytest (>=7.2.2)", "pytest-cov (>=4)", "pytest-mock (>=3.10)", "pytest-timeout (>=2.1)"] +docs = ["furo (>=2023.3.27)", "sphinx (>=6.1.3)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"] +testing = ["covdefaults (>=2.3)", "coverage (>=7.2.3)", "diff-cover (>=7.5)", "pytest (>=7.3.1)", "pytest-cov (>=4)", "pytest-mock (>=3.10)", "pytest-timeout (>=2.1)"] [[package]] name = "flake8" @@ -3035,4 +3035,4 @@ validation = ["fastjsonschema"] [metadata] lock-version = "2.0" python-versions = "^3.7.4" -content-hash = "ffe8a051efdfcacf7d64eee522f7e9c1a1260aa605e4ba68dec7e3d5330d0979" +content-hash = "87b6c40e864e9c6431f62c748ba3eefaab3f116dc6cf409c0c23719c0e3bf42c" diff --git a/pyproject.toml b/pyproject.toml index dfba2eddebf..6c5b4c2fb7c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -82,7 +82,7 @@ mypy-boto3-xray = "^1.26.11" types-requests = "^2.28.11" typing-extensions = "^4.4.0" mkdocs-material = "^9.1.6" -filelock = "^3.11.0" +filelock = "^3.12.0" checksumdir = "^1.2.0" mypy-boto3-appconfigdata = "^1.26.70" importlib-metadata = "^6.4" From 0210d52d6b2aac3c51a81a3077d43741e7704c8e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 18 Apr 2023 22:46:13 +0100 Subject: [PATCH 050/100] chore(deps): bump dependabot/fetch-metadata from 1.3.6 to 1.4.0 (#2140) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/auto-merge.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/auto-merge.yml b/.github/workflows/auto-merge.yml index 2e799c65333..b2a3d23bd9b 100644 --- a/.github/workflows/auto-merge.yml +++ b/.github/workflows/auto-merge.yml @@ -14,7 +14,7 @@ jobs: steps: - name: Dependabot metadata id: metadata - uses: dependabot/fetch-metadata@v1.3.6 + uses: dependabot/fetch-metadata@v1.4.0 with: github-token: "${{ secrets.GITHUB_TOKEN }}" - name: Enable auto-merge for mypy-boto3 stubs Dependabot PRs From 521b1478d16c7e0cc84a8e377a8c19a2ffa44729 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 18 Apr 2023 22:55:56 +0100 Subject: [PATCH 051/100] chore(deps-dev): bump importlib-metadata from 6.4.1 to 6.5.0 (#2141) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 8 ++++---- pyproject.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/poetry.lock b/poetry.lock index f9fe73286fa..aeaaec3a1e1 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1091,14 +1091,14 @@ files = [ [[package]] name = "importlib-metadata" -version = "6.4.1" +version = "6.5.0" description = "Read metadata from Python packages" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "importlib_metadata-6.4.1-py3-none-any.whl", hash = "sha256:63ace321e24167d12fbb176b6015f4dbe06868c54a2af4f15849586afb9027fd"}, - {file = "importlib_metadata-6.4.1.tar.gz", hash = "sha256:eb1a7933041f0f85c94cd130258df3fb0dec060ad8c1c9318892ef4192c47ce1"}, + {file = "importlib_metadata-6.5.0-py3-none-any.whl", hash = "sha256:03ba783c3a2c69d751b109fc0c94a62c51f581b3d6acf8ed1331b6d5729321ff"}, + {file = "importlib_metadata-6.5.0.tar.gz", hash = "sha256:7a8bdf1bc3a726297f5cfbc999e6e7ff6b4fa41b26bba4afc580448624460045"}, ] [package.dependencies] @@ -3035,4 +3035,4 @@ validation = ["fastjsonschema"] [metadata] lock-version = "2.0" python-versions = "^3.7.4" -content-hash = "87b6c40e864e9c6431f62c748ba3eefaab3f116dc6cf409c0c23719c0e3bf42c" +content-hash = "49068e0c4f4dd9b22bb9fa199afa60d5b4f10020b602fc5b8e99ac209bbbb239" diff --git a/pyproject.toml b/pyproject.toml index 6c5b4c2fb7c..07a06d31c90 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -85,7 +85,7 @@ mkdocs-material = "^9.1.6" filelock = "^3.12.0" checksumdir = "^1.2.0" mypy-boto3-appconfigdata = "^1.26.70" -importlib-metadata = "^6.4" +importlib-metadata = "^6.5" ijson = "^3.2.0" typed-ast = { version = "^1.5.4", python = "< 3.8"} hvac = "^1.1.0" From 180e5286a52aec10b82c9cea223e96bc93428371 Mon Sep 17 00:00:00 2001 From: Ruben Fonseca Date: Wed, 19 Apr 2023 10:35:23 +0200 Subject: [PATCH 052/100] chore: add Python 3.10 PyPi language classifier (#2144) --- poetry.lock | 58 +++++++++++++++++++++++++------------------------- pyproject.toml | 1 + 2 files changed, 30 insertions(+), 29 deletions(-) diff --git a/poetry.lock b/poetry.lock index aeaaec3a1e1..1b08afdd42c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -43,14 +43,14 @@ tests-no-zope = ["cloudpickle", "cloudpickle", "hypothesis", "hypothesis", "mypy [[package]] name = "aws-cdk-asset-awscli-v1" -version = "2.2.144" +version = "2.2.145" description = "A library that contains the AWS CLI for use in Lambda Layers" category = "dev" optional = false python-versions = "~=3.7" files = [ - {file = "aws-cdk.asset-awscli-v1-2.2.144.tar.gz", hash = "sha256:2953dbaa0dae2a1893318452a6d681a975cb73f160d61eb197a6b47b293c6371"}, - {file = "aws_cdk.asset_awscli_v1-2.2.144-py3-none-any.whl", hash = "sha256:cf9fd74fc56b4333ffb3631ce38ca585ec722fd59bd06f5f9b61c7f838ba1dd4"}, + {file = "aws-cdk.asset-awscli-v1-2.2.145.tar.gz", hash = "sha256:74098ca36a0e3d0655c98638174c77f1c6599f1b16fb4e4387721a955b431aac"}, + {file = "aws_cdk.asset_awscli_v1-2.2.145-py3-none-any.whl", hash = "sha256:bf736e03cff78b6bad51777cfa204985368975d5b0139434ef6d7e069b757bb7"}, ] [package.dependencies] @@ -77,14 +77,14 @@ typeguard = ">=2.13.3,<2.14.0" [[package]] name = "aws-cdk-asset-node-proxy-agent-v5" -version = "2.0.119" +version = "2.0.120" description = "@aws-cdk/asset-node-proxy-agent-v5" category = "dev" optional = false python-versions = "~=3.7" files = [ - {file = "aws-cdk.asset-node-proxy-agent-v5-2.0.119.tar.gz", hash = "sha256:2a93b5a0870c0914771a0591a82aa44134f25e0236f94d05d4a558465caff385"}, - {file = "aws_cdk.asset_node_proxy_agent_v5-2.0.119-py3-none-any.whl", hash = "sha256:ea59cc9f924fc9c566819b7106b330e7632e4b5f9c1d3bee3d3d494615bc680d"}, + {file = "aws-cdk.asset-node-proxy-agent-v5-2.0.120.tar.gz", hash = "sha256:5c885003685fe86aafe1611a4f1310f1cda62b27036e3528e1fe4e16ba3a3ac4"}, + {file = "aws_cdk.asset_node_proxy_agent_v5-2.0.120-py3-none-any.whl", hash = "sha256:6264375b03fa62a3a2e67e360517276874ec814dc4367d7c9eff55a4e8dff155"}, ] [package.dependencies] @@ -94,18 +94,18 @@ typeguard = ">=2.13.3,<2.14.0" [[package]] name = "aws-cdk-aws-apigatewayv2-alpha" -version = "2.75.0a0" +version = "2.75.1a0" description = "The CDK Construct Library for AWS::APIGatewayv2" category = "dev" optional = false python-versions = "~=3.7" files = [ - {file = "aws-cdk.aws-apigatewayv2-alpha-2.75.0a0.tar.gz", hash = "sha256:1348c29ab83cccfe82ba0e34b97153a81f09391cdfab22b83d7d6390444bc551"}, - {file = "aws_cdk.aws_apigatewayv2_alpha-2.75.0a0-py3-none-any.whl", hash = "sha256:42e2ecb3b1ec6da1bed0ee3be8dab29b10e92e17fcebfa8cf8a44bb487102332"}, + {file = "aws-cdk.aws-apigatewayv2-alpha-2.75.1a0.tar.gz", hash = "sha256:ddfa9b4ad8c9a4968fd637081ed732b0e099ccedb4d7ccd7c1526bff7f036b93"}, + {file = "aws_cdk.aws_apigatewayv2_alpha-2.75.1a0-py3-none-any.whl", hash = "sha256:cf1920e37a60265286c0ab50ea78e1e065278f3758c0dde9e79d0811bd7c90d9"}, ] [package.dependencies] -aws-cdk-lib = "2.75.0" +aws-cdk-lib = "2.75.1" constructs = ">=10.0.0,<11.0.0" jsii = ">=1.78.1,<2.0.0" publication = ">=0.0.3" @@ -113,19 +113,19 @@ typeguard = ">=2.13.3,<2.14.0" [[package]] name = "aws-cdk-aws-apigatewayv2-authorizers-alpha" -version = "2.75.0a0" +version = "2.75.1a0" description = "Authorizers for AWS APIGateway V2" category = "dev" optional = false python-versions = "~=3.7" files = [ - {file = "aws-cdk.aws-apigatewayv2-authorizers-alpha-2.75.0a0.tar.gz", hash = "sha256:0b9407cef4d46b41e44433952ed4ca00cae651437f3f532bf942f1d719abe43e"}, - {file = "aws_cdk.aws_apigatewayv2_authorizers_alpha-2.75.0a0-py3-none-any.whl", hash = "sha256:306e1ff0c919fc528ff1b69a6210870958f6e028266f5aba842ffcf74c3728ac"}, + {file = "aws-cdk.aws-apigatewayv2-authorizers-alpha-2.75.1a0.tar.gz", hash = "sha256:524918a1aebf29c72f345162079bbb34cca87213480dc106931444a37496c8fe"}, + {file = "aws_cdk.aws_apigatewayv2_authorizers_alpha-2.75.1a0-py3-none-any.whl", hash = "sha256:493ea5f7e981c08dd772e50c95158aa7223b395a0668b5bba05b8c0ccb694f5a"}, ] [package.dependencies] -"aws-cdk.aws-apigatewayv2-alpha" = "2.75.0.a0" -aws-cdk-lib = "2.75.0" +"aws-cdk.aws-apigatewayv2-alpha" = "2.75.1.a0" +aws-cdk-lib = "2.75.1" constructs = ">=10.0.0,<11.0.0" jsii = ">=1.78.1,<2.0.0" publication = ">=0.0.3" @@ -133,19 +133,19 @@ typeguard = ">=2.13.3,<2.14.0" [[package]] name = "aws-cdk-aws-apigatewayv2-integrations-alpha" -version = "2.75.0a0" +version = "2.75.1a0" description = "Integrations for AWS APIGateway V2" category = "dev" optional = false python-versions = "~=3.7" files = [ - {file = "aws-cdk.aws-apigatewayv2-integrations-alpha-2.75.0a0.tar.gz", hash = "sha256:355e8980d886f50c37395b022647d31c0d071943f181de1d1f0c162055a3af39"}, - {file = "aws_cdk.aws_apigatewayv2_integrations_alpha-2.75.0a0-py3-none-any.whl", hash = "sha256:75c442ee356e782d81613266efcd2520cee2abed482928ada2d16f457f829692"}, + {file = "aws-cdk.aws-apigatewayv2-integrations-alpha-2.75.1a0.tar.gz", hash = "sha256:bfc11f80ad38b092c2ce861579b1bfa3b841773c85fb79c3ed548170f80cc115"}, + {file = "aws_cdk.aws_apigatewayv2_integrations_alpha-2.75.1a0-py3-none-any.whl", hash = "sha256:f536d663a1fffb55e0785151d2def5a94f1b914a59463824e69ca185b6018f4c"}, ] [package.dependencies] -"aws-cdk.aws-apigatewayv2-alpha" = "2.75.0.a0" -aws-cdk-lib = "2.75.0" +"aws-cdk.aws-apigatewayv2-alpha" = "2.75.1.a0" +aws-cdk-lib = "2.75.1" constructs = ">=10.0.0,<11.0.0" jsii = ">=1.78.1,<2.0.0" publication = ">=0.0.3" @@ -153,14 +153,14 @@ typeguard = ">=2.13.3,<2.14.0" [[package]] name = "aws-cdk-lib" -version = "2.75.0" +version = "2.75.1" description = "Version 2 of the AWS Cloud Development Kit library" category = "dev" optional = false python-versions = "~=3.7" files = [ - {file = "aws-cdk-lib-2.75.0.tar.gz", hash = "sha256:e81e328906577a79d8bb2980403e37a83645f8a883ba5c1309b399b5e0d1baae"}, - {file = "aws_cdk_lib-2.75.0-py3-none-any.whl", hash = "sha256:eb11341f2dc7134a354087396b2efcd952f54f3cff18c5c55a281cd6c45fc821"}, + {file = "aws-cdk-lib-2.75.1.tar.gz", hash = "sha256:7b9c285ea9681e59c215e2ad3917b046ef47c48d83bc9c555b425a37df30d34d"}, + {file = "aws_cdk_lib-2.75.1-py3-none-any.whl", hash = "sha256:1a4a61ce69280f522b7cee7b910284ab01ef091af220e7e0fad8433fd58e4325"}, ] [package.dependencies] @@ -519,14 +519,14 @@ files = [ [[package]] name = "constructs" -version = "10.1.314" +version = "10.2.1" description = "A programming model for software-defined state" category = "dev" optional = false python-versions = "~=3.7" files = [ - {file = "constructs-10.1.314-py3-none-any.whl", hash = "sha256:852faf1acbb74355f172f4f4ead8029d085c0ad46e4a131203d216917a588daa"}, - {file = "constructs-10.1.314.tar.gz", hash = "sha256:389c336c0f91471232dee07e3dbd7a218d85f99b07423c3f93e326d68fb2d857"}, + {file = "constructs-10.2.1-py3-none-any.whl", hash = "sha256:398d32c65d2945949195dcc642bc7bd7b7552758d274fa0e1616ca0069d01a25"}, + {file = "constructs-10.2.1.tar.gz", hash = "sha256:36e86d1092edd1f2ee8895d21c49bdabf81e62deb5f18329b275ee8ec1f67aa3"}, ] [package.dependencies] @@ -2110,14 +2110,14 @@ files = [ [[package]] name = "pygments" -version = "2.15.0" +version = "2.15.1" description = "Pygments is a syntax highlighting package written in Python." category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "Pygments-2.15.0-py3-none-any.whl", hash = "sha256:77a3299119af881904cd5ecd1ac6a66214b6e9bed1f2db16993b54adede64094"}, - {file = "Pygments-2.15.0.tar.gz", hash = "sha256:f7e36cffc4c517fbc252861b9a6e4644ca0e5abadf9a113c72d1358ad09b9500"}, + {file = "Pygments-2.15.1-py3-none-any.whl", hash = "sha256:db2db3deb4b4179f399a09054b023b6a586b76499d36965813c71aa8ed7b5fd1"}, + {file = "Pygments-2.15.1.tar.gz", hash = "sha256:8ace4d3c1dd481894b2005f560ead0f9f19ee64fe983366be1a21e171d12775c"}, ] [package.extras] diff --git a/pyproject.toml b/pyproject.toml index 07a06d31c90..574c60b31a1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,6 +12,7 @@ classifiers=[ "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", ] repository = "https://github.com/awslabs/aws-lambda-powertools-python" documentation = "https://awslabs.github.io/aws-lambda-powertools-python/" From 5e9049d38132a80a3fd32d5486ff43e114948278 Mon Sep 17 00:00:00 2001 From: Leandro Damascena Date: Wed, 19 Apr 2023 20:55:40 +0100 Subject: [PATCH 053/100] feat(event_sources): add queue_url field in SQS EventSource DataClass (#2146) --- .../utilities/data_classes/sqs_event.py | 12 ++++++++++++ tests/functional/test_data_classes.py | 1 + 2 files changed, 13 insertions(+) diff --git a/aws_lambda_powertools/utilities/data_classes/sqs_event.py b/aws_lambda_powertools/utilities/data_classes/sqs_event.py index 1b93a775bca..7d0dbe49352 100644 --- a/aws_lambda_powertools/utilities/data_classes/sqs_event.py +++ b/aws_lambda_powertools/utilities/data_classes/sqs_event.py @@ -133,6 +133,18 @@ def aws_region(self) -> str: """aws region eg: us-east-1""" return self["awsRegion"] + @property + def queue_url(self) -> str: + """The URL of the queue.""" + arn_parts = self["eventSourceARN"].split(":") + region = arn_parts[3] + account_id = arn_parts[4] + queue_name = arn_parts[5] + + queue_url = f"https://sqs.{region}.amazonaws.com/{account_id}/{queue_name}" + + return queue_url + class SQSEvent(DictWrapper): """SQS Event diff --git a/tests/functional/test_data_classes.py b/tests/functional/test_data_classes.py index 5e2aad30e8e..37b934d478e 100644 --- a/tests/functional/test_data_classes.py +++ b/tests/functional/test_data_classes.py @@ -779,6 +779,7 @@ def test_seq_trigger_event(): assert record.md5_of_body == "e4e68fb7bd0e697a0ae8f1bb342846b3" assert record.event_source == "aws:sqs" assert record.event_source_arn == "arn:aws:sqs:us-east-2:123456789012:my-queue" + assert record.queue_url == "https://sqs.us-east-2.amazonaws.com/123456789012/my-queue" assert record.aws_region == "us-east-2" From 45b98b0a02e91c4b220e698dd912e26006b609c6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 19 Apr 2023 20:59:46 +0000 Subject: [PATCH 054/100] chore(deps-dev): bump mypy-boto3-secretsmanager from 1.26.89 to 1.26.116 (#2147) Bumps [mypy-boto3-secretsmanager](https://github.com/youtype/mypy_boto3_builder) from 1.26.89 to 1.26.116. - [Release notes](https://github.com/youtype/mypy_boto3_builder/releases) - [Commits](https://github.com/youtype/mypy_boto3_builder/commits) --- updated-dependencies: - dependency-name: mypy-boto3-secretsmanager dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 12 ++++++------ pyproject.toml | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/poetry.lock b/poetry.lock index 1b08afdd42c..2f3dbe77e0a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1795,18 +1795,18 @@ typing-extensions = {version = ">=4.1.0", markers = "python_version < \"3.9\""} [[package]] name = "mypy-boto3-secretsmanager" -version = "1.26.89" -description = "Type annotations for boto3.SecretsManager 1.26.89 service generated with mypy-boto3-builder 7.12.5" +version = "1.26.116" +description = "Type annotations for boto3.SecretsManager 1.26.116 service generated with mypy-boto3-builder 7.14.5" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "mypy-boto3-secretsmanager-1.26.89.tar.gz", hash = "sha256:4e08ec1ae81229fb20e16af40004923f86f6fe119fa7730edb289cd851fa9e55"}, - {file = "mypy_boto3_secretsmanager-1.26.89-py3-none-any.whl", hash = "sha256:b3f008770ef9c580ebf24b9942ced350d0842e58aa8500fadb80925c0dabe9b5"}, + {file = "mypy-boto3-secretsmanager-1.26.116.tar.gz", hash = "sha256:d95bbef7fdd39876fe42799ed15abd83eee80b612734bd83513b8ce720e7ceec"}, + {file = "mypy_boto3_secretsmanager-1.26.116-py3-none-any.whl", hash = "sha256:3d2f4c42945447e6abdd18289c159a8d5b0e45ccc32067915863e93e38cd9c49"}, ] [package.dependencies] -typing-extensions = ">=4.1.0" +typing-extensions = {version = ">=4.1.0", markers = "python_version < \"3.9\""} [[package]] name = "mypy-boto3-ssm" @@ -3035,4 +3035,4 @@ validation = ["fastjsonschema"] [metadata] lock-version = "2.0" python-versions = "^3.7.4" -content-hash = "49068e0c4f4dd9b22bb9fa199afa60d5b4f10020b602fc5b8e99ac209bbbb239" +content-hash = "f6079cf10d522cf588a46d5a7016f4e3ef37a4ab1fe4bd46bf982dbb1735a6bf" diff --git a/pyproject.toml b/pyproject.toml index 574c60b31a1..815671ebdbc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -76,7 +76,7 @@ mypy-boto3-cloudwatch = "^1.26.99" mypy-boto3-dynamodb = "^1.26.115" mypy-boto3-lambda = "^1.26.115" mypy-boto3-logs = "^1.26.53" -mypy-boto3-secretsmanager = "^1.26.89" +mypy-boto3-secretsmanager = "^1.26.116" mypy-boto3-ssm = "^1.26.97" mypy-boto3-s3 = "^1.26.104" mypy-boto3-xray = "^1.26.11" From d29cd619d517a20a6dd64c87e48aaf718eb51a87 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 19 Apr 2023 22:33:23 +0100 Subject: [PATCH 055/100] chore(deps-dev): bump cfn-lint from 0.77.1 to 0.77.2 (#2148) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 8 ++++---- pyproject.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/poetry.lock b/poetry.lock index 2f3dbe77e0a..57c04585dd3 100644 --- a/poetry.lock +++ b/poetry.lock @@ -370,14 +370,14 @@ files = [ [[package]] name = "cfn-lint" -version = "0.77.1" +version = "0.77.2" description = "Checks CloudFormation templates for practices and behaviour that could potentially be improved" category = "dev" optional = false python-versions = ">=3.7, <=4.0, !=4.0" files = [ - {file = "cfn-lint-0.77.1.tar.gz", hash = "sha256:f2861748ef8ba4bcb9f47bd12ea396f11b0f29ff50ca98fec39de52695544b61"}, - {file = "cfn_lint-0.77.1-py3-none-any.whl", hash = "sha256:19ae30984d3538c14439b39f9488fa0d4ea5d15d2398e011209ae97300228652"}, + {file = "cfn-lint-0.77.2.tar.gz", hash = "sha256:a720fdbd68b7ada0fcef2ee65fc17c67f5dbd03797d9117eee7c18bb2cb49a2c"}, + {file = "cfn_lint-0.77.2-py3-none-any.whl", hash = "sha256:d1b508824ed47d622dee07f270f04a7cbbe05d2230d7bfb10641964e6d65500a"}, ] [package.dependencies] @@ -3035,4 +3035,4 @@ validation = ["fastjsonschema"] [metadata] lock-version = "2.0" python-versions = "^3.7.4" -content-hash = "f6079cf10d522cf588a46d5a7016f4e3ef37a4ab1fe4bd46bf982dbb1735a6bf" +content-hash = "26f0259bd6c37c21db35c42a891a9a381618f153657f79f96cbb95346e2ada37" diff --git a/pyproject.toml b/pyproject.toml index 815671ebdbc..1d859d21dab 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -101,7 +101,7 @@ all = ["pydantic", "aws-xray-sdk", "fastjsonschema"] aws-sdk = ["boto3"] [tool.poetry.group.dev.dependencies] -cfn-lint = "0.77.1" +cfn-lint = "0.77.2" mypy = "^1.1.1" types-python-dateutil = "^2.8.19.6" httpx = ">=0.23.3,<0.25.0" From 4853646d4ea09b465d9fd5abf834aba2fb57a3dd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 19 Apr 2023 22:33:44 +0100 Subject: [PATCH 056/100] chore(deps-dev): bump aws-cdk from 2.75.0 to 2.75.1 (#2150) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 14 +++++++------- package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index ee0c802acc4..eca41a6ef1d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,13 +8,13 @@ "name": "aws-lambda-powertools-python-e2e", "version": "1.0.0", "devDependencies": { - "aws-cdk": "^2.75.0" + "aws-cdk": "^2.75.1" } }, "node_modules/aws-cdk": { - "version": "2.75.0", - "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.75.0.tgz", - "integrity": "sha512-BkyWNpYZz66Ewoi7rBPYZnW+0BAKbWYawhQ1v7KQWmGB0cFlQmvIfoOFklF5EOyAKOltUVRQF6KJf1/AIedkmg==", + "version": "2.75.1", + "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.75.1.tgz", + "integrity": "sha512-LB0pvt3FwHEvljBIczNwvVCrknZ8u/s7CFNaCC6AmpFajwy8BZrbcRL8iKxHKwaWvPULY1bzvsqhHAoE34h4Ow==", "dev": true, "bin": { "cdk": "bin/cdk" @@ -43,9 +43,9 @@ }, "dependencies": { "aws-cdk": { - "version": "2.75.0", - "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.75.0.tgz", - "integrity": "sha512-BkyWNpYZz66Ewoi7rBPYZnW+0BAKbWYawhQ1v7KQWmGB0cFlQmvIfoOFklF5EOyAKOltUVRQF6KJf1/AIedkmg==", + "version": "2.75.1", + "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.75.1.tgz", + "integrity": "sha512-LB0pvt3FwHEvljBIczNwvVCrknZ8u/s7CFNaCC6AmpFajwy8BZrbcRL8iKxHKwaWvPULY1bzvsqhHAoE34h4Ow==", "dev": true, "requires": { "fsevents": "2.3.2" diff --git a/package.json b/package.json index 1d08fc890ac..6d4aa92c887 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,6 @@ "name": "aws-lambda-powertools-python-e2e", "version": "1.0.0", "devDependencies": { - "aws-cdk": "^2.75.0" + "aws-cdk": "^2.75.1" } } From 146d006e4bff44c16f4d70f4b47438a3af18bdd9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 19 Apr 2023 21:36:41 +0000 Subject: [PATCH 057/100] chore(deps-dev): bump mypy-boto3-s3 from 1.26.104 to 1.26.116 (#2149) Bumps [mypy-boto3-s3](https://github.com/youtype/mypy_boto3_builder) from 1.26.104 to 1.26.116. - [Release notes](https://github.com/youtype/mypy_boto3_builder/releases) - [Commits](https://github.com/youtype/mypy_boto3_builder/commits) --- updated-dependencies: - dependency-name: mypy-boto3-s3 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 10 +++++----- pyproject.toml | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/poetry.lock b/poetry.lock index 57c04585dd3..33c837df909 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1780,14 +1780,14 @@ typing-extensions = ">=4.1.0" [[package]] name = "mypy-boto3-s3" -version = "1.26.104" -description = "Type annotations for boto3.S3 1.26.104 service generated with mypy-boto3-builder 7.14.5" +version = "1.26.116" +description = "Type annotations for boto3.S3 1.26.116 service generated with mypy-boto3-builder 7.14.5" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "mypy-boto3-s3-1.26.104.tar.gz", hash = "sha256:a58d342d72d58fefa2ecd24d926dbc92ae8b97205c59c3144d186857d5f30814"}, - {file = "mypy_boto3_s3-1.26.104-py3-none-any.whl", hash = "sha256:24ff5ec193659abb0415925e73787a64631de46e59fd0f261a840e6c0611a38e"}, + {file = "mypy-boto3-s3-1.26.116.tar.gz", hash = "sha256:597aac58bb2c962d166403d0bdc10cdfa62ac82c61b02faf69a461c5a5107087"}, + {file = "mypy_boto3_s3-1.26.116-py3-none-any.whl", hash = "sha256:dcdab86eae381c15b872c020e6b0d01ecaee4092190b60e313fac180b243e66a"}, ] [package.dependencies] @@ -3035,4 +3035,4 @@ validation = ["fastjsonschema"] [metadata] lock-version = "2.0" python-versions = "^3.7.4" -content-hash = "26f0259bd6c37c21db35c42a891a9a381618f153657f79f96cbb95346e2ada37" +content-hash = "d802cb3b02f4b58fb01497d07d26f679cf4ad3df9c0eaaed86cf9b6472453680" diff --git a/pyproject.toml b/pyproject.toml index 1d859d21dab..77041812c71 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -78,7 +78,7 @@ mypy-boto3-lambda = "^1.26.115" mypy-boto3-logs = "^1.26.53" mypy-boto3-secretsmanager = "^1.26.116" mypy-boto3-ssm = "^1.26.97" -mypy-boto3-s3 = "^1.26.104" +mypy-boto3-s3 = "^1.26.116" mypy-boto3-xray = "^1.26.11" types-requests = "^2.28.11" typing-extensions = "^4.4.0" From 6d466f4b07762ae5ed8bca8787e2a733d0598240 Mon Sep 17 00:00:00 2001 From: Ruben Fonseca Date: Thu, 20 Apr 2023 15:34:00 +0200 Subject: [PATCH 058/100] fix(e2e): fix test brittleness (#2152) --- tests/e2e/idempotency/test_idempotency_dynamodb.py | 3 ++- tests/e2e/streaming/handlers/s3_object_handler.py | 8 +++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/tests/e2e/idempotency/test_idempotency_dynamodb.py b/tests/e2e/idempotency/test_idempotency_dynamodb.py index 06147227549..31382ff9050 100644 --- a/tests/e2e/idempotency/test_idempotency_dynamodb.py +++ b/tests/e2e/idempotency/test_idempotency_dynamodb.py @@ -130,4 +130,5 @@ def test_idempotent_function_thread_safety(function_thread_safety_handler_fn_arn assert function_thread["exception"] is None assert function_thread["output"] is not None - assert first_execution_response == second_execution_response + # we use set() here because we want to compare the elements regardless of their order in the array + assert set(first_execution_response) == set(second_execution_response) diff --git a/tests/e2e/streaming/handlers/s3_object_handler.py b/tests/e2e/streaming/handlers/s3_object_handler.py index 98bda22c2bb..3c47f4ab3b7 100644 --- a/tests/e2e/streaming/handlers/s3_object_handler.py +++ b/tests/e2e/streaming/handlers/s3_object_handler.py @@ -66,13 +66,15 @@ def lambda_handler(event, context): if transform_zip or transform_zip_lzma: response["manifest"] = obj.namelist() - response["body"] = obj.read(obj.namelist()[1]).rstrip() # extracts the second file on the zip + response["body"] = ( + obj.read(obj.namelist()[1]).rstrip().decode("utf-8") + ) # extracts the second file on the zip elif transform_csv or csv: response["body"] = obj.__next__() elif transform_gzip or gunzip: - response["body"] = obj.readline().rstrip() + response["body"] = obj.readline().rstrip().decode("utf-8") else: - response["body"] = obj.readline().rstrip() + response["body"] = obj.readline().rstrip().decode("utf-8") except botocore.exceptions.ClientError as e: if e.response["Error"]["Code"] == "404": response["error"] = "Not found" From c24951447b0a7d5c7eef71d95bc06fc3db80050d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 21 Apr 2023 09:47:52 +0200 Subject: [PATCH 059/100] chore(deps): bump codecov/codecov-action from 3.1.2 to 3.1.3 (#2153) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/python_build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python_build.yml b/.github/workflows/python_build.yml index b126c285918..5daf9d5c2d3 100644 --- a/.github/workflows/python_build.yml +++ b/.github/workflows/python_build.yml @@ -53,7 +53,7 @@ jobs: - name: Complexity baseline run: make complexity-baseline - name: Upload coverage to Codecov - uses: codecov/codecov-action@40a12dcee2df644d47232dde008099a3e9e4f865 # 3.1.2 + uses: codecov/codecov-action@894ff025c7b54547a9a2a1e9f228beae737ad3c2 # 3.1.3 with: file: ./coverage.xml env_vars: PYTHON From 73acf3c100cbbbbc9fb33844998113c16a50a90f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 21 Apr 2023 09:48:07 +0200 Subject: [PATCH 060/100] chore(deps-dev): bump aws-cdk from 2.75.1 to 2.76.0 (#2154) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 14 +++++++------- package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index eca41a6ef1d..a206f7a7b7b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,13 +8,13 @@ "name": "aws-lambda-powertools-python-e2e", "version": "1.0.0", "devDependencies": { - "aws-cdk": "^2.75.1" + "aws-cdk": "^2.76.0" } }, "node_modules/aws-cdk": { - "version": "2.75.1", - "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.75.1.tgz", - "integrity": "sha512-LB0pvt3FwHEvljBIczNwvVCrknZ8u/s7CFNaCC6AmpFajwy8BZrbcRL8iKxHKwaWvPULY1bzvsqhHAoE34h4Ow==", + "version": "2.76.0", + "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.76.0.tgz", + "integrity": "sha512-y6VHtqUpYenn6mGIBFbcGGXIoXfKA3o0eGL/eeD/gUJ9TcPrgMLQM1NxSMb5JVsOk5BPPXzGmvB0gBu40utGqg==", "dev": true, "bin": { "cdk": "bin/cdk" @@ -43,9 +43,9 @@ }, "dependencies": { "aws-cdk": { - "version": "2.75.1", - "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.75.1.tgz", - "integrity": "sha512-LB0pvt3FwHEvljBIczNwvVCrknZ8u/s7CFNaCC6AmpFajwy8BZrbcRL8iKxHKwaWvPULY1bzvsqhHAoE34h4Ow==", + "version": "2.76.0", + "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.76.0.tgz", + "integrity": "sha512-y6VHtqUpYenn6mGIBFbcGGXIoXfKA3o0eGL/eeD/gUJ9TcPrgMLQM1NxSMb5JVsOk5BPPXzGmvB0gBu40utGqg==", "dev": true, "requires": { "fsevents": "2.3.2" diff --git a/package.json b/package.json index 6d4aa92c887..9536d277acb 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,6 @@ "name": "aws-lambda-powertools-python-e2e", "version": "1.0.0", "devDependencies": { - "aws-cdk": "^2.75.1" + "aws-cdk": "^2.76.0" } } From d00425fe0c82d9a6e3e78c4d4f9ef5fd4d3b6f2e Mon Sep 17 00:00:00 2001 From: Heitor Lessa Date: Fri, 21 Apr 2023 13:52:56 +0200 Subject: [PATCH 061/100] chore(batch): safeguard custom use of BatchProcessingError exception (#2155) --- aws_lambda_powertools/utilities/batch/exceptions.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/aws_lambda_powertools/utilities/batch/exceptions.py b/aws_lambda_powertools/utilities/batch/exceptions.py index d541d18d18f..89659e42bf8 100644 --- a/aws_lambda_powertools/utilities/batch/exceptions.py +++ b/aws_lambda_powertools/utilities/batch/exceptions.py @@ -1,6 +1,8 @@ """ Batch processing exceptions """ +from __future__ import annotations + import traceback from types import TracebackType from typing import List, Optional, Tuple, Type @@ -9,10 +11,10 @@ class BaseBatchProcessingError(Exception): - def __init__(self, msg="", child_exceptions: Optional[List[ExceptionInfo]] = None): + def __init__(self, msg="", child_exceptions: List[ExceptionInfo] | None = None): super().__init__(msg) self.msg = msg - self.child_exceptions = child_exceptions + self.child_exceptions = child_exceptions or [] def format_exceptions(self, parent_exception_str): exception_list = [f"{parent_exception_str}\n"] @@ -27,7 +29,7 @@ def format_exceptions(self, parent_exception_str): class BatchProcessingError(BaseBatchProcessingError): """When all batch records failed to be processed""" - def __init__(self, msg="", child_exceptions: Optional[List[ExceptionInfo]] = None): + def __init__(self, msg="", child_exceptions: List[ExceptionInfo] | None = None): super().__init__(msg, child_exceptions) def __str__(self): From cd5e1c6df4d2496219d80e9c7d041cef0f388103 Mon Sep 17 00:00:00 2001 From: walmsles <2704782+walmsles@users.noreply.github.com> Date: Fri, 21 Apr 2023 23:00:39 +1000 Subject: [PATCH 062/100] fix(batch): resolve use of ValidationError in batch (#2157) Co-authored-by: heitorlessa --- aws_lambda_powertools/utilities/batch/base.py | 25 +++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/aws_lambda_powertools/utilities/batch/base.py b/aws_lambda_powertools/utilities/batch/base.py index 210caf2bb14..c2c91708272 100644 --- a/aws_lambda_powertools/utilities/batch/base.py +++ b/aws_lambda_powertools/utilities/batch/base.py @@ -26,7 +26,6 @@ KinesisStreamRecord, ) from aws_lambda_powertools.utilities.data_classes.sqs_event import SQSRecord -from aws_lambda_powertools.utilities.parser import ValidationError from aws_lambda_powertools.utilities.typing import LambdaContext logger = logging.getLogger(__name__) @@ -496,9 +495,15 @@ def _process_record(self, record: dict) -> Union[SuccessResponse, FailureRespons result = self.handler(record=data) return self.success_handler(record=record, result=result) - except ValidationError: - return self._register_model_validation_error_record(record) - except Exception: + except Exception as exc: + # NOTE: Pydantic is an optional dependency, but when used and a poison pill scenario happens + # we need to handle that exception differently. + # We check for a public attr in validation errors coming from Pydantic exceptions (subclass or not) + # and we compare if it's coming from the same model that trigger the exception in the first place + model = getattr(exc, "model", None) + if model == self.model: + return self._register_model_validation_error_record(record) + return self.failure_handler(record=data, exception=sys.exc_info()) @@ -634,7 +639,13 @@ async def _async_process_record(self, record: dict) -> Union[SuccessResponse, Fa result = await self.handler(record=data) return self.success_handler(record=record, result=result) - except ValidationError: - return self._register_model_validation_error_record(record) - except Exception: + except Exception as exc: + # NOTE: Pydantic is an optional dependency, but when used and a poison pill scenario happens + # we need to handle that exception differently. + # We check for a public attr in validation errors coming from Pydantic exceptions (subclass or not) + # and we compare if it's coming from the same model that trigger the exception in the first place + model = getattr(exc, "model", None) + if model == self.model: + return self._register_model_validation_error_record(record) + return self.failure_handler(record=data, exception=sys.exc_info()) From 3e87bcf1cfbc22a126c80b8b5e6b09dae8e6e839 Mon Sep 17 00:00:00 2001 From: Release bot Date: Fri, 21 Apr 2023 13:09:21 +0000 Subject: [PATCH 063/100] bump version to 2.14.1 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 77041812c71..1ee2845cdd1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "aws_lambda_powertools" -version = "2.14.0" +version = "2.14.1" description = "AWS Lambda Powertools is a developer toolkit to implement Serverless best practices and increase developer velocity." authors = ["Amazon Web Services"] include = ["aws_lambda_powertools/py.typed", "THIRD-PARTY-LICENSES"] From 0c16011a1c0486d3a9fcff16c283e465b0f3ffcd Mon Sep 17 00:00:00 2001 From: Release bot Date: Fri, 21 Apr 2023 13:09:39 +0000 Subject: [PATCH 064/100] update changelog with latest changes --- CHANGELOG.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0dce26ef95d..aaec15e4ed9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,34 @@ # Unreleased +## Bug Fixes + +* **batch:** resolve use of ValidationError in batch ([#2157](https://github.com/awslabs/aws-lambda-powertools-python/issues/2157)) +* **e2e:** fix test brittleness ([#2152](https://github.com/awslabs/aws-lambda-powertools-python/issues/2152)) + +## Documentation + +* **readme:** update python version badge to 3.10 + +## Features + +* **event_sources:** add queue_url field in SQS EventSource DataClass ([#2146](https://github.com/awslabs/aws-lambda-powertools-python/issues/2146)) + +## Maintenance + +* add Python 3.10 PyPi language classifier ([#2144](https://github.com/awslabs/aws-lambda-powertools-python/issues/2144)) +* update v2 layer ARN on documentation +* **batch:** safeguard custom use of BatchProcessingError exception ([#2155](https://github.com/awslabs/aws-lambda-powertools-python/issues/2155)) +* **deps:** bump codecov/codecov-action from 3.1.2 to 3.1.3 ([#2153](https://github.com/awslabs/aws-lambda-powertools-python/issues/2153)) +* **deps:** bump dependabot/fetch-metadata from 1.3.6 to 1.4.0 ([#2140](https://github.com/awslabs/aws-lambda-powertools-python/issues/2140)) +* **deps-dev:** bump aws-cdk from 2.75.0 to 2.75.1 ([#2150](https://github.com/awslabs/aws-lambda-powertools-python/issues/2150)) +* **deps-dev:** bump mypy-boto3-secretsmanager from 1.26.89 to 1.26.116 ([#2147](https://github.com/awslabs/aws-lambda-powertools-python/issues/2147)) +* **deps-dev:** bump aws-cdk from 2.75.1 to 2.76.0 ([#2154](https://github.com/awslabs/aws-lambda-powertools-python/issues/2154)) +* **deps-dev:** bump importlib-metadata from 6.4.1 to 6.5.0 ([#2141](https://github.com/awslabs/aws-lambda-powertools-python/issues/2141)) +* **deps-dev:** bump mypy-boto3-s3 from 1.26.104 to 1.26.116 ([#2149](https://github.com/awslabs/aws-lambda-powertools-python/issues/2149)) +* **deps-dev:** bump filelock from 3.11.0 to 3.12.0 ([#2142](https://github.com/awslabs/aws-lambda-powertools-python/issues/2142)) +* **deps-dev:** bump cfn-lint from 0.77.1 to 0.77.2 ([#2148](https://github.com/awslabs/aws-lambda-powertools-python/issues/2148)) + ## [v2.14.0] - 2023-04-18 From 49bd097e21eb086936d7ef64562ad49bd2fa9cae Mon Sep 17 00:00:00 2001 From: Release bot Date: Fri, 21 Apr 2023 13:22:32 +0000 Subject: [PATCH 065/100] chore: update v2 layer ARN on documentation --- docs/index.md | 128 ++++++++++++++--------------- examples/logger/sam/template.yaml | 2 +- examples/metrics/sam/template.yaml | 2 +- examples/tracer/sam/template.yaml | 2 +- 4 files changed, 67 insertions(+), 67 deletions(-) diff --git a/docs/index.md b/docs/index.md index a1ad0e0f2ad..91a15dc092e 100644 --- a/docs/index.md +++ b/docs/index.md @@ -26,8 +26,8 @@ Powertools is a developer toolkit to implement Serverless best practices and inc You can install Powertools using one of the following options: -* **Lambda Layer (x86_64)**: [**arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:30**](#){: .copyMe}:clipboard: -* **Lambda Layer (arm64)**: [**arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:30**](#){: .copyMe}:clipboard: +* **Lambda Layer (x86_64)**: [**arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:31**](#){: .copyMe}:clipboard: +* **Lambda Layer (arm64)**: [**arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:31**](#){: .copyMe}:clipboard: * **Pip**: **[`pip install "aws-lambda-powertools"`](#){: .copyMe}:clipboard:** ??? question "Using Pip? You might need to install additional dependencies." @@ -78,60 +78,60 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. | Region | Layer ARN | | ---------------- | ---------------------------------------------------------------------------------------------------------- | - | `af-south-1` | [arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:30](#){: .copyMe}:clipboard: | - | `ap-east-1` | [arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:30](#){: .copyMe}:clipboard: | - | `ap-northeast-1` | [arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:30](#){: .copyMe}:clipboard: | - | `ap-northeast-2` | [arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:30](#){: .copyMe}:clipboard: | - | `ap-northeast-3` | [arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:30](#){: .copyMe}:clipboard: | - | `ap-south-1` | [arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:30](#){: .copyMe}:clipboard: | - | `ap-south-2` | [arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:30](#){: .copyMe}:clipboard: | - | `ap-southeast-1` | [arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:30](#){: .copyMe}:clipboard: | - | `ap-southeast-2` | [arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:30](#){: .copyMe}:clipboard: | - | `ap-southeast-3` | [arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:30](#){: .copyMe}:clipboard: | - | `ap-southeast-4` | [arn:aws:lambda:ap-southeast-4:017000801446:layer:AWSLambdaPowertoolsPythonV2:30](#){: .copyMe}:clipboard: | - | `ca-central-1` | [arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:30](#){: .copyMe}:clipboard: | - | `eu-central-1` | [arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:30](#){: .copyMe}:clipboard: | - | `eu-central-2` | [arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:30](#){: .copyMe}:clipboard: | - | `eu-north-1` | [arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:30](#){: .copyMe}:clipboard: | - | `eu-south-1` | [arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:30](#){: .copyMe}:clipboard: | - | `eu-south-2` | [arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:30](#){: .copyMe}:clipboard: | - | `eu-west-1` | [arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:30](#){: .copyMe}:clipboard: | - | `eu-west-2` | [arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:30](#){: .copyMe}:clipboard: | - | `eu-west-3` | [arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:30](#){: .copyMe}:clipboard: | - | `me-central-1` | [arn:aws:lambda:me-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:30](#){: .copyMe}:clipboard: | - | `me-south-1` | [arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:30](#){: .copyMe}:clipboard: | - | `sa-east-1` | [arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:30](#){: .copyMe}:clipboard: | - | `us-east-1` | [arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:30](#){: .copyMe}:clipboard: | - | `us-east-2` | [arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:30](#){: .copyMe}:clipboard: | - | `us-west-1` | [arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:30](#){: .copyMe}:clipboard: | - | `us-west-2` | [arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:30](#){: .copyMe}:clipboard: | + | `af-south-1` | [arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:31](#){: .copyMe}:clipboard: | + | `ap-east-1` | [arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:31](#){: .copyMe}:clipboard: | + | `ap-northeast-1` | [arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:31](#){: .copyMe}:clipboard: | + | `ap-northeast-2` | [arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:31](#){: .copyMe}:clipboard: | + | `ap-northeast-3` | [arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:31](#){: .copyMe}:clipboard: | + | `ap-south-1` | [arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:31](#){: .copyMe}:clipboard: | + | `ap-south-2` | [arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:31](#){: .copyMe}:clipboard: | + | `ap-southeast-1` | [arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:31](#){: .copyMe}:clipboard: | + | `ap-southeast-2` | [arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:31](#){: .copyMe}:clipboard: | + | `ap-southeast-3` | [arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:31](#){: .copyMe}:clipboard: | + | `ap-southeast-4` | [arn:aws:lambda:ap-southeast-4:017000801446:layer:AWSLambdaPowertoolsPythonV2:31](#){: .copyMe}:clipboard: | + | `ca-central-1` | [arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:31](#){: .copyMe}:clipboard: | + | `eu-central-1` | [arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:31](#){: .copyMe}:clipboard: | + | `eu-central-2` | [arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:31](#){: .copyMe}:clipboard: | + | `eu-north-1` | [arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:31](#){: .copyMe}:clipboard: | + | `eu-south-1` | [arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:31](#){: .copyMe}:clipboard: | + | `eu-south-2` | [arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:31](#){: .copyMe}:clipboard: | + | `eu-west-1` | [arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:31](#){: .copyMe}:clipboard: | + | `eu-west-2` | [arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:31](#){: .copyMe}:clipboard: | + | `eu-west-3` | [arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:31](#){: .copyMe}:clipboard: | + | `me-central-1` | [arn:aws:lambda:me-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:31](#){: .copyMe}:clipboard: | + | `me-south-1` | [arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:31](#){: .copyMe}:clipboard: | + | `sa-east-1` | [arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:31](#){: .copyMe}:clipboard: | + | `us-east-1` | [arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:31](#){: .copyMe}:clipboard: | + | `us-east-2` | [arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:31](#){: .copyMe}:clipboard: | + | `us-west-1` | [arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:31](#){: .copyMe}:clipboard: | + | `us-west-2` | [arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:31](#){: .copyMe}:clipboard: | === "arm64" | Region | Layer ARN | | ---------------- | ---------------------------------------------------------------------------------------------------------------- | - | `af-south-1` | [arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:30](#){: .copyMe}:clipboard: | - | `ap-east-1` | [arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:30](#){: .copyMe}:clipboard: | - | `ap-northeast-1` | [arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:30](#){: .copyMe}:clipboard: | - | `ap-northeast-2` | [arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:30](#){: .copyMe}:clipboard: | - | `ap-northeast-3` | [arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:30](#){: .copyMe}:clipboard: | - | `ap-south-1` | [arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:30](#){: .copyMe}:clipboard: | - | `ap-southeast-1` | [arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:30](#){: .copyMe}:clipboard: | - | `ap-southeast-2` | [arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:30](#){: .copyMe}:clipboard: | - | `ap-southeast-3` | [arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:30](#){: .copyMe}:clipboard: | - | `ca-central-1` | [arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:30](#){: .copyMe}:clipboard: | - | `eu-central-1` | [arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:30](#){: .copyMe}:clipboard: | - | `eu-north-1` | [arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:30](#){: .copyMe}:clipboard: | - | `eu-south-1` | [arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:30](#){: .copyMe}:clipboard: | - | `eu-west-1` | [arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:30](#){: .copyMe}:clipboard: | - | `eu-west-2` | [arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:30](#){: .copyMe}:clipboard: | - | `eu-west-3` | [arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:30](#){: .copyMe}:clipboard: | - | `me-south-1` | [arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:30](#){: .copyMe}:clipboard: | - | `sa-east-1` | [arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:30](#){: .copyMe}:clipboard: | - | `us-east-1` | [arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:30](#){: .copyMe}:clipboard: | - | `us-east-2` | [arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:30](#){: .copyMe}:clipboard: | - | `us-west-1` | [arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:30](#){: .copyMe}:clipboard: | - | `us-west-2` | [arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:30](#){: .copyMe}:clipboard: | + | `af-south-1` | [arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:31](#){: .copyMe}:clipboard: | + | `ap-east-1` | [arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:31](#){: .copyMe}:clipboard: | + | `ap-northeast-1` | [arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:31](#){: .copyMe}:clipboard: | + | `ap-northeast-2` | [arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:31](#){: .copyMe}:clipboard: | + | `ap-northeast-3` | [arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:31](#){: .copyMe}:clipboard: | + | `ap-south-1` | [arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:31](#){: .copyMe}:clipboard: | + | `ap-southeast-1` | [arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:31](#){: .copyMe}:clipboard: | + | `ap-southeast-2` | [arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:31](#){: .copyMe}:clipboard: | + | `ap-southeast-3` | [arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:31](#){: .copyMe}:clipboard: | + | `ca-central-1` | [arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:31](#){: .copyMe}:clipboard: | + | `eu-central-1` | [arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:31](#){: .copyMe}:clipboard: | + | `eu-north-1` | [arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:31](#){: .copyMe}:clipboard: | + | `eu-south-1` | [arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:31](#){: .copyMe}:clipboard: | + | `eu-west-1` | [arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:31](#){: .copyMe}:clipboard: | + | `eu-west-2` | [arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:31](#){: .copyMe}:clipboard: | + | `eu-west-3` | [arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:31](#){: .copyMe}:clipboard: | + | `me-south-1` | [arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:31](#){: .copyMe}:clipboard: | + | `sa-east-1` | [arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:31](#){: .copyMe}:clipboard: | + | `us-east-1` | [arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:31](#){: .copyMe}:clipboard: | + | `us-east-2` | [arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:31](#){: .copyMe}:clipboard: | + | `us-west-1` | [arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:31](#){: .copyMe}:clipboard: | + | `us-west-2` | [arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:31](#){: .copyMe}:clipboard: | ??? note "Note: Click to expand and copy code snippets for popular frameworks" @@ -144,7 +144,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. Type: AWS::Serverless::Function Properties: Layers: - - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:30 + - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:31 ``` === "Serverless framework" @@ -154,7 +154,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. hello: handler: lambda_function.lambda_handler layers: - - arn:aws:lambda:${aws:region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:30 + - arn:aws:lambda:${aws:region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:31 ``` === "CDK" @@ -170,7 +170,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. powertools_layer = aws_lambda.LayerVersion.from_layer_version_arn( self, id="lambda-powertools", - layer_version_arn=f"arn:aws:lambda:{env.region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:30" + layer_version_arn=f"arn:aws:lambda:{env.region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:31" ) aws_lambda.Function(self, 'sample-app-lambda', @@ -219,7 +219,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. role = aws_iam_role.iam_for_lambda.arn handler = "index.test" runtime = "python3.9" - layers = ["arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:30"] + layers = ["arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:31"] source_code_hash = filebase64sha256("lambda_function_payload.zip") } @@ -272,7 +272,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. ? Do you want to configure advanced settings? Yes ... ? Do you want to enable Lambda layers for this function? Yes - ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:30 + ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:31 ❯ amplify push -y @@ -283,7 +283,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. - Name: ? Which setting do you want to update? Lambda layers configuration ? Do you want to enable Lambda layers for this function? Yes - ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:30 + ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:31 ? Do you want to edit the local lambda function now? No ``` @@ -297,7 +297,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. Properties: Architectures: [arm64] Layers: - - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:30 + - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:31 ``` === "Serverless framework" @@ -308,7 +308,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. handler: lambda_function.lambda_handler architecture: arm64 layers: - - arn:aws:lambda:${aws:region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:30 + - arn:aws:lambda:${aws:region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:31 ``` === "CDK" @@ -324,7 +324,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. powertools_layer = aws_lambda.LayerVersion.from_layer_version_arn( self, id="lambda-powertools", - layer_version_arn=f"arn:aws:lambda:{env.region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:30" + layer_version_arn=f"arn:aws:lambda:{env.region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:31" ) aws_lambda.Function(self, 'sample-app-lambda', @@ -374,7 +374,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. role = aws_iam_role.iam_for_lambda.arn handler = "index.test" runtime = "python3.9" - layers = ["arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:30"] + layers = ["arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:31"] architectures = ["arm64"] source_code_hash = filebase64sha256("lambda_function_payload.zip") @@ -430,7 +430,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. ? Do you want to configure advanced settings? Yes ... ? Do you want to enable Lambda layers for this function? Yes - ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:30 + ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:31 ❯ amplify push -y @@ -441,7 +441,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. - Name: ? Which setting do you want to update? Lambda layers configuration ? Do you want to enable Lambda layers for this function? Yes - ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:30 + ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:31 ? Do you want to edit the local lambda function now? No ``` @@ -449,7 +449,7 @@ You can include Powertools Lambda Layer using [AWS Lambda Console](https://docs. Change {region} to your AWS region, e.g. `eu-west-1` ```bash title="AWS CLI" - aws lambda get-layer-version-by-arn --arn arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:30 --region {region} + aws lambda get-layer-version-by-arn --arn arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:31 --region {region} ``` The pre-signed URL to download this Lambda Layer will be within `Location` key. diff --git a/examples/logger/sam/template.yaml b/examples/logger/sam/template.yaml index 8921b950f6a..546367280d4 100644 --- a/examples/logger/sam/template.yaml +++ b/examples/logger/sam/template.yaml @@ -14,7 +14,7 @@ Globals: Layers: # Find the latest Layer version in the official documentation # https://awslabs.github.io/aws-lambda-powertools-python/latest/#lambda-layer - - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:30 + - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:31 Resources: LoggerLambdaHandlerExample: diff --git a/examples/metrics/sam/template.yaml b/examples/metrics/sam/template.yaml index 4378e9835f7..14bb92be061 100644 --- a/examples/metrics/sam/template.yaml +++ b/examples/metrics/sam/template.yaml @@ -15,7 +15,7 @@ Globals: Layers: # Find the latest Layer version in the official documentation # https://awslabs.github.io/aws-lambda-powertools-python/latest/#lambda-layer - - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:30 + - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:31 Resources: CaptureLambdaHandlerExample: diff --git a/examples/tracer/sam/template.yaml b/examples/tracer/sam/template.yaml index 0cf1ddbb4e8..53f4277967a 100644 --- a/examples/tracer/sam/template.yaml +++ b/examples/tracer/sam/template.yaml @@ -13,7 +13,7 @@ Globals: Layers: # Find the latest Layer version in the official documentation # https://awslabs.github.io/aws-lambda-powertools-python/latest/#lambda-layer - - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:30 + - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:31 Resources: CaptureLambdaHandlerExample: From d835329bd66a51bc01d58f57e8431d1590f450db Mon Sep 17 00:00:00 2001 From: Ruben Fonseca Date: Fri, 21 Apr 2023 16:31:31 +0200 Subject: [PATCH 066/100] chore: add dummy reusable dispatch analytics job --- .github/workflows/reusable_dispatch_analytics.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 .github/workflows/reusable_dispatch_analytics.yml diff --git a/.github/workflows/reusable_dispatch_analytics.yml b/.github/workflows/reusable_dispatch_analytics.yml new file mode 100644 index 00000000000..312fb991109 --- /dev/null +++ b/.github/workflows/reusable_dispatch_analytics.yml @@ -0,0 +1,12 @@ +name: Reusable dispatch analytics + +on: + workflow_call: + +jobs: + dispatch_token: + concurrency: + group: analytics + runs-on: ubuntu-latest + steps: + - run: echo 'hello world' From 1a2d43a4823deb934854f0c77fedb3d345ccec83 Mon Sep 17 00:00:00 2001 From: Ruben Fonseca Date: Fri, 21 Apr 2023 16:32:34 +0200 Subject: [PATCH 067/100] fix: typo --- .github/workflows/reusable_dispatch_analytics.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/reusable_dispatch_analytics.yml b/.github/workflows/reusable_dispatch_analytics.yml index 312fb991109..97e16fd2bdf 100644 --- a/.github/workflows/reusable_dispatch_analytics.yml +++ b/.github/workflows/reusable_dispatch_analytics.yml @@ -1,7 +1,7 @@ name: Reusable dispatch analytics on: - workflow_call: + workflow_dispatch: jobs: dispatch_token: From 625b40af591c93a5f81de1179744e3c232d13221 Mon Sep 17 00:00:00 2001 From: Ruben Fonseca Date: Mon, 24 Apr 2023 21:25:39 +0200 Subject: [PATCH 068/100] feat(ci): dispatch GitHub analytics action (#2161) --- .github/workflows/dispatch_analytics.yml | 43 +++++++++++++++++++ .../workflows/reusable_dispatch_analytics.yml | 12 ------ 2 files changed, 43 insertions(+), 12 deletions(-) create mode 100644 .github/workflows/dispatch_analytics.yml delete mode 100644 .github/workflows/reusable_dispatch_analytics.yml diff --git a/.github/workflows/dispatch_analytics.yml b/.github/workflows/dispatch_analytics.yml new file mode 100644 index 00000000000..49a276f6f61 --- /dev/null +++ b/.github/workflows/dispatch_analytics.yml @@ -0,0 +1,43 @@ +name: Dispatch analytics + +on: + workflow_dispatch: + + schedule: + - cron: '0 * * * *' + +permissions: + id-token: write + actions: read + checks: read + contents: read + deployments: read + issues: read + discussions: read + packages: read + pages: read + pull-requests: read + repository-projects: read + security-events: read + statuses: read + +jobs: + dispatch_token: + concurrency: + group: analytics + runs-on: ubuntu-latest + environment: analytics + steps: + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@e1e17a757e536f70e52b5a12b2e8d1d1c60e04ef + with: + aws-region: eu-central-1 + role-to-assume: ${{ secrets.AWS_ANALYTICS_ROLE_ARN }} + + - name: Invoke Lambda function + run: | + payload=$(echo -n '{"githubToken": "${{ secrets.GITHUB_TOKEN }}"}' | base64) + aws lambda invoke \ + --function-name ${{ secrets.AWS_ANALYTICS_DISPATCHER_ARN }} \ + --payload "$payload" response.json + cat response.json diff --git a/.github/workflows/reusable_dispatch_analytics.yml b/.github/workflows/reusable_dispatch_analytics.yml deleted file mode 100644 index 97e16fd2bdf..00000000000 --- a/.github/workflows/reusable_dispatch_analytics.yml +++ /dev/null @@ -1,12 +0,0 @@ -name: Reusable dispatch analytics - -on: - workflow_dispatch: - -jobs: - dispatch_token: - concurrency: - group: analytics - runs-on: ubuntu-latest - steps: - - run: echo 'hello world' From 6027aae931a59bc2389869d62d9de6665c9cbf5a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Apr 2023 22:34:02 +0100 Subject: [PATCH 069/100] chore(deps-dev): bump importlib-metadata from 6.5.0 to 6.6.0 (#2163) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 8 ++++---- pyproject.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/poetry.lock b/poetry.lock index 33c837df909..3c866babcaf 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1091,14 +1091,14 @@ files = [ [[package]] name = "importlib-metadata" -version = "6.5.0" +version = "6.6.0" description = "Read metadata from Python packages" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "importlib_metadata-6.5.0-py3-none-any.whl", hash = "sha256:03ba783c3a2c69d751b109fc0c94a62c51f581b3d6acf8ed1331b6d5729321ff"}, - {file = "importlib_metadata-6.5.0.tar.gz", hash = "sha256:7a8bdf1bc3a726297f5cfbc999e6e7ff6b4fa41b26bba4afc580448624460045"}, + {file = "importlib_metadata-6.6.0-py3-none-any.whl", hash = "sha256:43dd286a2cd8995d5eaef7fee2066340423b818ed3fd70adf0bad5f1fac53fed"}, + {file = "importlib_metadata-6.6.0.tar.gz", hash = "sha256:92501cdf9cc66ebd3e612f1b4f0c0765dfa42f0fa38ffb319b6bd84dd675d705"}, ] [package.dependencies] @@ -3035,4 +3035,4 @@ validation = ["fastjsonschema"] [metadata] lock-version = "2.0" python-versions = "^3.7.4" -content-hash = "d802cb3b02f4b58fb01497d07d26f679cf4ad3df9c0eaaed86cf9b6472453680" +content-hash = "8c58cc3cfc48a96a63d86c8154aa19257dfe3a8614d6385bc36245af28ae8011" diff --git a/pyproject.toml b/pyproject.toml index 1ee2845cdd1..dbe596b23b6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -86,7 +86,7 @@ mkdocs-material = "^9.1.6" filelock = "^3.12.0" checksumdir = "^1.2.0" mypy-boto3-appconfigdata = "^1.26.70" -importlib-metadata = "^6.5" +importlib-metadata = "^6.6" ijson = "^3.2.0" typed-ast = { version = "^1.5.4", python = "< 3.8"} hvac = "^1.1.0" From 84f075459bb784ac40f5921c9bcf75071b3c88b0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Apr 2023 22:47:22 +0100 Subject: [PATCH 070/100] chore(deps-dev): bump mkdocs-material from 9.1.6 to 9.1.8 (#2162) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 8 ++++---- pyproject.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/poetry.lock b/poetry.lock index 3c866babcaf..c877e758a2e 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1574,14 +1574,14 @@ mkdocs = ">=0.17" [[package]] name = "mkdocs-material" -version = "9.1.6" +version = "9.1.8" description = "Documentation that simply works" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "mkdocs_material-9.1.6-py3-none-any.whl", hash = "sha256:f2eb1d40db89da9922944833c1387207408f8937e1c2b46ab86e0c8f170b71e0"}, - {file = "mkdocs_material-9.1.6.tar.gz", hash = "sha256:2e555152f9771646bfa62dc78a86052876183eff69ce30db03a33e85702b21fc"}, + {file = "mkdocs_material-9.1.8-py3-none-any.whl", hash = "sha256:ac76e31bf52b2742c08a9d6629d64878f32dda5c949cd371082e25106c9be7dd"}, + {file = "mkdocs_material-9.1.8.tar.gz", hash = "sha256:616ef98fc143b3ec8c559e2fec85f32103d2093e9c88333964d93105ea2d670b"}, ] [package.dependencies] @@ -3035,4 +3035,4 @@ validation = ["fastjsonschema"] [metadata] lock-version = "2.0" python-versions = "^3.7.4" -content-hash = "8c58cc3cfc48a96a63d86c8154aa19257dfe3a8614d6385bc36245af28ae8011" +content-hash = "52d4c322f52727590fb17436b95d67abf0bb17c58696d77bd0f82826000f8113" diff --git a/pyproject.toml b/pyproject.toml index dbe596b23b6..607e7c6f09c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -82,7 +82,7 @@ mypy-boto3-s3 = "^1.26.116" mypy-boto3-xray = "^1.26.11" types-requests = "^2.28.11" typing-extensions = "^4.4.0" -mkdocs-material = "^9.1.6" +mkdocs-material = "^9.1.8" filelock = "^3.12.0" checksumdir = "^1.2.0" mypy-boto3-appconfigdata = "^1.26.70" From 45f2a9efc5d984e887b653c785ba183e2465d5a8 Mon Sep 17 00:00:00 2001 From: Leandro Damascena Date: Tue, 25 Apr 2023 12:55:58 +0100 Subject: [PATCH 071/100] docs(homepage): add customer references section (#2159) Co-authored-by: Heitor Lessa --- README.md | 25 +++++++++ docs/index.md | 27 +++++++++- docs/media/logos/cloudzero-logo.png | Bin 0 -> 176734 bytes docs/media/logos/cpqi.png | Bin 0 -> 7967 bytes docs/media/logos/cyberark-logo-dark.svg | 56 +++++++++++++++++++ docs/media/logos/globaldatanet.png | Bin 0 -> 4083 bytes docs/media/logos/ims-logo.png | Bin 0 -> 14094 bytes docs/media/logos/propellor-ai.png | Bin 0 -> 8063 bytes docs/media/logos/topsport.svg | 68 ++++++++++++++++++++++++ docs/media/logos/trek10-logo.jpeg | Bin 0 -> 362914 bytes 10 files changed, 175 insertions(+), 1 deletion(-) create mode 100644 docs/media/logos/cloudzero-logo.png create mode 100644 docs/media/logos/cpqi.png create mode 100644 docs/media/logos/cyberark-logo-dark.svg create mode 100644 docs/media/logos/globaldatanet.png create mode 100644 docs/media/logos/ims-logo.png create mode 100644 docs/media/logos/propellor-ai.png create mode 100644 docs/media/logos/topsport.svg create mode 100644 docs/media/logos/trek10-logo.jpeg diff --git a/README.md b/README.md index b79f43a85f3..310c267af6e 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,31 @@ With [pip](https://pip.pypa.io/en/latest/index.html) installed, run: ``pip insta * [Serverless E-commerce platform](https://github.com/aws-samples/aws-serverless-ecommerce-platform) * [Serverless GraphQL Nanny Booking Api](https://github.com/trey-rosius/babysitter_api) +## How to support AWS Lambda Powertools for Python? + +### Becoming a reference customer + +Knowing which companies are using this library is important to help prioritize the project internally. If your company is using AWS Lambda Powertools for Python, you can request to have your name and logo added to the README file by raising a [Support Lambda Powertools (become a reference)](https://github.com/awslabs/aws-lambda-powertools-python/issues/new?assignees=&labels=customer-reference&template=support_powertools.yml&title=%5BSupport+Lambda+Powertools%5D%3A+%3Cyour+organization+name%3E) issue. + +The following companies, among others, use Powertools: + +* [CPQi (Exadel Financial Services)](https://cpqi.com/) +* [CloudZero](https://www.cloudzero.com/) +* [CyberArk](https://www.cyberark.com/) +* [globaldatanet](https://globaldatanet.com/) +* [IMS](https://ims.tech/) +* [Propellor.ai](https://www.propellor.ai/) +* [TopSport](https://www.topsport.com.au/) +* [Trek10](https://www.trek10.com/) + +### Sharing your work + +Share what you did with Powertools 💞💞. Blog post, workshops, presentation, sample apps and others. Check out what the community has already shared about Powertools [here](https://awslabs.github.io/aws-lambda-powertools-python/latest/we_made_this/). + +### Using Lambda Layer or SAR + +This helps us understand who uses Powertools in a non-intrusive way, and helps us gain future investments for other Powertools languages. When [using Layers](https://awslabs.github.io/aws-lambda-powertools-python/latest/#lambda-layer), you can add Powertools as a dev dependency (or as part of your virtual env) to not impact the development process. + ## Credits * Structured logging initial implementation from [aws-lambda-logging](https://gitlab.com/hadrien/aws_lambda_logging) diff --git a/docs/index.md b/docs/index.md index 91a15dc092e..d25c9e7caf0 100644 --- a/docs/index.md +++ b/docs/index.md @@ -14,7 +14,7 @@ Powertools is a developer toolkit to implement Serverless best practices and inc You can choose to support us in three ways: - 1) [**Become a reference customers**](https://github.com/awslabs/aws-lambda-powertools-python/issues/new?assignees=&labels=customer-reference&template=support_powertools.yml&title=%5BSupport+Lambda+Powertools%5D%3A+%3Cyour+organization+name%3E). This gives us permission to list your company in our documentation. + 1) [**Become a reference customer**](https://github.com/awslabs/aws-lambda-powertools-python/issues/new?assignees=&labels=customer-reference&template=support_powertools.yml&title=%5BSupport+Lambda+Powertools%5D%3A+%3Cyour+organization+name%3E). This gives us permission to list your company in our documentation. 2) [**Share your work**](https://github.com/awslabs/aws-lambda-powertools-python/issues/new?assignees=&labels=community-content&template=share_your_work.yml&title=%5BI+Made+This%5D%3A+%3CTITLE%3E). Blog posts, video, sample projects you used Powertools! @@ -737,6 +737,31 @@ As a best practice for libraries, Powertools module logging statements are suppr When necessary, you can use `POWERTOOLS_DEBUG` environment variable to enable debugging. This will provide additional information on every internal operation. +## How to support AWS Lambda Powertools for Python? + +### Becoming a reference customer + +Knowing which companies are using this library is important to help prioritize the project internally. If your company is using AWS Lambda Powertools for Python, you can request to have your name and logo added to the README file by raising a [Support Lambda Powertools (become a reference)](https://github.com/awslabs/aws-lambda-powertools-python/issues/new?assignees=&labels=customer-reference&template=support_powertools.yml&title=%5BSupport+Lambda+Powertools%5D%3A+%3Cyour+organization+name%3E){target="_blank"} issue. + +The following companies, among others, use Powertools: + +* [CPQi (Exadel Financial Services)](https://cpqi.com/){target="_blank"} +* [CloudZero](https://www.cloudzero.com/){target="_blank"} +* [CyberArk](https://www.cyberark.com/){target="_blank"} +* [globaldatanet](https://globaldatanet.com/){target="_blank"} +* [IMS](https://ims.tech/){target="_blank"} +* [Propellor.ai](https://www.propellor.ai/){target="_blank"} +* [TopSport](https://www.topsport.com.au/){target="_blank"} +* [Trek10](https://www.trek10.com/){target="_blank"} + +### Sharing your work + +Share what you did with Powertools 💞💞. Blog post, workshops, presentation, sample apps and others. Check out what the community has already shared about Powertools [here](https://awslabs.github.io/aws-lambda-powertools-python/latest/we_made_this/). + +### Using Lambda Layer or SAR + +This helps us understand who uses Powertools in a non-intrusive way, and helps us gain future investments for other Powertools languages. When [using Layers](https://awslabs.github.io/aws-lambda-powertools-python/latest/#lambda-layer), you can add Powertools as a dev dependency (or as part of your virtual env) to not impact the development process. + ## Tenets These are our core principles to guide our decision making. diff --git a/docs/media/logos/cloudzero-logo.png b/docs/media/logos/cloudzero-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..08326a8aaa9afab3a5c6ddf87c3b7e4d9ce8b7c3 GIT binary patch literal 176734 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 VY|xuzdB_4J@d`>kj|` literal 0 HcmV?d00001 diff --git a/docs/media/logos/cpqi.png b/docs/media/logos/cpqi.png new file mode 100644 index 0000000000000000000000000000000000000000..4815fd8fe70797c5722b1e244c24c370cb954c66 GIT binary patch literal 7967 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 am%^4ucuVHBr@-bml8mH+M7fy0&;J32@2k@Q literal 0 HcmV?d00001 diff --git a/docs/media/logos/cyberark-logo-dark.svg b/docs/media/logos/cyberark-logo-dark.svg new file mode 100644 index 00000000000..982087c5ca3 --- /dev/null +++ b/docs/media/logos/cyberark-logo-dark.svg @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/media/logos/globaldatanet.png b/docs/media/logos/globaldatanet.png new file mode 100644 index 0000000000000000000000000000000000000000..d65d33ee35e628e499059bf539563fa0b259f4af GIT binary patch literal 4083 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 literal 0 HcmV?d00001 diff --git a/docs/media/logos/ims-logo.png b/docs/media/logos/ims-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..d8ccd148a675397dbfbbd03cca40483f8d98ae80 GIT binary patch literal 14094 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 literal 0 HcmV?d00001 diff --git a/docs/media/logos/topsport.svg b/docs/media/logos/topsport.svg new file mode 100644 index 00000000000..8e35c7caba7 --- /dev/null +++ b/docs/media/logos/topsport.svg @@ -0,0 +1,68 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/docs/media/logos/trek10-logo.jpeg b/docs/media/logos/trek10-logo.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..98bab568f64f952293342964a6313e0b2b4bd2df GIT binary patch literal 362914 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

1+xiIAwm?+I= z&4C3^VyI1-3qN*cjH@}XQs4pz=VpdclZR$AuhqhO7qKHKsg8;)TIlzBGg^QPq1+!w z5gKO@Q_q|FDAE)tt7!fRs)p6Y6o8Wu;m?``G!n*z9t*sC!!T~E1r?&i8r37ZZH6pD zd?k~EC2%fb9xH9N?jBQ&gOA`Z& z5m~!jUI5nAz$Hs&YDOfB^gxhP(~_m6tVYi7D8SnDry7X_mx)#xVp zY^l`CvmP|n>t(pWu|;p}%$uwzw%Y6DdaVejpily)AS2gFnZ(Abnc@(+EU-Z^EtAz| z(pIcwpk~lk(#+Jj(Tw3$vN86k2xH&_{h5oVRKi%dwz9pI?0 zl}%%!IL#=Zbz}tZOnSY%6oJZkzZy;gq2}b;?KEBs$9~Can6qFO@NRZgYY?`v7;Pj< zM!Jw!NY6_B;V@~DZ7EZGdgu$PMygziDc~2dMr_bDO}O1bIyp+z+gXJgk<_HdHEMDL zR)*LjzDzlxF_Ke7Jk_(h5FRyDt=_d-2s5a3o7${eCM`k*PB~_VMn+~>tPPTso#~NM z4ATWC#VBruvu1i)3c|&l(iJJCU?syQZf6l;D%9z2mnDlzHEQz~=>C@FH@dLg_MT;Z zyt7^|ub$^Td>-YVcab^ZGuP$2zxR3LEv&ES+0&lad*>8Bm(}&$C?gbZG{XuMa}#aW z=gR0}Y33KC0h^Pg4$>PyP+?GHQc^YvMxO$RP^Od#hn-p60ny zf7W7KU}s0JC-HGKE_3l>UY>MC6c<%gYZxOX(%V%6bof@@t>&U^WR{ENLfjvz5?aCg zz^V%3lE;BrAWnr{1vpu#ku^&NjS8p5PHPdZ*ljKQKe`PZ!W)gIMtXXdvTji$~`L&)-tp+!4TIOf`7>hT$jN7RZX+4j+u8x z^-0(!eI10bL|plM3ZUVOKz>c4orL zYTKA~UDy~m?Ph;M4UlrN2AAxa3h|D;}N;!asVP>1t zVQ*Fn(}f^68RaWvPgLtPTh66RhFEJ$7}KUO-N^R{ zEm@b6RH^P^l%x|$yV-*})#}I-i2=9RI58Y%v|bgDdQJtAxbmb<>Qgc4poM@9ojR6x zF}Gz*(@0#_LEIh)t~`l@2^;q)uwF^cz~m~|IXYJkTgW0>G4acM=uNy)WSQ-hM8q+} z*Bb=b6@ zg<_|uyqP4*Ub~c(nwCQ42NTz;gq>tsC9{Y2;?T2-oqdT2>g2MFN!`LYZ2rFsh{My`s^h3YI1qRx7weQMpX{YOiW`f`W-jB~ zt%~`)yV~x(Y%Y{VH*MFkQkNHbuwjX519m9Ya2f|?u2hHyn5SSF8ex-sQx|mwn*z61 zx)ss>SX4ATN_MEp&=#w*iOc~puSV55&p|*_VyIx}_#m&yBQTSW*=(Cnp)S;Qv*R)| z8jQt!2TuE<)ljHLohu}bRx4X1RL88ux^2(YIiPA=QzITzLtUw4!}I`Es(o1J+h`f> z!*PAs80XtMO^rOQgpdW7k9@l1NnkS)#2H!p`jOQ2GN-<*9Nx8%I@QE+tvP`tex|yAW}5O%!MP! zXf*8(mC4tuPED0FAQt^R%sHhIQ)Noz%gu6G!7FeTQ~F7L(NmZJicA%&U=!dQ)NjbdR&h?vM^F}{4&48HsV%D3+ z;JXiX;E~{ifkIJ-&2dG`_p-KOf-P2MbkcCbsH!3*piZn1i^D0*0H19t=x|bFIIPon zlkAE@lTU@Y>YRruuRaq)qZpA@umh|P>r5eA<^%@pLzT=Zh_cl}J>AIWv&m9FJ7P#X zIf>~ySYby+VXELN4YvR2)mfbDju&2H#|u-4nG(BQI5tP=Vw5X4yRi^LK0`3FMH6%f z$RSNvhEvch)u5@Q#woOw?T&%3pxqQkv*sj)DN5++i>@b5h`5Q3C7V}UNRfxKnNBiL zI{8{bD_dhXmXL^<06#&q0-`lZcsPt=j2Sh_o`up=18C}^CmytA44u4 zd2NG~1<3?^9$KS*r_?NxFg^?Ycs6OZJ9@rpb?PyS^l{*3akT+VRs*YyVeSAmacDf5 z1LkUQ(&~rMut`{B7@>I>>~S-RMvbPYom!S|(*3G3A&5E)0xFY%-S$w#ur#IJN_PyX zCDjl{g7AVxS2%MHs5UEwC{qOcOlovRY3V88?ieGfv=_k{sx`ECn#Z4R%(LbBAZ$Gc z6vYfo~fhs6`bm5vIkUG^_0#)!Jd;1>=eiHbH{$fl+0BeX%`; z8rlOBY=Cs9zz+m=QsO1PpXF6K3#&a-9(B~Zri7V_SCG@yx)=u)BO|8d)mk`-0ZUo8Vs&!R&<-6P1fGnh6*icTf%AOak6hX) zPlJX)CTj!WoGFd6#dwG|T`prSrct?6?=`?z4Zx6PT|{mLIsw!W?B1)4V~Z-3^X+oY zA4ojkYcyx%n5_%#T3NtoKj@)waXe$e1Yo!|qmT9$dT3ABU_3)zX_x5V4nF-)Qgfk< zyo_Wnhxl2H=olb`<+@-8!gxx`4Kp(xn%c<0$x57#QnjR}(V;(+G~DF+fjI#lg^V>M zL}6CX5v8&p%mI~@K1-D%Ulzs5S5f!oKx5}%%aG$C_bt38KNjivfG`C zNcs8lu8;!G*G!c$#_h@+up+cODqRf)XPFce-uE~X@TRA0I5(#B4;2BQ6|ZO8ki145{lRD5sSEB#j(P*mr zJu)WBU8@$kxX>gTu~tEtItF{@A{HQlov*4&;Vj~Lq+twc7NHqgMsuc_FOiDZF){Ya$JUUU|!6Qg1}Ek6SwY@!*0}^OIgC$CfsT&LQS*>G%E^HYvgBl zTBANgA*Jfbb|Q7?SsAb3PiRu-V+A-*g@ub?Jc?b36~OpFx3Z(8t^q47*%do^r6`Z9 z!eml43n1|Aa44JWs%V*zTiGc^s3T(_OLSI7X}&dbQb-Tfn^RchtO3#rLnW+Cl(s*H zU@;mO>urK2Au%~r%5AHa!s`R6)2*g)6V8q}xnXBhNR%mnRkD>ULUs`r!L-p?ctv`R z{HUC?hoPdD8)9Bkw4e_B1R%r%_IOvyIobjXauAwNIaEF#y0)t*qa0u((osVX0vrF- zCe-Q+R+01;TixtoR){=0r_GA(mdHjqOqKE@uV0VLg^8z!mC^`!f?63lw%`$PpFky2 z53!My_R_gHXeCvntRn4Rza?+mnMOyEoRfETm??3T^a$X{w~&#HlvS>5SiBxh`%p(< zlya-u&S{7{gbLA=%JubhXcf!ExV9J^M7uF$Fv;<#dY{zC9iO$Pw&o0~aWW1kAu=9B zS&e6;8q?+UrlW%;n!~CUdL|b&F~^LXLy;RH=^^;4ZK2q3D=KGLVC*8CouM=)4G?XF+HlZEy<$z|1+v|U7cSE&oGt3( zv@jgCOraG&$j%g_inA0I`D|40RJo=;G$Vfo_GqVSus@s8t~}9lvk_1SHB+6m zl4B6?$c%k9&kTeL1I5yqS{O@UzcwQ0=s{ncOnPxXg_g>&A6GjH<)z6?SML@plTMnV zCC?LbG>jJ^9We~>HAvaRosm8u8JFa<2$95nXij0i;Ap@u$8%t36Nsw}Jg`y6R0nL! z_mXBqh^Av7NRcje8@h$hT-VfeCX=iTn-jx_{9R-D3&36TQmLZ3b;k#?i?3gI|33DA z@(uR#chb-LRq^td*c`Woae`0f=Pyt_jvJA+6mio_lhoEmedkeSJAUMVIT^D>~t@XAy zeYfY&s9(~3W1?%M@7f!l-{;vU&rdqoV(bvfyipJYXES+3-IUKF(57xaTijGEWO|zl zDqH|N74%%L*gZM*jJi7rTK>d;@mPDNNP36{hV2}@DObp)PJ_ufFsfthoU`0FbkO7p6`IzF1ei~v(snx+q9N80&u89 zywiha_ALug)JMDKZhrudPI!I-UVKdtWC6~h*rIlqkN7wxP=S&xGkB-G9V9PmEWc<` zU?<(!-d*8zr&}x(kxhtR00Jzk#Z84CI8Y&vKu{LR!|W*B2h0C&i0=7~w9kB{%K+t?VTI7P`hrrQCsi)6Add5)o^icAD zGqIyt|2I*0!}|A2c4NqM-~O9j&&{9Rp8lI%yD{XsZ~x7%=jP9DPyfxX-5B!RxBq6> zbMt4nr_aT%wL4Bv1Pi9E8>irG#Ha2_;LGR0|I2H|ilrs+-_nZh*N)VRWssc!b}6>K z_`m%7)E5)$_FTDXzk60LtxK#}x3qHI(o?r3jsk~BuUN5i8GZS5=;dp#wR`TpYRw+2 zSFTtt&_5utv}(oD%B7Vn_g%a9>Q#vsB$igJT(x@59(%4kaIf_Ty?E^lHXeKkTqr8d z=v^0Hcm3TjJoM;e(&%{d-R~ck!)X3Z?|#p6 zwc|_Td7nF>tG)gW;6+CQ3KoSvHu${`O)~N!yAA6!$1D{6|cSKoS*)#b@R1{OQE^`_B)>V!9#ER z!U^a6{*_N9_J8Of-AmBnjjzy}_T<;+T=3&3jQh^-kAD5D|N22{{YP%@ylBmlZya9p z8eeblv$?e~3 z$oj2Yt7qRf`TXE5SDkmn{kQM?z(#YpT=){<(_BUcEx$cN5Ae|`?DWD z@CRvlxpM}8^&h*+XOvBsKXCdb2cK{b^7Y%X_Z@r}d*k&dz5S-o{&H{(*ZSxYr@i@O z-+S;8`j-zraOoc=m%ZY%lf$Kn^z+L;blpAgx#L`28oCE;J?tN!z4Pt<#*@xC?56hT z5B&MZsRKXt&B}DWzv&|szn-z#Uh+?w?)TU8o&A2W#`m>d3t#3Reyii&DXr`x9s89-10r@qfGCL>u{~AW=35TB>W;5} z;*T@rwR=AKx|f{M{L6l?Jos&`%z+nO-Qf65cinKsqkrA_2~ql1_3~GI;s>|=?6M=@ zdAs&y=B01hk5!oUr`>e;BR@Uq@CSZy>D8T=zyHlwS5N%j8FwD><>1C|-~Z%;*Isk; zalwCou>Oxbw z9bOZh_tFn*y` zd*1);CoX#99_N4Py!9VzjlR^p`t^@aF8=g|-#yuOKX%5=pF6vB&(F<`vxk55lbiQv zzdXAck}EU-gh*z1%2rF&-mYZ{N{Up{lM@w$YazsZ~D^zVeh@; z+RBzZak|}Yw{zQ=oVo#nNyY?$1qPm*3?Wj_1anfLa$JG1Z2?C-O)`|cmoxuNd8=Ua8osdKANRndId zIqou6Oy(^QwlhOF0KB}7ISgWdEz_?-rI!_}dM^f5`rdq486u8OxodnA?0mUY#8#PE zE4$-6LJe3%es3LQSx~FGjZ$m)J#_b6X%BYy%os%NeO!{TI-NE*N6}ef`B&3}VokJM z*j>m^6F4q&tqxzb^bCDjO%7FCD1Wxr`Wr`#ELV2-IKr&V$v$HEeX+}I9^Ln6Z=)-7 z6iZ@5TVnah%<^UjKFQbmb>YjU^s+j*Lw+j?Pf+vQ$Ss#J#uE4E}$E3l)Nd_}Y_41CXhVGL#2MSfm^|1G9uX0ftXniTO+s)ATI$~_7 zC-ixedGl`B1@WDGt4Q5Wg2z*dz2zHu1Gc}+IQ}xK^5cG$Y~*5k%hCt(0*yw1KI?PM zhH+UTF|s?8MMcCfv|+PUB=*`bMS6712IV$IedF;%02KGYVTGLs7n-rcSZ(;2+$#LY zq&s}7j1dQh;gB*jDKFh?hb--Fn4zWfdEVWdN`n;l=WG+MF`nF~yNgTI!PEA|v65=- znb9QzZtBI5r2;lCW_Eg+JLo9n(ypYgzLsbCN#2o`M3Ebh>kJX7sO>-@y}JDed%kf@CpWJl-Xp(p06^kKp=VaoG&5t< z4i7QY7%`|#^BxH%X1V$^4&v?Im}}H=SPUo3L7ZfJ(dD!-%gH_9QvFhf68qU-c30mm z;S=s7BwnwCmmk=_-FcG(BU7HG$A`b>ii5Bg-nV@U`_O%HyH{DBs!zW>tN%Lr zEEbrNmy@B$50Pu$dFg8eDL#F>lQ5dak)?cqug!Ru;T6HO#{JGxkZ+x903?1$LCiN` z)8+%;;hqMu7HOsLlD6UNJI{VwD$3IOZ3mrdCS+{3^z>tYxp&x(iBitMs)hRYr~@CX zY$DI#Y1f0i!V>GCB`?aRrMH=pFDi(d?Fsy+r< zR0c=3SwjiBPTIsm{DoRm8VMK6Q2SUwf>^dXT#<|W5OhDsIO|Fac*WMYk5FMx^dyS; z&7okbJh>;OXSXXTDtxB)QtEH-KmS4Te+2?UDA&=QFeM%pr0?(tyV9HG(j%QK zwqD^peBX;X?Cdf(!D1M|3RB({8IfD~6jm{@hVvUMN$!YgK~KE#%t_95N7g7bGil>! zg8-W-&Zk|sz3@92@{imCm6p3prCiVY29zRcQiW(g)fe)fQ>$XV$r=`iKA$15_;iVg zi7of3yrlR?fxNpkEdP!b%C+0;u^Qn_ zoi2^ybJUZ`U`3?7sOo=uS3krRYEaM|$d%eiA`;%0%L&O}BS|f0Bn9qbcPuF5oIZFq za~FCbLEXR%g?io4_U=>6}N>|!arx#<~;S_fy)6Als5%Cb!0 z^2l|w>4#x@>L&C0nwRzkBsFk7nU+vkLmdr5GHKCFa;Q#%pFXjTcOG1&l~Sqk@;91f z1;&9*Q3_i1gM8y)c#jm2huWb})+Q|OJf&-BCCyEjL4|dL%O?{Dzm({jyeS?dRN;$h zEug}X*zocJqcwr4+cIIV`>W(Pk@gSq%pgtF;xHZ!?GyZ4~u3_roEPe z3f2u{#kU?+(;jv^7P^P#p%JFmp8;e{{^4_QT%@c0R`>!(1FF7=gG4|4WUHbs5D@q z2AqXmN!O}&cd@I6Gty+flt`n^6~Uglg)Q|?KiEcm=c4I0C$D7g(zKRW`KWk1EU5Bb zx^)vYYceRO;RlR2PuXwf^VenSBI%k-c`Y_QGRflk`Vqssq`N$K{j~hkuo}PQMugq0 z&rPxFv#*UL3v|_!(Bw+BN!7@mSbctHq4`_Dl?wQ3`m0zr%QZE(8lsR|s6oh_4z%xq zCN0=Hl|y7NxA&eOy~$ta7nIF4RIRUu7upUmpzTVNCzvXXrBIXafwUqM2e;nDmudSr z26&~gX^@J92eDkeEfnVi{gGKi9nIC2KBjl0J&A%XD^{hipzPy>`b|gMgUN^ERVJOX zvrYoF!p^&P2K@Cuk*&O`4jrIAl8)D73Kqa02RFZw|DkE${@PPJwg1|2)1Uq|sXLdQKzC8#A-Zg+vS$>n3cR-0K2rcP3`zHhi$wd9UHT72 z4NtrLr6b4s&u*?Py1fXoAhWz0_-;?Y)vIdk zwE%t}CdEQ4>Fn-kN%=7!d7o8`3$D#7uKKKXenOlPG8P{9yl2ffH+(59db-fa zT|R6Ha$LBn4SYCT?f-d7{)U^6NQ_RP#;V|9vvc59^S5Pt zKP_swX5mst2ZV_|j{y@yLlN(OkH{s`@|6hNJCIOsfjbYdf-k!$`Bl?K2mWO@2EE}q zb--w!fS7{ftJ4}%iONjVpn7$GA~wL?J>c~q1$+YA^ROlPXMTiMSj-xxIp-6$6vQJ# zcYj5sJ-8d!jc{Oqslpgc@rKN!&)p`$X^lBnd424u!K?$A_#83%L83(-d-6+{(!MFdKIQ-+>|6K@N zp9S$_=B34MaDhPKKV_f&g7zh$hi?cql3bSigg9N$mp4y%G!NqfzHv1AR=;j`nd+#e zxF$-%M@c0}`#s7sipro~ECD|pCmwjO%8`aVC4 z{~ac)1{7>7Pov=O(UgIotYvE?6qH_Hj)7cxtxzPr0A}t<8n! z(vEJA!#S9$U+Dp^&H1LgiMvI6!_rW8V1IktaKPy9L#H3%ih1TDZsiYs%h9sRaek8) zuDj6Y?G~FLegea12&|LQf>0@l>o3p{NAZ>ENrkkd{fgCQdF~v~(l4b>r0kCtOu?CZJbs#mB|qHhiw&$B ziVNzj1-Mq+)LV)C(AGYeXD{mXLWSa_v5z-*Xk{TVB__omzg&LdJcbBF`gNCQeHGyR zUjOTaq*c;-nHWBBrjS^Pj0z87tVifPhu#<^-=kdZ2>me2Ne+JO%o)Z z-5A{1x^zGk^OPQzdwHSK+0&g;(j))m6KmRQf2D`#S8J(Q8f5Bxx9N$LIHt>}h{bLr zAlHs(H9y*ya^pK<&OWijT^n&@t}k*Wo0NSvG=cm~@?;a1Bd zijD0H6acK)6uOf9De0Q79fzai;U0r1;R;8%3w%UR4{bOvbD%bN&25Y8bAL!?lZ8jU z4Vb(F9j*(^fBA}HIsoBPu_R*c7Kf*^=jY{O)7oE^R1S_?^UoCBXitXQ5AU@|OP(Kx zt66Pdtc7VL%oA^v>X*ms`TYVf@~JtPFR~tQnN^yyRlEHPZJ4uIG1lh1I>cV%UIG4? zGFfFP*z3N^=d4pu7AJD`J`a^FTglo<3Go<)Ey^uMG%I+l$-?n;H|RHx?%cj#-|Ga` zLO4TC2qg3-|Kr|pJ3eMsPjR(FnWM`yheL9eu{P@k-e!NjEIT4#TySoYmPC_Mtwt-q zt+l*zaj@u*|5Xt{WnbD6>Vjy_@yN9bBx_%FY>rEkEVErrWKARx@!tfjnpPB$l3I^uQh(Ut=&}0JB{Hy$w8($j2KDu_0hdnXjRXJ$l<; z9vx_BQ_HX^zOtM1+`XQW?xKUA4YzfxDk{nXK6lsf(Cj9nAGfxFI6)z4(;$$fR>7K; zsSIn)Z-^RsDZ`Me@wPE7WVPN=qifXZRYH`UXIMeWyhf?N?pwq%nGomju56!wzgyT~ zzv1GZ$-oZ=$L>&P>UgJ39QBXhAB8TTg*c9G3RAMsg;-N<1`r|NvEI5CIOlV{1mwiX zYlRw23-iAeOVw6T(7@vsP`h+tLZAfqQ#9;l$S+$BkuLt z?1yeItjQHJ&0hAu>T*{8>NWDt?+pdt8j4%AE)+!fz=!9E4opCRl@)}Gz%UVHOk=!W zT>MIil*W77o0~lzq9s7FD=6Xg)Lo4lN*4k|V2a@cV+hZH7uJvdSGo3&>;4lX@Bp3` zvW(fkY!69)r_yo%(ttQUrnRDD?$Za`=o=8TA77QkXr84$n$d5MGmtp~*LQtx+a3V? zK@E&m;$NHv->fk7$7=u=t#eEswFPSC<{at^1m7JZY$bYIMJGh)L~psPD-MW1`^JG6 zY;FELyqG`!ZjipfVDzh+IOpXh1Ps(#1BAC>+ShjLLwi!zh>M>!yDcm5LLI*vqXLyR z=8iY@i~r!-9}dzr0@XyzovdQ7CPsgffh{JLFLI$AE9#cyq%p z!^`*+s2mrB%Yl!iAS`T7;7BP9IrSD+*8t%S*@V5wul1Kr&np#${%(d~+ zp^)h-@}3mfqcJLL=6Vkd(_>TGmvBx$5OiW zhyn!GbKCA4hdX)Nc6xRXgPGSCNUi!>v{xlQ6z}Qc1MI*@(Svg~o37K2o>B+IvW-qU zKf8>p_II&`U#q;?^D%HzvMW=qpdaC~EHHapcDLVi|K}lC?%B28Kf`O4(^%Fq_`-D|8SVnu3iFnF3|SJ^-%KQNx8DHk8~M>!Er?|WT5Wr z#e}$ahV3fB*!C{ibkmqN{Vu;@PTC}L`7s#ShmYpGa+WSJ ze^Yw71PAc<4VpTCCpF#q#rYs;VWG>j#tFV#UZ$9Uiu!wB{zgGL_z0 z>428#`a~M@`M^{cY)eUK6;B6}m^jHbL67Lz2IvOw!D};Mcq6+*&qW!}JYpUJR&J0F zb&1zgf0-sG91k64eVHRj%L|!?)z3J2lJcpe#JQ^RA{Vd9txqyvv-o&x%54hb%r`V* z`p=XaDi20VY2wadfr~d+nMe^&0?O&NZO`5?gy$I#kwAGt~;! ziQ^6(np~7s!OV+@tHCOX%|K99JV{m4SUI7ekB2nzNs0N{k-hVvXD-yZ+{13DwbqB# z$x5=e&-D4^kON{0gp(o#O|GB_Pff4-CU1YJwoAol5<0+0BQd)QODo!1k=G3T=-LH% zBQ!_@su0`zMTsj7$&=PJUY6MEBGoxjl9f4{fDRI6V=_l)S4dV)7-{|!s=W_4?2rf< zinRCcc)cw6*|e=i*37humY{>Mp3wQ)a$n#b*~#l8zR$Pe>lj62w=FPEqM+n`TGBu- zXHE94KA_F+P65e(fdwwRWyu!QuKpWY_>ar~b_C8nN8C6R4Top+e-jCVr3<}9i9=w9ajl72D#dD4BnFReFO@fRC zAhI71!mFS4p^mSoY^|O7nua?{edF-JN3Fh0pAShDCa;Oa$b`ErKREP9?2j~QC6Ju9 zpz~8NPmk*?Px}DZ$IkU^-P3?hYH@>)+qV|!y)*7tPBkeJ-5G}twC01KvQ^ZR_BXe$ zV4ZC}*)@#RL@*@*ZJH>UjuqF_z!Xn4xaaP!6!}ShvgyDr3z>3K2WXZMk%v}oo{ZA? z*E}ZX!ABP~lax0b>s3v(Q-}E5Q&&p^RAbO2eGjHL$WNI0pIer-N4v9o*qW6|fDVHVlSQS4|B_fnG{3Jz8;pY3d?G$ z`h$V6Rhdd6tmT`pSRn^H*7o!W-#B=~+FEXvjGlkw4{JQ|=s-;@lBc~q-o#8?_o*B- zU8}-K?t9d!ms-u^G?RyK^g=7SI-*icwR%0_A4<6chIwQ%=9NC?CK)Z~-2joohH`Ho zS|;Vs2FSB@K-);L2G*#3O_r|x=f4AG#fAc(4^*cD*#Rfwq{AsTXv}^1{uaQ^smS*3 zNuqJ^NLcz*nOm~*O7b$md|BY;ph_Op`PVKcT~;VvSvn;&LdJJ{Wy}QeJbL0raGFdY z%<5B_up4M$iS4>h>)7n^N6v!M>N4-HgbS8zE?)o}B#=HZ3{Jlmt!dgJJ@y`-r5Yr7 zjtz`97e^MTsEBq+=&vvZ29k#cCYnq*S+k}zq(XmB9og-LnE%c>ex zg|+S5Z^!c#neS8tHkZ$hQ)@|=ZD-?h^SfMIr^F7a3wUDB0Bv*&@OJHmH({bHEwM>h z7n`H;ci{S;gyh2WovVZMKWt~`&j5LfOtstm3exbSQl7zGY%{*>j)%S;?bC>mj^Jc4 z(~n2OtKWI2YrK6=XBb=Qz%*b|<09a$A0Xtb4)4G)No$5af5#l4%O_S}0mDvDoxFw; zV3rwAs4e4$raYeGRHfhLKVQ=m!*Kd)N9xox{2966T`reB{pLK&!kgn6){Fi#qZxM;SO*WGjL zaJ{!KeXi}VZ=|0Y`CzA3{;Sk!KnS%l+mUZC2|avrDF4W;vD5tc^Q;K_&en&vtZLWe z+gd#dXNeV-n>06l(?uF|7o+!WVOn^>yptB;Al|K^m4;V^2Yqw%m%@VGCr!4XdkZuL zt;=%yTiWj;KK|wFJ{bRMR(9oxUhfrt!c!pm)wSr&~4*S`GpX7;>(dWO`_ z*X$70?yTB^(3Han-_5r3)FB>@+i5tyA5CJgJ12Kpo9Ywjr)6e{ir?%xsouZE#l<4V zNw^|LfMT9nP08h0k3KLOU=!zSSAL-*nmM%4w~&cj-sNf3PBX(iTQyqbT1sE-7?R)8 z@;#fzHYo<4Btb?u-p=iyPkG#$Y<2g%>KkzRX{|OoFksm0H%b5Orx0NBpaHMc`D+Pd2e1~WvnGg z-A$}~_-WQaaJ0m8c4=N*Z(K(arUc!M3a!a_W98u68IzRk=-kP^*mA#yknr=@nkY-K zPA8}%NYPDH20xNhfc72mhm|0b94}a$Y?a2J?(_9_$@T6kOh)vntJ8cePZe?wwz$7> zlsF}(lwqctQ+y8|9?e69PS%yOQ|+@?o_^!dSz+%`&GuWP=G#u3kKfVI;8XG1h>q)1 zY71*?&oho2$G>qvuOCXfBS{?*t;$-OTFX4F{N?HDjoV|VkHZg``Vr_W^K;zuN4$UW z(2Z{#HVwDsowypJ?@n#L-0P`PKlDVyn z8^=45`oO-asdK=C*VNNik!{nSHT$!M6zdU=ju?`s8#7ycr;V$RfB(yx-uuRp8-xrU zFFb~7Z_S*N!;Kv4Wg>1u8fGu7WdJveZI^nFS9h%je;TOpk*@@Y-*x9h( zPh9=RaYqZioYzo)9s+E7Y_Vf~T;7jyC=G1f$+Nrr##4 zFjhvJCdo#VY9U{Up*?CyL(}a?$u;>kLG~jnx=y#O%(#BL+H&7*$E_hov ztU0-PcytGWGrz%4AP%3l3CyBIqhrJqr2!VUTj@d77GTl3DonJ_~XMsOm zxoS;Yvx4)s7R&>Cg5u!+G}j&#v&5`VJGY4je(GoPm3($Tcxg*_$${lg2h0yol$CU! zB~(aRcD!uWD6y)u}#k`e1)|C|&yIUCqu(&Vq1EA3%zx~ce+y;9(M{TnBE z?h?`3&pPpCHZ#RgSfJeIUYHWLy-i==9AY(rl3tXN&VIDx{xV;HGiY^TyN}emnp7rS zT9qHcxa&Jw4CtVxl|FnqX#Qr_IgfwUp3~%{4hoY*66<@Bz_XQ=QbtVr)NRsFle2#) z2VV0HFCG|LW}X6-=~FvufzM2e-+%We1h$#ijA5_!7-xz>CaV?W83i=~=H8Wq@n0!* z4zox{B5|s=sRB*!tW~51nSxkxuU+)TPD_2&HLbgav6O{x91$IctavX4(Y+%n0o0kx z-^KG&&(}fu0<+-jlrfbZ1oxpqz(CMce&ZymXK9U!KFep<9oye*pYpRC_?LR(4zpHX z^%5y?tky9!|8SX%KO~Wu#n;vGo+ZZOyAp}bo3wso*?u)!S5!((y`eCnEVOLo%&x8o z)@x54(rb>tKcJ&m5C;p!a_ZafzK184x8 zO4JW3D*)F9omi%2;_q(jug}!x521ppnId33L4QX+6A2Ih>CIHB;l@!)pq@_a`Y9@AV4|w z>?6KxmgT;um~jwdQW{88-u$!@>~!aIiRciN|<@5-S_i1GE~`s+$o z^l9IER|h47xuYb7u<8)^E;&}Fe{^|`gww*x{fD?apF(d$mW!jh^^yi47>jvc+IG?Xe`c-9K~ zwCiDe$<;eR)w zsDkQn12!MHEv}g{yc+3H4$wUD?8* z2-~<4>BGBVCQU_&YWq83&a4A>{=6YC`Cz*7n1#Eqg36Z-Jp@p@N@2Ny1YOgzVi;Vf=o z25rc`u23<2ePcoX`<&8TYQLrR7~J{eV}>f)@}ZbSq@KLx3@#oaJjID8L_OHg_~Tz0 zT>gVkofi%S4O#OC)V@U9+NM?btC+q|2Gnb|*~hC7@vq(aLZ4rui0qs@w`#}Q?S(He_B{eSc{!=`jjxAIIF#WOU`*-XI^e&nC7+=_QWfJ!@%W4u9|= zUTyZ%g%U1}B_;~T6l5N15(qjcLj~S9dLy_-2gh!C)cy+P>wB>7&W&`F2%V;q-JVPd zJu6;RNlcXMdu*Qr`f8?aLZx56uZm*y7G>HcT6HVq>oyQ-qCfv#xSyjgI6S9rgflP` zl~<$0O1$=M6JdM~UPbg9grX!c`AS>>a$^%vuVkH>_)tl(Bw3a05T*O(!$b`C$kNLF z_z|wr0f&ilZE4sPY**Slz+b774n>GVYaaOnZ#=5~VJ5>qg*S05W?lC%@0zoW@m`aq z=}GBsUweyg{8_$)*ugD@^{#GP8DXY}&0e0_V-5Wx5Avb#e(I`H>d1w13|?zu=j7`X zC`69rY^+Ea>LA|eH;%=wVfmTHVB;I&#pg@6dXv1DWv49Ptgoqu{lN|@4NoU{A7y^R zd9-eSW#)ENQA$8oF5Pi#XL>`AA)0!x9;K`O!mnE4RmIbi(P7HS!w|5fkv%GF)@CU{ z7o9v$+w|5qd~}fOMS5Xy=?|wbe;2U-35dRf_`Vz1ed8xTbLQw;2xQ?EB?kg~57c~n zJlcB!Ve+4kRkYp~-}!9+{ki{Eo6zgR{%ukl+)q{R-eF}P#a6VF%NV6v<0@Cx?+|Yi zTH_naTx5(`x@Ym*{R{j38cEgm?6b@Ymw4ehJDhrSf#Y6SPJ2NKF*gFJ54tTIGj+z5 zZyf3luet(8HeZFVe6`*9SpT?z7${X>W%H#%`z`sy7i8pTD0VG|uRS#1<95))js&yN zuD%|ifEd<>-M6o2J&td*)=4%xPlpnamN}4h_U`BQS)VC5=hxE#Rmz;+FFD|HQdiBN zrq1j1L+YDj2l7{F!nWDD-#F|}W7R%Uq6Z~LI15R3Lt+CJRUV zq%}y3?kV4GvZF=K_zz94eepBOzV$*u4?K-l9+9@VRXYY{ge-Z3x_m=iqZUiP_Jd3| zR2zPkw%M47-z<6VVjl=^K%}2#_Ki;56`9t7Bsgwe{Il3gz<&eu-~E59bsmygTL#!< zkKM`|x|)=@hwj$jGo74yJE91_L(a@%_bDb#!^4y6V=NctH{<4KS984XU;lB$aUyY) zWc9O#R)?-Jr#R?KhQqdh?F&E9m#9Rq`DU+{kp_HlE)dwRaQ@diuwDbp{iBufCDr#d z?&di_9VAyQxXgC;ytCdvSK!BT4K2-q`WvS&d&ARKBGajcr`;cqzA8_pS!87%TsdXP zX6|$O?os~edhxT|n|~(z?+fSnsAa^`@4iS3liCI5G*oz@`W26ueL+GsuKqH)E*~-1 zk%N)6dKlf8ZgC+v$Ph&k?XbCi8zH7Zr9PV!O6q7U<3G&KDN1T3;UU1)dQPcCPl3`} ziS!32-jakdk$ z_o?ugguN-Kw_3NhcpP@sh_QqaQSW0YRg5WA`kwlzed>0)t;!Dp6Q+{(CDJc`u0`1T z)ly~H*L;P__4PT^v<;=7F_JXrMSh&F*@h}5QrFU`k)F3%^~PgC!!9^UA9=ClERFEG z?sbGq9?8OnyuXKpTkl`$JGPtJ=B~Xo+wH@49c#8}DUIlp7yg*lvTJz#oLi~OEY2SO?EL+jr+i3X zlm}cQk}rk0fN^V}5-f>1=C@+MWbnW|#mBXmCOShq23j{y3tzBG9AND$?&K>mkH=_u zqQLDmTZ;=b^6jmA;3gqyP56Y6I*MWs_Nx}V!V@@8_yC&DyTquqR>X%fD(yB#n-Sxq zAF-i0c2*uNP_M?L_J@v!+nmbJHv7l6%&zpgaZ%Fk4o9uL3Cq>R{Tias)e35H3t2Hf z0Y%X_oe1=*c$Q*+qK2p$$SGm(?3@rre;Zmv5p+o_W|XrORce>rkXF6JoBD;3nvB9+ z$)wRit2Glp_MhB>91%OJ@N=c$U}TucLlQ)#b*CN@XIPxJGT3y<@5}6TWUnGBS>@rp zQUBwwE3QHboK`D36_YAs#3B71-3#}3@=KE-mflxQj0a2{hL$2BZ|RE{Y{q{dTB%d0+SeqTe7}!jNQLahsyY(oHyXfqf>EXg{S( zDs~%ok(VIGKh;dR1^sER@=G#7^UiiapsI!n^`>xVZXPnqV)9)kCR}}-Prx*$Sd+=6@?V+E$g>wu{QJg^kD4dSX3WPD-mUVEfu zY$6M|wWXGoo7s&LZUZJjhgZ8$f)l0iQI;+oYu?UcTpV9O4Zcnrd3LNj2zI=KP^_;~ zvY3_GeE-aqg{&Z%U9WAQ+asiGfF_^?Y%;3rMl{sKcx`S|9_@()EK z+cvpw^Iv}QrzihXlkb3zne`uOzXe1=ziT~i@m1&zQ)dLiu6&x8KbjKVU;{Ai_7cx2 zto+>+GKBz$=Dsc|`_5j-hB&k0Y`5rwHjDGm?Ti)x1d>S=lbKW`x%O$=)NHP=Wd^O7 zcQBkt9Fsh!*<^D#<7%@A2Qe>0gS|mRHUq~=OcLqz>hS|^;Oj4;$R+K_P{Pa=Rrz(t zwb;pk*rrU|q2dx;`TYlV_daP%AYGg6;9l^fs~#&%TY_y|VxFw7l16?=4&EpqRqn8U zg032)$P~l!rr)p&tLt_(XguW6Xa2!B9*ng3jyLu5#G)9fx(9b_6FERCT_dk9!w2f) z2N;1eW`Sx=AN~c6e@|(X4WF=#zyC66ugzq|Ww26?sD9Q^;1k%KS5!@vI%{o|CQ+ z;NKeWN_C_oNYR0#vsssbPLEnQOfx7K1-+&x(+4nt@BUCN2@(32cjs>3K0Y$t*FU_j zap+#o?=vfTq%yPiY9QRzC=|(3Iw zClr=H_A0LFrUIbZ*LD@-d8*%!Vn(EKW@D3+aok5%_eWX5CUgNsyRFVQtJx<1UI^u6TeLS$wqe{$6b+{{#{`o$+c zfPpRaYdwj0mSe3c#~Eds4-<~}*_B0AsT!xvvtG`F;oY{d#=xGA5=A9uCaAXww7Tf8j5V73A6r$ zv#plif{#~Gh>eRg7;e_1kW5H$`%gD+sA1LHA1}HldWz#cg=7<{4trG4*?=)#ipXqn zAohchTuv^>W+Ur=#gc#CIj462`k+XW=GCxA4hIK78AH-aZcskWz8V{5gcXAtJQEPe zT26KP$!KkUR}u zf!9ujF6Sf))*uEXT=J`p(Lqn2?5ikvBhy?nouida-hr0p!RD*Z-WZK7^R`ooY2+bd zIp$?ey!Rv1>k1P24JMqK@*=DL56u)FkSRj)Lnm`|_L!_eu?&8+cdrt|W9*z6L_xuu zl&D&B=dEQK)t7G3p0+dd{PXlRxpU7VaY4s=`U&g$vZOgAK@pe_QZ;*vE?0zWjTyr$ zASst;q6G%X4&&{xNtUnKM+tqT#;43efYj84At$$O@h{qn20H&!f&ORo{sRi%^M$VM z+>Ek()O%%}8+I9`KH|$$y=jC#HJ<7D>!sq`o`gE+tV;B zCqSpqB*~_{&OIAce_QaD1DiaA<7(ub32H+*H78y?S#em==d`SWRSH?ZCSsHf}mfMfM|5|Ept&oEKC$Y(&;0? zEpy+*eHkh|U--dO+B3g68HS0@G&g^I<~E7S*rTll&C}RH^FX#gf!c8<;7f&H!mj;m zW}<%!>Wi-yj0b;feZC_W6*42I(al9F#`N#i!WP+{-n(&;RU$4QX1A(~0SP*how&^z z+e zC|SC7b&`Laf@U=XCqzIm`a}yV9bFeYJr>3I3>|kCJK=E9P5vm~rYu9{J#Y6IiTa`gUq|GELnMZGqS_(Uh3^c(*Ceg(bFN$MqCeFO* zx>14*IDW1abEa=l?27a7b>=3lPY(c(TP#gvU{XtG3%^$UH4>l$2;sJBFf|@Vv19q? zVFOJs{BkPtaB_F>& zTa_~W^Is{wO6s}Ss0R(d_c#>O>$FpCH~9GOSh5^dJ8W=)*9?c2%*11&yP0q&w(b3N zjY4SoGo{Im0o%~l#k0hhqzosnr|Mw&YPA=$!e>supL?<&6{6}SLJMm1Xz^dReU0@+ zf$E*-e<^EX#1V3n0(|<)n`zO!ne(AIv+oxBb$1D*pyu%S(5A1G)gP@dbUOf(6VYK* zPCg23ghyAn`*&{&5ll`RtO|YB&Wb!XAzyjh)e?xJcxn4oOkL@=NO49hAsVXF=t}C23%9H`pB@Qksq7!(l)>wk(mj7> z|A%l|Z;xOm8s-*2#SSfZm9%fV4V1yKDysWkU4eY8(aix#chRGomOsBJ$*kRblxIIy zf$Odm#6Igyp;C?XiwlB9#n5$Fi6Ao{(xpaU*W8RHhPR4M`<4%97wT4*a zPrL`NxaGkig*RtG>fY4dFFRLMKjrn&t?yaGvxMSMs%4%OY0iYaI#P(q+2WDdCw&`>Q5Hw;aNR$7d+xu2MXo19ZP)D zLW~c@_tc4OUiGBOWnE(7t>NV0%95frd7M>w;b%YTAh@*6QXzZj&YdX%7ql{Kllov% zkL{#{r6qT|lyoA*lIUaP2(j?lXl}z*NG(j?7}m)`oJ}+5fgS86T4$%RzVSm7GhJLaq)MC2m4CmVs+rWgI~_$4#)C`>f!l4U&ZE%ii>eu zX3AwC#4O&^;XoX>+_Hwkb+Dxg=$XX8FaJYs{nNqglY9kb%3zsJS?*twflsoexTT&Z zONvb=OW71HyoZl6&gPQl_7m4Lu;pMiDZ9k8wpj{KrwYb@A^G1eV)@_2#Eb%O7|U|% zDl69TeLV}$K<-F@_94&AsG$Zdt8q*W^(;V9VrPE?;rwD-Y1?AP!H)6U%7P<)oa!B1 z(wZGhqc1i|Oq?({u27=GUh~>z*~Fs~yBl~3x0v^V;=^P`kdyyBzDaf72ekm{t7fQU z2s+Va&pOsFK*4F&IyO0sErAED0am>8%1=vzVwptq`1P0|{i`E*&7D8>^ejbb&}U1o zEF&MxG0Cbl$>K3C1R7D> z6Gu0F=Zm}xb8(4)ZWDj!D;nrVCX6U7O6m5feOx;7YZ`%B7~SnChZ4?|Flq_#^@)d$ zGjvsvFZ~L*x@6UTT0Tmjm_*-OWz>El6ol`pGZa?8>=#6baz0do;(7AYWO%p1nRQE7 z-v3Y8^B;8L`x~@B(f-t*!05U7C1ZYLZN?@`n#;?51+*j8kne?X$V)1 z_->mpgsk2ze;7tp+4N>-%WPf0w|ZzPK_?~C)3$prsdcnZ9A#TBE>31eH+m+e57U*m zI+Ic){X+Z_N92P0$-oZy&LQ6H{Z2XDwcJg9pk~D0u4P*or=d<|`x`v@eb_wz^S`fN z-`myvu*?pZ&gN`-(4CC$<+a7D*%dH@^i8ycdzI>*wz3M4NR#|}-LueNfvwVeX48%) zq(@YJf4>AiecSjCastjRSU_({9@Lyf1r+xuOYEr7iia{mo}a=*bW=PW-T-~OlM(j* zNh)m9qRyHq6#>^Cci>8gtOkrmF`yFq(>`1H5;c@MpQy7E^QxcL3{ z%<}wOnih4Bv;A;81>xXLrt5##H6B1u8sF1UpL8faTQ`?AyzIT-LUx`MoeBab9oZ#m zctC2e3e>d;7|$HspL+L3+cj^w1QB-f36yQV=0vxJ^Pg((kIN(8o3qf62RY zkI^?rz3$}Ikx}QvQp`F6JNC=|K%#Q#lh4X*^BMGs98q_Qvf|c9m|p-+t|d0j63ZE$ z5J8d`&Rap4-0KJ~4;^Td3z>=c$ZG8uczqRARaGzrxirA&qxI4Gck=Kx>Jz?Uf*FDn zf($E*o_^3ndy^j_vc&)mZSxiXKxyeP5>IPP3y+oK9b`qU|DXN}hre&9G=k_ZqXe5H zS;pS6bs4;0Z5vpU1jX`!ycVB(K2FjB8gc2GEqexv>qVI%5ifEPEq~P(Sk zDbu@SqkGVxEjJYNlU$F_EQ6>_8lAk0HcJs4`U^Gl->r^Zzd9eEbHBGxL*>6P_ug?$ zW$oIqGmbhIbPy?0N2+w`(nsk+=%JUPLqd@nNho6hqyz+{HwCGIK!5-t5Jr&_ARvSQ zfdr(59(ou3GUt2W-+AUa?>WD7W}ff&et%`Jz4qQ~t!wY>b?+y;S5E*C6Ts)kM0^Hy2RK9p^VzeF|&oJn|=1Mh}syb?6kLeAY{5s+wMum@Gn$r zOl5N*EqgKe0PUHkCzEWV#{Ev&##8U^T7Txg>AL3A3J>c~Ha?|6Bc0_JO{~rY>`tg1 zIAJ$iwxy;_PEP{?=a(NxfN%cmN5|dEm}(kS4&c%wQ7=i=&(`)|ZDMfRkIP60HUjIU z!#<-_wlV-J;%Dsl^#hu{yOEIoYpJoGi&8%k>`gL`k`wcgSCbFGoQhbtwg~2T-3M=&jV~})EX1O6lo>0ydJ};y?4hsRgl_vTk zmJ`#*MUya#x8u|rKLByobK((3_8DoV>-5!2*y7sdJgnl<@d$w#_#d?qi4u!mQ?tzSRoqX@Ym6;nlANdrQqZv=P4t zJM_i+HO#;2AtKGrS1Y_Un$zTaLjcZG`U-kQ7FVV~HQbk%euRwlc@r}6wDjKJ z9n!h16qBen=k767zQ6z(FF21)>(bMo+_|X&{Im%WljT;lB2FU#DqbCp=Gay@!CB3T^b28zG^Z79!I`A@~(NNGGP3MWgH8eK1a*5|A2bBgAjyk8aUkbC#0 zHCm|gplkM8JA0<#vgTFmKfKSIpUS?)$O>I}nyl*3S& zmsM??ZZ@5)wp$vvKHBvEWI}0jkk+wqHvgKu5SuG9aDd{bm6Sr|+l812z4DE$n;S`iBc&$=PX;gR{w z-_A|AZne;q2W#TqyV)RkrCF~iPs^ax3J*2FH*yEkjm{cASKo-OKj}1#dyGamoknUJ z^pDH$)cQknfJy+lQ##~gGngOD?;hAZ=;=elsSY|gI>H++9t*ARS`WL1iB^0DRrMI? z7*EG2$lLAN45m*n5#$yNZH1zJ1Kqk#0@# zlngF$)p8%iM67lQq@tfMUAR_N@Yxf}@?!jYP~-A88y9M>U)|$5v%PEUBzUSx-y`4x zv2r6wOhcKYRXI(DkeWO^zghM*G!-}Zv7|V{Y!So&zN0riSpjgdSVg3^Od_Kr)+dGOf8}+J&?}3;G2}dxm~YYSA#zl8tUq}o<$qRris?hfO30B|qtoF#N9HcI)0X)~lktxSzOd+& z<(0LWJ)8*+?f!9MCgOy~$Vt$2rry1XITwTv&K!CbUKvJdzv3$wS{aQadsgS_ZEx{6 zwnru~MU}YRU;Iw#Z`foP?}qA)Z5p1jn-YT}4TB(r8s1+pd2cIhPWl&kdREcxQ0~zD zj|OZ{D;J#~+=-J;aTb@1sfYD==O4-}Q=Yw#kv@96Z#J>4irMq-Fcc~d?y|m^msL>hu6F$(?L}{wc|bR za#j!NS}pL@Y024{pF1GN%kg$Nyb4!Sud`F_lGo-j6v0Jc&78ThE6uu-;fZoOezN&W z0We&LuA;Sz0AP|X;Pzy9ILuualME+7`O&6b;2L(YeG{c7l#QWjEqyID%H9sr*vu6f z1lDn6vWrg7NcoasF*evn`|a=li~e<2KsNXJoNC|C+HM}!w8-B9+-6y6UHVd>v?TBD zm5a+-j^g6$wS4U@`SiPg>NdSCxR=X|W%I;Y#5>2f4pzjsex%-G)&F2S@){kRTKl?t zB3La|I7ZScWm1>Eo~a}epeIAuO0?HA2`s64gMbT{R>QaTXSjIB`M;e5LZ!A~defO@ zAeCHb6(l&=qMf(rNq!e4c32}DGvlxtTt3aWv;nM+WA1}$u=s?jrwh{G(Gz9DoStLlmIBMf1^^kRpdSKYL~6*T#E=CL!|rq!s^^Rph5-QK~iCN{(i zYePStZr&~jzo^2}X)g6KO{>}_pUq2_VL$&}aKB^XtuD~kdrrDXRRuT0JPtO4CLyG! z%bUTZWrv6fZi&?%>6k=JE1>Z}I&tbEuTYSL)ztKMkV3!G__X-0;*!Z8YgT?qGpL{y zZ`)KBR=of2C;hsTR{i?HGX#!RL2jX7sZ(OYbNE%$m7!DnTfs`=(_JQ7O`YNeI=cHh zpHKRF%}dumA9Nb9E!eE)RiEeLm52Vrp#CP|l| zrxO|B0YS`q4mT>Ym#n$C<)jJTE6GuO=v{D4%H62Jv+*?5mK8!kbc6zfGY8ngsWb4LVI6L_S++-og03m>z+# z7#whPqbvGI0`Qt-4u0^RXLob1Nw^!ivG|2?F%@02yX&jS`Qt_y!q+dE!_6NKw!pRf z!=^W!7_7fz-bEN?2{WiR@4D_1A4nI(x>8&qxo0mo(^WvZl~ly^VW@x^)|T7Xe@yEd z!2RCGF}ju|wa=c=+!(rku;RC!$hXCqVW7RgC2HK%TKA|d)=FSLO{wgU6>BkNq|UIJ@fb0z z)y6;bl$tiHP`2%ptC9f94d=VIxBFo)!a_@&wU(jvj3xvFSy``2gh-AXi&rE8oirA> zEbA!5*msM;W_853y_TY#i;Cc@S0ijM2EIa#IKSoO=T|rsZJ@R{%7@zav7}QyZLI+D zk4I&#KdY?Vmp0g$5=^CXLgNC1D=CX3xuu~_qSyL|d?WSVO6jUK)P!$?%YScKE#@)~ zuyZ-6dmr_TEoAL3`F&Eg8%t#9ReAr>P)7mtyu#RI{k}HeAO176{{H^ozhX{)@7}|| zZD6gnDTie>tAx1{x6K74l+J5m*T~dh)(qgy*Ea=IM-sF*!WR79Y=xlBR;riqyMn6? zZpaRWksWM0{^e`6YNG zoc8?tjAxf{BGY4n^ zQ+*ygIhPmEFoCpoS3~On`vy7Em|wrA51#;~>JLuGS-QWarDf)-ihbk-xx35WZtnLw zxy(|#xczix6&2dqP;hOqnLJ2Aev>yqs@V{}v-G%aTD%lPMK<(XSXh|u|G^fSt|!Qk zs1L#xGWEo#55*7}z`pVUWiPwG5AwN7YuqU@>zSf_+^F_?Jwbmf4JDKrgP%$|k=D_+ zv^**$ z(RPwclKxU63rR&;Qmfhfk=F{EQT0I=8vt;Svw;Thlt(#xqO^>~;73W1gI4R-r8-ir zX!T2n??S?4KQ!h&cBDD$#Jp^^2Nj)W=I;53gdxizo+9)zOIIOHt49cQkPWtJ z8^dWK+oifEL3p&GJnytUWJe0;5@g}84GHE>HrcWKqMnqBbcY*oEKJfcN($4*x4xnW z-Et3&HLI`$L|K+pHA9nqFCY_Jj7OG;b{W zx0_2V`Mx41(6Tn1_r3&WI6iCyPx|(g+Nl@ke6u?2FnxL4m67iPcwSO7?iTI>-E(1j z0T8IHS-q!YRlDtl5e4)hju$%%JUjsnVg1Jrr)`v&vp=qLR7VAW_qxY(3j@m7;i&HB z-FL{86L~o5msvA;`-+7D(`woWTC1`fEc*b%T2)c;PC?N8fxv98l8%HSdLT&LVO+#c znL$g1W(bDq<88nTKhwCrSfSZ7Ct9W>Hc{N$v3ql^nYQxkQrdmZeoq90SUm9*-NPF{79rzy?cQgWM z>V{8ShCCNG`g)S(E&wC@d2ZDtAH2`2OZF7`E=dP;?2Ptfez^#$|8Ytvr|s8R>*jmE zb8zlww;;z~tou@}A4eNo3!{h@%}FG=P$;*=iXVxUPG(U^UDrvHOH{mvGgzekJYZz2 zI2D;G{h%D2+F)&^X*Kf60*q`J?Jr@T6u;wnyf}4DwjF(W@w(omG9-HPSRe?qiDjG0 z%n}LT*wq(95q#xkUfT*#>gGYFu{CzXi2Ukj)xJAU)4FT-GT9qHw<&vl7`v}pIPMWs z*PXAV4rRQFl>j3I@gjNTWZpYiK{2n593S7D+Hem?`n^C8>(CjLj^V1OCAD4=nH2k@ z*qIu908PQ zmgVJ9TAFA>k*EvyXB&^@etvP)_219?Ut66{s1wYXiv4gq*4|nPpQix($%nIe0?t~i zi(~gCPYh3w;4oJ1PG_lnK_QRoFa=A6jnq`KWEg>>g@R0Nm6i^KerN#ghd5GR_m_t{J@w>-2=Nn>d(e1)^oVH-HAzxPjU@)YmxcwKOpvh z*zw)|V{(2ICbN5~&Q_d}mx^~IB2z>X-k_j5v9`D9OY*lspU*uKN%mA=%zCY2+$yV_ z;svb0rbR=Z&OR?Amu;r9glvS3e zZVj2JN$YjV%cATK)KkC=dy&BgZGb$C1kJ0YlBUY(VW4?TkyQ`sICnW?Wt1PYJ!@ z80xx*&GeF5;UKw@JX~=m+LT0$)70?;m+o0Ldo$MSezPr{Xy0WWp1GXFhJLa8c_sGZ z(8~-ee94{Ejoe#)YJ`N_Oyah%U;Ynh{VR5I>OQo$l2|090qjPuc#f33nr@ED|_fcn!hJwnLmG*nESQ_Je=-;yeUI3dmHz> z(H58-F|r-l?XYt_Tf1 zSebCCb}Wa0wemFcao@2pY$0mtp8rqvzZxlnKOBW+Vf?~c4wS+Y1#5v+!CiG`EG_4> zNFbFNTY!eUagK>(RSynS+cLze&Qi8Z10c?|y8%(7R-GoCA-}#WgAY3S=jIB(yN3b} zPEbcQ3>=R6Xf#v3-~SbOpW{h4n^Kfy@pw;H$+Vlk>M<@0tUq!-{Zk79eXO@{dC;kT4HtCSe{+Ex>v_s`H?jciRy{QQ6Qik4Wm>_(4xfDK>V5OcC zq%y&CXJ7fZ)#${^_5Bf~Qpo#LoXD%t3U{ZY>d6mP{d>i!ec#SiSd*_c5Q8(OFK>Wa z4TNjNvy7EVug4`yyNGr|)+8H$Raz5CS);%Nqs~MR&};QU>(jJ}kcXb=YQ_Wy_>zgy znK;&6Y?l&zD$qQ4s-$EX*^HX8uv#ZId>9w&XhE1E3o{&$3)D}L_AA@|8$>zfrZ>e^sNAwbqLGd&X%UNICszkkq}c1 z^s&0N>k+Bwz2=n2g*BLUz4O&#|2Am!+7Mi$qs89E%41v99CzGJUJ(P%+&>lf7ts(S z4;ZoWZF1yLd0v#HBkN7uGCbYQn+UMbwb2ORi-7wNJ6hjG?`Qr2jsL5g zf016z=<^RpU-FUWc?SFEv$P{q=C}!+u!FMKMPiD|!JHrFF#IuNdbAmE5VuuPo%Yak ztWJ6zPIIyT=fQp`@YgX?2{f#=!h^aYI96a!R~|t{j=jC(QDFD}<0@1zxy(G}lXj50q#N<4W1o6?~V}=$LB8xIR25e@0Tkoiw1YHGvp7D=k zS;_RX8rhb8_sTG<0QhN=BD-JsvZmJ#-j4Wqa9D1Jzu}&1D4p(~U$kSFCHi=(tVJQ? ze)rLs2F`sLe-&o*mZ2w?%zENB*=nL#dt!e_H@tN*wJ)>dwWo@odd|qOM>0#Ae)ZlE zrK<|MC)7&n-oScQf_zN4h<1SgFM^+_Jc@6^)cw-aSFt3(agrM}E>6!UcX%ChMdFcqnuYcCm?T^KlrA$y zc8td@poT~LB`<5ProQT0Sln1Rb~-MSNTHNndq2i~Ax^Tz`T9tyWc@UO+1fbB$8it8 z1QjqhD1#Vm4yzK}>^{12(YWM;RoRvgT{`!E#pSs-A)-Z3GC<;%uS%VBBMn`XIEs zCbK$C1GJ+)2^p+@+qx($nnsm68Bh(h6>1t&*2ude&Ea8HtRUvI4;BXT2LRG#;O;db zsQW@gpT&)!l>X&_$H7(RB$Fi#Ihh**#n9hWPaKODE~&d&;QdwSQbd33NZ?lt8uE_aWvVVF4Kf7o_1ntM{^v8Z&u&n#*$o}cf^ZZcPRd&x6M8@N( zuS{Opm$1A<%6>OseU2OoW8;rJxo%yX1exFR-J=CXpZCPFQfEU@I9Wn<1KJaL1K9~- zs0$HR4{H|pLGJx{ zR^2k?bkOPzb-Xx8s8kT_uT?PZ7Nf&QPzMvk5I?W9P$ozOvHmelp#Z^dFCEw0Nmj3c zF&%ZuN1l#huMsl2e$s4wWn!oA0d|LP0A%L4n8vR<(X+#j^;fT=i@iG4{5RDTCv~>w zq25RDj9;W;Qd|)Z3Ane9J!LvE&trT!#xGNB!#Z2ia#dOl$TP{>b3M&SMRUP}*T4Mk*K`#k1d?1ssyiUW}R3p7I@{}*YjP{~T>vgXuqtLGA zR(b_vNG&c~&+4ioy!$5{m+3f)&n%+eK9H%kcs#WHQG(rz(
M_IqaRQn3&(RyO4 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

%;m8zLL-}GrIQU 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≥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 C`I-LgxN+@Yc=hz2+YGGAV-?pSOnVCJ1h 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 z%0A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 Fe*o0EI-CFi literal 0 HcmV?d00001 From 46f86243356bd0cfb2bd6d367adfc69b7d3e2a0f Mon Sep 17 00:00:00 2001 From: Release bot Date: Tue, 25 Apr 2023 11:56:21 +0000 Subject: [PATCH 072/100] update changelog with latest changes --- CHANGELOG.md | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aaec15e4ed9..fbaa3e70882 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,27 @@ ## Bug Fixes +* typo + +## Documentation + +* **homepage:** add customer references section ([#2159](https://github.com/awslabs/aws-lambda-powertools-python/issues/2159)) + +## Features + +* **ci:** dispatch GitHub analytics action ([#2161](https://github.com/awslabs/aws-lambda-powertools-python/issues/2161)) + +## Maintenance + +* add dummy reusable dispatch analytics job +* **deps-dev:** bump mkdocs-material from 9.1.6 to 9.1.8 ([#2162](https://github.com/awslabs/aws-lambda-powertools-python/issues/2162)) +* **deps-dev:** bump importlib-metadata from 6.5.0 to 6.6.0 ([#2163](https://github.com/awslabs/aws-lambda-powertools-python/issues/2163)) + + + +## [v2.14.1] - 2023-04-21 +## Bug Fixes + * **batch:** resolve use of ValidationError in batch ([#2157](https://github.com/awslabs/aws-lambda-powertools-python/issues/2157)) * **e2e:** fix test brittleness ([#2152](https://github.com/awslabs/aws-lambda-powertools-python/issues/2152)) @@ -19,14 +40,15 @@ ## Maintenance +* update v2 layer ARN on documentation * add Python 3.10 PyPi language classifier ([#2144](https://github.com/awslabs/aws-lambda-powertools-python/issues/2144)) * update v2 layer ARN on documentation * **batch:** safeguard custom use of BatchProcessingError exception ([#2155](https://github.com/awslabs/aws-lambda-powertools-python/issues/2155)) * **deps:** bump codecov/codecov-action from 3.1.2 to 3.1.3 ([#2153](https://github.com/awslabs/aws-lambda-powertools-python/issues/2153)) * **deps:** bump dependabot/fetch-metadata from 1.3.6 to 1.4.0 ([#2140](https://github.com/awslabs/aws-lambda-powertools-python/issues/2140)) * **deps-dev:** bump aws-cdk from 2.75.0 to 2.75.1 ([#2150](https://github.com/awslabs/aws-lambda-powertools-python/issues/2150)) -* **deps-dev:** bump mypy-boto3-secretsmanager from 1.26.89 to 1.26.116 ([#2147](https://github.com/awslabs/aws-lambda-powertools-python/issues/2147)) * **deps-dev:** bump aws-cdk from 2.75.1 to 2.76.0 ([#2154](https://github.com/awslabs/aws-lambda-powertools-python/issues/2154)) +* **deps-dev:** bump mypy-boto3-secretsmanager from 1.26.89 to 1.26.116 ([#2147](https://github.com/awslabs/aws-lambda-powertools-python/issues/2147)) * **deps-dev:** bump importlib-metadata from 6.4.1 to 6.5.0 ([#2141](https://github.com/awslabs/aws-lambda-powertools-python/issues/2141)) * **deps-dev:** bump mypy-boto3-s3 from 1.26.104 to 1.26.116 ([#2149](https://github.com/awslabs/aws-lambda-powertools-python/issues/2149)) * **deps-dev:** bump filelock from 3.11.0 to 3.12.0 ([#2142](https://github.com/awslabs/aws-lambda-powertools-python/issues/2142)) @@ -3164,7 +3186,8 @@ * Merge pull request [#5](https://github.com/awslabs/aws-lambda-powertools-python/issues/5) from jfuss/feat/python38 -[Unreleased]: https://github.com/awslabs/aws-lambda-powertools-python/compare/v2.14.0...HEAD +[Unreleased]: https://github.com/awslabs/aws-lambda-powertools-python/compare/v2.14.1...HEAD +[v2.14.1]: https://github.com/awslabs/aws-lambda-powertools-python/compare/v2.14.0...v2.14.1 [v2.14.0]: https://github.com/awslabs/aws-lambda-powertools-python/compare/v2.13.0...v2.14.0 [v2.13.0]: https://github.com/awslabs/aws-lambda-powertools-python/compare/v2.12.0...v2.13.0 [v2.12.0]: https://github.com/awslabs/aws-lambda-powertools-python/compare/v2.11.0...v2.12.0 From 31eaa2ecc9c6e417bfc1e8ef0bb3839571a99ec3 Mon Sep 17 00:00:00 2001 From: Leandro Damascena Date: Tue, 25 Apr 2023 21:25:25 +0100 Subject: [PATCH 073/100] parser(sqs3): fixing mypy errors and adding documentation --- .../utilities/parser/models/s3_event_notification.py | 2 +- aws_lambda_powertools/utilities/parser/models/sqs.py | 4 ++-- docs/utilities/parser.md | 1 + tests/functional/parser/test_sqs_s3_event_notification.py | 4 +++- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/aws_lambda_powertools/utilities/parser/models/s3_event_notification.py b/aws_lambda_powertools/utilities/parser/models/s3_event_notification.py index 37d77821099..e3bedb2b0b0 100644 --- a/aws_lambda_powertools/utilities/parser/models/s3_event_notification.py +++ b/aws_lambda_powertools/utilities/parser/models/s3_event_notification.py @@ -3,7 +3,7 @@ from pydantic import Json from aws_lambda_powertools.utilities.parser.models.s3 import S3Model -from aws_lambda_powertools.utilities.parser.models.sqs import SqsRecordModel, SqsModel +from aws_lambda_powertools.utilities.parser.models.sqs import SqsModel, SqsRecordModel class SqsS3EventNotificationRecordModel(SqsRecordModel): diff --git a/aws_lambda_powertools/utilities/parser/models/sqs.py b/aws_lambda_powertools/utilities/parser/models/sqs.py index c92a8361b7c..a1c172c20fc 100644 --- a/aws_lambda_powertools/utilities/parser/models/sqs.py +++ b/aws_lambda_powertools/utilities/parser/models/sqs.py @@ -1,5 +1,5 @@ from datetime import datetime -from typing import Dict, List, Optional, Type, Union +from typing import Dict, List, Optional, Sequence, Type, Union from pydantic import BaseModel @@ -63,4 +63,4 @@ class SqsRecordModel(BaseModel): class SqsModel(BaseModel): - Records: List[SqsRecordModel] + Records: Sequence[SqsRecordModel] diff --git a/docs/utilities/parser.md b/docs/utilities/parser.md index 66103ad474b..9b450e3abf6 100644 --- a/docs/utilities/parser.md +++ b/docs/utilities/parser.md @@ -175,6 +175,7 @@ Parser comes with the following built-in models: | **LambdaFunctionUrlModel** | Lambda Event Source payload for Lambda Function URL payload | | **KafkaSelfManagedEventModel** | Lambda Event Source payload for self managed Kafka payload | | **KafkaMskEventModel** | Lambda Event Source payload for AWS MSK payload | +| **SqsS3EventNotificationModel** | Lambda Event Source payload for SQS-wrapped S3 event notifications | #### Extending built-in models diff --git a/tests/functional/parser/test_sqs_s3_event_notification.py b/tests/functional/parser/test_sqs_s3_event_notification.py index 75c35af7773..21b0781a6bf 100644 --- a/tests/functional/parser/test_sqs_s3_event_notification.py +++ b/tests/functional/parser/test_sqs_s3_event_notification.py @@ -18,7 +18,9 @@ def test_handle_sqs_json_body_containing_s3_notifications(): for record in sqs_event_dict["Records"]: record["body"] = json_serialize(s3_event_notification_dict) - parsed_event: SqsS3EventNotificationModel = handle_sqs_json_body_containing_s3_notifications(sqs_event_dict, LambdaContext()) + parsed_event: SqsS3EventNotificationModel = handle_sqs_json_body_containing_s3_notifications( + sqs_event_dict, LambdaContext() + ) assert len(parsed_event.Records) == 2 for parsed_sqs_record in parsed_event.Records: From 11b6a3744aaa3653b7e7d1924e7f88eb9088a72b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 25 Apr 2023 22:15:09 +0100 Subject: [PATCH 074/100] chore(deps-dev): bump cfn-lint from 0.77.2 to 0.77.3 (#2165) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 8 ++++---- pyproject.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/poetry.lock b/poetry.lock index c877e758a2e..614a377adc9 100644 --- a/poetry.lock +++ b/poetry.lock @@ -370,14 +370,14 @@ files = [ [[package]] name = "cfn-lint" -version = "0.77.2" +version = "0.77.3" description = "Checks CloudFormation templates for practices and behaviour that could potentially be improved" category = "dev" optional = false python-versions = ">=3.7, <=4.0, !=4.0" files = [ - {file = "cfn-lint-0.77.2.tar.gz", hash = "sha256:a720fdbd68b7ada0fcef2ee65fc17c67f5dbd03797d9117eee7c18bb2cb49a2c"}, - {file = "cfn_lint-0.77.2-py3-none-any.whl", hash = "sha256:d1b508824ed47d622dee07f270f04a7cbbe05d2230d7bfb10641964e6d65500a"}, + {file = "cfn-lint-0.77.3.tar.gz", hash = "sha256:d2a51a0ee222f3772fd87c3e4de82c59539172db34c2e5dc60ead7ce354365e0"}, + {file = "cfn_lint-0.77.3-py3-none-any.whl", hash = "sha256:cad9219416acc198d162ece4a1039e914852e71b96c9022b0b6f5faa676daa89"}, ] [package.dependencies] @@ -3035,4 +3035,4 @@ validation = ["fastjsonschema"] [metadata] lock-version = "2.0" python-versions = "^3.7.4" -content-hash = "52d4c322f52727590fb17436b95d67abf0bb17c58696d77bd0f82826000f8113" +content-hash = "0ec22c8c2a10a974b5e9dd5acc5314cd646524b59019bcaea28364c0f898d697" diff --git a/pyproject.toml b/pyproject.toml index 607e7c6f09c..6f893fc2e88 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -101,7 +101,7 @@ all = ["pydantic", "aws-xray-sdk", "fastjsonschema"] aws-sdk = ["boto3"] [tool.poetry.group.dev.dependencies] -cfn-lint = "0.77.2" +cfn-lint = "0.77.3" mypy = "^1.1.1" types-python-dateutil = "^2.8.19.6" httpx = ">=0.23.3,<0.25.0" From 4663745f838c142690d4d1bc882f8e9b4e6501e5 Mon Sep 17 00:00:00 2001 From: Neil Ramsay Date: Thu, 27 Apr 2023 00:11:39 +1200 Subject: [PATCH 075/100] feat(event_sources): Add __str__ to Data Classes base DictWrapper (#2129) Co-authored-by: Neil Ramsay Co-authored-by: Leandro Damascena Co-authored-by: Heitor Lessa --- .../data_classes/code_pipeline_job_event.py | 2 + .../utilities/data_classes/common.py | 45 +++++- docs/utilities/data_classes.md | 41 +++++ examples/event_sources/src/debugging.py | 9 ++ .../event_sources/src/debugging_event.json | 34 +++++ .../event_sources/src/debugging_output.json | 50 ++++++ tests/functional/test_data_classes.py | 144 ++++++++++++++++++ 7 files changed, 324 insertions(+), 1 deletion(-) create mode 100644 examples/event_sources/src/debugging.py create mode 100644 examples/event_sources/src/debugging_event.json create mode 100644 examples/event_sources/src/debugging_output.json diff --git a/aws_lambda_powertools/utilities/data_classes/code_pipeline_job_event.py b/aws_lambda_powertools/utilities/data_classes/code_pipeline_job_event.py index a4139ebbe68..c502aacb090 100644 --- a/aws_lambda_powertools/utilities/data_classes/code_pipeline_job_event.py +++ b/aws_lambda_powertools/utilities/data_classes/code_pipeline_job_event.py @@ -80,6 +80,8 @@ def location(self) -> CodePipelineLocation: class CodePipelineArtifactCredentials(DictWrapper): + _sensitive_properties = ["secret_access_key", "session_token"] + @property def access_key_id(self) -> str: return self["accessKeyId"] diff --git a/aws_lambda_powertools/utilities/data_classes/common.py b/aws_lambda_powertools/utilities/data_classes/common.py index fa0d479af8a..5c1fea14731 100644 --- a/aws_lambda_powertools/utilities/data_classes/common.py +++ b/aws_lambda_powertools/utilities/data_classes/common.py @@ -1,7 +1,7 @@ import base64 import json from collections.abc import Mapping -from typing import Any, Dict, Iterator, Optional +from typing import Any, Dict, Iterator, List, Optional from aws_lambda_powertools.shared.headers_serializer import BaseHeadersSerializer @@ -28,6 +28,49 @@ def __iter__(self) -> Iterator: def __len__(self) -> int: return len(self._data) + def __str__(self) -> str: + return str(self._str_helper()) + + def _str_helper(self) -> Dict[str, Any]: + """ + Recursively get a Dictionary of DictWrapper properties primarily + for use by __str__ for debugging purposes. + + Will remove "raw_event" properties, and any defined by the Data Class + `_sensitive_properties` list field. + This should be used in case where secrets, such as access keys, are + stored in the Data Class but should not be logged out. + """ + properties = self._properties() + sensitive_properties = ["raw_event"] + if hasattr(self, "_sensitive_properties"): + sensitive_properties.extend(self._sensitive_properties) # pyright: ignore + + result: Dict[str, Any] = {} + for property_key in properties: + if property_key in sensitive_properties: + result[property_key] = "[SENSITIVE]" + else: + try: + property_value = getattr(self, property_key) + result[property_key] = property_value + + # Checks whether the class is a subclass of the parent class to perform a recursive operation. + if issubclass(property_value.__class__, DictWrapper): + result[property_key] = property_value._str_helper() + # Checks if the key is a list and if it is a subclass of the parent class + elif isinstance(property_value, list): + for seq, item in enumerate(property_value): + if issubclass(item.__class__, DictWrapper): + result[property_key][seq] = item._str_helper() + except Exception: + result[property_key] = "[Cannot be deserialized]" + + return result + + def _properties(self) -> List[str]: + return [p for p in dir(self.__class__) if isinstance(getattr(self.__class__, p), property)] + def get(self, key: str, default: Optional[Any] = None) -> Optional[Any]: return self._data.get(key, default) diff --git a/docs/utilities/data_classes.md b/docs/utilities/data_classes.md index 169133788ad..04779ccf0f5 100644 --- a/docs/utilities/data_classes.md +++ b/docs/utilities/data_classes.md @@ -52,6 +52,22 @@ Same example as above, but using the `event_source` decorator if 'helloworld' in event.path and event.http_method == 'GET': do_something_with(event.body, user) ``` + +Log Data Event for Troubleshooting + +=== "app.py" + + ```python hl_lines="4 8" + from aws_lambda_powertools.utilities.data_classes import event_source, APIGatewayProxyEvent + from aws_lambda_powertools.logging.logger import Logger + + logger = Logger(service="hello_logs", level="DEBUG") + + @event_source(data_class=APIGatewayProxyEvent) + def lambda_handler(event: APIGatewayProxyEvent, context): + logger.debug(event) + ``` + **Autocomplete with self-documented properties and methods** ![Utilities Data Classes](../media/utilities_data_classes.png) @@ -1104,3 +1120,28 @@ This example is based on the AWS Blog post [Introducing Amazon S3 Object Lambda for record in event.records: do_something_with(record.body) ``` + +## Advanced + +### Debugging + +Alternatively, you can print out the fields to obtain more information. All classes come with a `__str__` method that generates a dictionary string which can be quite useful for debugging. + +However, certain events may contain sensitive fields such as `secret_access_key` and `session_token`, which are labeled as `[SENSITIVE]` to prevent any accidental disclosure of confidential information. + +!!! warning "If we fail to deserialize a field value (e.g., JSON), they will appear as `[Cannot be deserialized]`" + +=== "debugging.py" + ```python hl_lines="9" + --8<-- "examples/event_sources/src/debugging.py" + ``` + +=== "debugging_event.json" + ```json hl_lines="28 29" + --8<-- "examples/event_sources/src/debugging_event.json" + ``` +=== "debugging_output.json" + ```json hl_lines="16 17 18" + --8<-- "examples/event_sources/src/debugging_output.json" + ``` + ``` diff --git a/examples/event_sources/src/debugging.py b/examples/event_sources/src/debugging.py new file mode 100644 index 00000000000..a03bf823885 --- /dev/null +++ b/examples/event_sources/src/debugging.py @@ -0,0 +1,9 @@ +from aws_lambda_powertools.utilities.data_classes import ( + CodePipelineJobEvent, + event_source, +) + + +@event_source(data_class=CodePipelineJobEvent) +def lambda_handler(event, context): + print(event) diff --git a/examples/event_sources/src/debugging_event.json b/examples/event_sources/src/debugging_event.json new file mode 100644 index 00000000000..a95c3d57e86 --- /dev/null +++ b/examples/event_sources/src/debugging_event.json @@ -0,0 +1,34 @@ +{ + "CodePipeline.job": { + "id": "11111111-abcd-1111-abcd-111111abcdef", + "accountId": "111111111111", + "data": { + "actionConfiguration": { + "configuration": { + "FunctionName": "MyLambdaFunctionForAWSCodePipeline", + "UserParameters": "some-input-such-as-a-URL" + } + }, + "inputArtifacts": [ + { + "name": "ArtifactName", + "revision": null, + "location": { + "type": "S3", + "s3Location": { + "bucketName": "the name of the bucket configured as the pipeline artifact store in Amazon S3, for example codepipeline-us-east-2-1234567890", + "objectKey": "the name of the application, for example CodePipelineDemoApplication.zip" + } + } + } + ], + "outputArtifacts": [], + "artifactCredentials": { + "accessKeyId": "AKIAIOSFODNN7EXAMPLE", + "secretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", + "sessionToken": "MIICiTCCAfICCQD6m7oRw0uXOjANBgkqhkiG9w0BAQUFADCBiDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAldBMRAwDgYDVQQHEwdTZWF0dGxlMQ8wDQYDVQQKEwZBbWF6b24xFDASBgNVBAsTC0lBTSBDb25zb2xlMRIwEAYDVQQDEwlUZXN0Q2lsYWMxHzAdBgkqhkiG9w0BCQEWEG5vb25lQGFtYXpvbi5jb20wHhcNMTEwNDI1MjA0NTIxWhcNMTIwNDI0MjA0NTIxWjCBiDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAldBMRAwDgYDVQQHEwdTZWF0dGxlMQ8wDQYDVQQKEwZBbWF6b24xFDASBgNVBAsTC0lBTSBDb25zb2xlMRIwEAYDVQQDEwlUZXN0Q2lsYWMxHzAdBgkqhkiG9w0BCQEWEG5vb25lQGFtYXpvbi5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMaK0dn+a4GmWIWJ21uUSfwfEvySWtC2XADZ4nB+BLYgVIk60CpiwsZ3G93vUEIO3IyNoH/f0wYK8m9TrDHudUZg3qX4waLG5M43q7Wgc/MbQITxOUSQv7c7ugFFDzQGBzZswY6786m86gpEIbb3OhjZnzcvQAaRHhdlQWIMm2nrAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAtCu4nUhVVxYUntneD9+h8Mg9q6q+auNKyExzyLwaxlAoo7TJHidbtS4J5iNmZgXL0FkbFFBjvSfpJIlJ00zbhNYS5f6GuoEDmFJl0ZxBHjJnyp378OD8uTs7fLvjx79LjSTbNYiytVbZPQUQ5Yaxu2jXnimvw3rrszlaEXAMPLE=" + }, + "continuationToken": "A continuation token if continuing job" + } + } + } diff --git a/examples/event_sources/src/debugging_output.json b/examples/event_sources/src/debugging_output.json new file mode 100644 index 00000000000..f13d6380afe --- /dev/null +++ b/examples/event_sources/src/debugging_output.json @@ -0,0 +1,50 @@ +{ + "account_id":"111111111111", + "data":{ + "action_configuration":{ + "configuration":{ + "decoded_user_parameters":"[Cannot be deserialized]", + "function_name":"MyLambdaFunctionForAWSCodePipeline", + "raw_event":"[SENSITIVE]", + "user_parameters":"some-input-such-as-a-URL" + }, + "raw_event":"[SENSITIVE]" + }, + "artifact_credentials":{ + "access_key_id":"AKIAIOSFODNN7EXAMPLE", + "expiration_time":"None", + "raw_event":"[SENSITIVE]", + "secret_access_key":"[SENSITIVE]", + "session_token":"[SENSITIVE]" + }, + "continuation_token":"A continuation token if continuing job", + "encryption_key":"None", + "input_artifacts":[ + { + "location":{ + "get_type":"S3", + "raw_event":"[SENSITIVE]", + "s3_location":{ + "bucket_name":"the name of the bucket configured as the pipeline artifact store in Amazon S3, for example codepipeline-us-east-2-1234567890", + "key":"the name of the application, for example CodePipelineDemoApplication.zip", + "object_key":"the name of the application, for example CodePipelineDemoApplication.zip", + "raw_event":"[SENSITIVE]" + } + }, + "name":"ArtifactName", + "raw_event":"[SENSITIVE]", + "revision":"None" + } + ], + "output_artifacts":[ + + ], + "raw_event":"[SENSITIVE]" + }, + "decoded_user_parameters":"[Cannot be deserialized]", + "get_id":"11111111-abcd-1111-abcd-111111abcdef", + "input_bucket_name":"the name of the bucket configured as the pipeline artifact store in Amazon S3, for example codepipeline-us-east-2-1234567890", + "input_object_key":"the name of the application, for example CodePipelineDemoApplication.zip", + "raw_event":"[SENSITIVE]", + "user_parameters":"some-input-such-as-a-URL" + } diff --git a/tests/functional/test_data_classes.py b/tests/functional/test_data_classes.py index 37b934d478e..068e8738fad 100644 --- a/tests/functional/test_data_classes.py +++ b/tests/functional/test_data_classes.py @@ -126,6 +126,150 @@ class DataClassSample(DictWrapper): assert event_source.items() == data.items() +def test_dict_wrapper_str_no_property(): + """ + Checks that the _properties function returns + only the "raw_event", and the resulting string + notes it as sensitive. + """ + + class DataClassSample(DictWrapper): + attribute = None + + def function(self) -> None: + pass + + event_source = DataClassSample({}) + assert str(event_source) == "{'raw_event': '[SENSITIVE]'}" + + +def test_dict_wrapper_str_single_property(): + """ + Checks that the _properties function returns + the defined property "data_property", and + resulting string includes the property value. + """ + + class DataClassSample(DictWrapper): + attribute = None + + def function(self) -> None: + pass + + @property + def data_property(self) -> str: + return "value" + + event_source = DataClassSample({}) + assert str(event_source) == "{'data_property': 'value', 'raw_event': '[SENSITIVE]'}" + + +def test_dict_wrapper_str_property_exception(): + """ + Check the recursive _str_helper function handles + exceptions that may occur when accessing properties + """ + + class DataClassSample(DictWrapper): + attribute = None + + def function(self) -> None: + pass + + @property + def data_property(self): + raise Exception() + + event_source = DataClassSample({}) + assert str(event_source) == "{'data_property': '[Cannot be deserialized]', 'raw_event': '[SENSITIVE]'}" + + +def test_dict_wrapper_str_property_list_exception(): + """ + Check that _str_helper properly handles exceptions + that occur when recursively working through items + in a list property. + """ + + class BrokenDataClass(DictWrapper): + @property + def broken_data_property(self): + raise Exception() + + class DataClassSample(DictWrapper): + attribute = None + + def function(self) -> None: + pass + + @property + def data_property(self) -> list: + return ["string", 0, 0.0, BrokenDataClass({})] + + event_source = DataClassSample({}) + event_str = ( + "{'data_property': ['string', 0, 0.0, {'broken_data_property': " + + "'[Cannot be deserialized]', 'raw_event': '[SENSITIVE]'}], 'raw_event': '[SENSITIVE]'}" + ) + assert str(event_source) == event_str + + +def test_dict_wrapper_str_recursive_property(): + """ + Check that the _str_helper function recursively + handles Data Classes within Data Classes + """ + + class DataClassTerminal(DictWrapper): + attribute = None + + def function(self) -> None: + pass + + @property + def terminal_property(self) -> str: + return "end-recursion" + + class DataClassRecursive(DictWrapper): + attribute = None + + def function(self) -> None: + pass + + @property + def data_property(self) -> DataClassTerminal: + return DataClassTerminal({}) + + event_source = DataClassRecursive({}) + assert ( + str(event_source) + == "{'data_property': {'raw_event': '[SENSITIVE]', 'terminal_property': 'end-recursion'}," + + " 'raw_event': '[SENSITIVE]'}" + ) + + +def test_dict_wrapper_sensitive_properties_property(): + """ + Checks that the _str_helper function correctly + handles _sensitive_properties + """ + + class DataClassSample(DictWrapper): + attribute = None + + def function(self) -> None: + pass + + _sensitive_properties = ["data_property"] + + @property + def data_property(self) -> str: + return "value" + + event_source = DataClassSample({}) + assert str(event_source) == "{'data_property': '[SENSITIVE]', 'raw_event': '[SENSITIVE]'}" + + def test_cloud_watch_dashboard_event(): event = CloudWatchDashboardCustomWidgetEvent(load_event("cloudWatchDashboardEvent.json")) assert event.describe is False From e9f838329caea643b5ced6ef5eb5c340d9074f36 Mon Sep 17 00:00:00 2001 From: Release bot Date: Wed, 26 Apr 2023 12:12:06 +0000 Subject: [PATCH 076/100] update changelog with latest changes --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fbaa3e70882..6961f5ed743 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,10 +15,12 @@ ## Features * **ci:** dispatch GitHub analytics action ([#2161](https://github.com/awslabs/aws-lambda-powertools-python/issues/2161)) +* **event_sources:** Add __str__ to Data Classes base DictWrapper ([#2129](https://github.com/awslabs/aws-lambda-powertools-python/issues/2129)) ## Maintenance * add dummy reusable dispatch analytics job +* **deps-dev:** bump cfn-lint from 0.77.2 to 0.77.3 ([#2165](https://github.com/awslabs/aws-lambda-powertools-python/issues/2165)) * **deps-dev:** bump mkdocs-material from 9.1.6 to 9.1.8 ([#2162](https://github.com/awslabs/aws-lambda-powertools-python/issues/2162)) * **deps-dev:** bump importlib-metadata from 6.5.0 to 6.6.0 ([#2163](https://github.com/awslabs/aws-lambda-powertools-python/issues/2163)) From f1185836ff023cbe831a11588740013cd099fb61 Mon Sep 17 00:00:00 2001 From: Leandro Damascena Date: Wed, 26 Apr 2023 17:25:10 +0100 Subject: [PATCH 077/100] parser(sqs3): improving documentation, refactoring classname and tests --- .../utilities/parser/models/__init__.py | 8 ++-- .../parser/models/s3_event_notification.py | 6 +-- docs/utilities/parser.md | 40 ++++++++--------- tests/events/sqsS3Event.json | 22 ++++++++++ .../parser/test_sqs_s3_event_notification.py | 43 ------------------- tests/unit/parser/test_s3.py | 35 +++++++++++++++ 6 files changed, 84 insertions(+), 70 deletions(-) create mode 100644 tests/events/sqsS3Event.json delete mode 100644 tests/functional/parser/test_sqs_s3_event_notification.py diff --git a/aws_lambda_powertools/utilities/parser/models/__init__.py b/aws_lambda_powertools/utilities/parser/models/__init__.py index 26b68359da3..5f7a8a6b550 100644 --- a/aws_lambda_powertools/utilities/parser/models/__init__.py +++ b/aws_lambda_powertools/utilities/parser/models/__init__.py @@ -51,8 +51,8 @@ S3RecordModel, ) from .s3_event_notification import ( - SqsS3EventNotificationModel, - SqsS3EventNotificationRecordModel, + S3SqsEventNotificationModel, + S3SqsEventNotificationRecordModel, ) from .s3_object_event import ( S3ObjectConfiguration, @@ -134,8 +134,8 @@ "SqsRecordModel", "SqsMsgAttributeModel", "SqsAttributesModel", - "SqsS3EventNotificationModel", - "SqsS3EventNotificationRecordModel", + "S3SqsEventNotificationModel", + "S3SqsEventNotificationRecordModel", "APIGatewayProxyEventModel", "APIGatewayEventRequestContext", "APIGatewayEventAuthorizer", diff --git a/aws_lambda_powertools/utilities/parser/models/s3_event_notification.py b/aws_lambda_powertools/utilities/parser/models/s3_event_notification.py index e3bedb2b0b0..1bcbc83ac18 100644 --- a/aws_lambda_powertools/utilities/parser/models/s3_event_notification.py +++ b/aws_lambda_powertools/utilities/parser/models/s3_event_notification.py @@ -6,9 +6,9 @@ from aws_lambda_powertools.utilities.parser.models.sqs import SqsModel, SqsRecordModel -class SqsS3EventNotificationRecordModel(SqsRecordModel): +class S3SqsEventNotificationRecordModel(SqsRecordModel): body: Json[S3Model] -class SqsS3EventNotificationModel(SqsModel): - Records: List[SqsS3EventNotificationRecordModel] +class S3SqsEventNotificationModel(SqsModel): + Records: List[S3SqsEventNotificationRecordModel] diff --git a/docs/utilities/parser.md b/docs/utilities/parser.md index 9b450e3abf6..38e12c0792d 100644 --- a/docs/utilities/parser.md +++ b/docs/utilities/parser.md @@ -156,26 +156,26 @@ def my_function(): Parser comes with the following built-in models: -| Model name | Description | -| --------------------------------------- | ---------------------------------------------------------------------------- | -| **DynamoDBStreamModel** | Lambda Event Source payload for Amazon DynamoDB Streams | -| **EventBridgeModel** | Lambda Event Source payload for Amazon EventBridge | -| **SqsModel** | Lambda Event Source payload for Amazon SQS | -| **AlbModel** | Lambda Event Source payload for Amazon Application Load Balancer | -| **CloudwatchLogsModel** | Lambda Event Source payload for Amazon CloudWatch Logs | -| **S3Model** | Lambda Event Source payload for Amazon S3 | -| **S3ObjectLambdaEvent** | Lambda Event Source payload for Amazon S3 Object Lambda | -| **S3EventNotificationEventBridgeModel** | Lambda Event Source payload for Amazon S3 Event Notification to EventBridge. | -| **KinesisDataStreamModel** | Lambda Event Source payload for Amazon Kinesis Data Streams | -| **KinesisFirehoseModel** | Lambda Event Source payload for Amazon Kinesis Firehose | -| **SesModel** | Lambda Event Source payload for Amazon Simple Email Service | -| **SnsModel** | Lambda Event Source payload for Amazon Simple Notification Service | -| **APIGatewayProxyEventModel** | Lambda Event Source payload for Amazon API Gateway | -| **APIGatewayProxyEventV2Model** | Lambda Event Source payload for Amazon API Gateway v2 payload | -| **LambdaFunctionUrlModel** | Lambda Event Source payload for Lambda Function URL payload | -| **KafkaSelfManagedEventModel** | Lambda Event Source payload for self managed Kafka payload | -| **KafkaMskEventModel** | Lambda Event Source payload for AWS MSK payload | -| **SqsS3EventNotificationModel** | Lambda Event Source payload for SQS-wrapped S3 event notifications | +| Model name | Description | +| --------------------------------------- | ------------------------------------------------------------------------------------- | +| **AlbModel** | Lambda Event Source payload for Amazon Application Load Balancer | +| **APIGatewayProxyEventModel** | Lambda Event Source payload for Amazon API Gateway | +| **APIGatewayProxyEventV2Model** | Lambda Event Source payload for Amazon API Gateway v2 payload | +| **CloudwatchLogsModel** | Lambda Event Source payload for Amazon CloudWatch Logs | +| **DynamoDBStreamModel** | Lambda Event Source payload for Amazon DynamoDB Streams | +| **EventBridgeModel** | Lambda Event Source payload for Amazon EventBridge | +| **KafkaMskEventModel** | Lambda Event Source payload for AWS MSK payload | +| **KafkaSelfManagedEventModel** | Lambda Event Source payload for self managed Kafka payload | +| **KinesisDataStreamModel** | Lambda Event Source payload for Amazon Kinesis Data Streams | +| **KinesisFirehoseModel** | Lambda Event Source payload for Amazon Kinesis Firehose | +| **LambdaFunctionUrlModel** | Lambda Event Source payload for Lambda Function URL payload | +| **S3EventNotificationEventBridgeModel** | Lambda Event Source payload for Amazon S3 Event Notification to EventBridge. | +| **S3Model** | Lambda Event Source payload for Amazon S3 | +| **S3ObjectLambdaEvent** | Lambda Event Source payload for Amazon S3 Object Lambda | +| **S3SqsEventNotificationModel** | Lambda Event Source payload for S3 event notifications wrapped in SQS event (S3->SQS) | +| **SesModel** | Lambda Event Source payload for Amazon Simple Email Service | +| **SnsModel** | Lambda Event Source payload for Amazon Simple Notification Service | +| **SqsModel** | Lambda Event Source payload for Amazon SQS | #### Extending built-in models diff --git a/tests/events/sqsS3Event.json b/tests/events/sqsS3Event.json new file mode 100644 index 00000000000..55863af12b0 --- /dev/null +++ b/tests/events/sqsS3Event.json @@ -0,0 +1,22 @@ +{ + "Records":[ + { + "messageId":"ca3e7a89-c358-40e5-8aa0-5da01403c267", + "receiptHandle":"AQEBE7XoI7IQRLF7SrpiW9W4BanmOWe8UtVDbv6/CEZYKf/OktSNIb4j689tQfR4k44V/LY20lZ5VpxYt2GTYCsSLKTcBalTJaRX9CKu/hVqy/23sSNiKxnP56D+VLSn+hU275+AP1h4pUL0d9gLdRB2haX8xiM+LcGfis5Jl8BBXtoxKRF60O87O9/NvCmmXLeqkJuexfyEZNyed0fFCRXFXSjbmThG0OIQgcrGI8glBRGPA8htns58VtXFsSaPYNoqP3p5n6+ewKKVLD0lfm+0DlnLKRa+mjvFBaSer9KK1ff+Aq6zJ6HynPwADj+aF70Hwimc2zImYe51SLEF/E2csYlMNZYI/2qXW0m9R7wJ/XDTV4g2+h+BMTxsKnJQ6NQd", + "body":"{\"Records\":[{\"eventVersion\":\"2.1\",\"eventSource\":\"aws:s3\",\"awsRegion\":\"us-east-1\",\"eventTime\":\"2023-04-12T20:43:38.021Z\",\"eventName\":\"ObjectCreated:Put\",\"userIdentity\":{\"principalId\":\"A1YQ72UWCM96UF\"},\"requestParameters\":{\"sourceIPAddress\":\"93.108.161.96\"},\"responseElements\":{\"x-amz-request-id\":\"YMSSR8BZJ2Y99K6P\",\"x-amz-id-2\":\"6ASrUfj5xpn859fIq+6FXflOex/SKl/rjfiMd7wRzMg/zkHKR22PDpnh7KD3uq//cuOTbdX4DInN5eIs+cR0dY1z2Mc5NDP/\"},\"s3\":{\"s3SchemaVersion\":\"1.0\",\"configurationId\":\"SNS\",\"bucket\":{\"name\":\"xxx\",\"ownerIdentity\":{\"principalId\":\"A1YQ72UWCM96UF\"},\"arn\":\"arn:aws:s3:::xxx\"},\"object\":{\"key\":\"test.pdf\",\"size\":104681,\"eTag\":\"2e3ad1e983318bbd8e73b080e2997980\",\"versionId\":\"yd3d4HaWOT2zguDLvIQLU6ptDTwKBnQV\",\"sequencer\":\"00643717F9F8B85354\"}}}]}", + "attributes":{ + "ApproximateReceiveCount":"1", + "SentTimestamp":"1681332219270", + "SenderId":"AIDAJHIPRHEMV73VRJEBU", + "ApproximateFirstReceiveTimestamp":"1681332239270" + }, + "messageAttributes":{ + + }, + "md5OfBody":"16f4460f4477d8d693a5abe94fdbbd73", + "eventSource":"aws:sqs", + "eventSourceARN":"arn:aws:sqs:us-east-1:123456789012:SQS", + "awsRegion":"us-east-1" + } + ] + } diff --git a/tests/functional/parser/test_sqs_s3_event_notification.py b/tests/functional/parser/test_sqs_s3_event_notification.py deleted file mode 100644 index 21b0781a6bf..00000000000 --- a/tests/functional/parser/test_sqs_s3_event_notification.py +++ /dev/null @@ -1,43 +0,0 @@ -import pytest - -from aws_lambda_powertools.utilities.parser import ValidationError, event_parser -from aws_lambda_powertools.utilities.parser.models import SqsS3EventNotificationModel -from aws_lambda_powertools.utilities.typing import LambdaContext -from tests.functional.parser.test_s3 import assert_s3 -from tests.functional.utils import json_serialize, load_event - - -@event_parser(model=SqsS3EventNotificationModel) -def handle_sqs_json_body_containing_s3_notifications(event: SqsS3EventNotificationModel, _: LambdaContext): - return event - - -def test_handle_sqs_json_body_containing_s3_notifications(): - sqs_event_dict = load_event("sqsEvent.json") - s3_event_notification_dict = load_event("s3Event.json") - for record in sqs_event_dict["Records"]: - record["body"] = json_serialize(s3_event_notification_dict) - - parsed_event: SqsS3EventNotificationModel = handle_sqs_json_body_containing_s3_notifications( - sqs_event_dict, LambdaContext() - ) - - assert len(parsed_event.Records) == 2 - for parsed_sqs_record in parsed_event.Records: - assert_s3(parsed_sqs_record.body) - - -def test_handle_sqs_body_invalid_json(): - sqs_event_dict = load_event("sqsEvent.json") - - with pytest.raises(ValidationError): - handle_sqs_json_body_containing_s3_notifications(sqs_event_dict, LambdaContext()) - - -def test_handle_sqs_json_body_containing_arbitrary_json(): - sqs_event_dict = load_event("sqsEvent.json") - for record in sqs_event_dict["Records"]: - record["body"] = json_serialize({"foo": "bar"}) - - with pytest.raises(ValidationError): - handle_sqs_json_body_containing_s3_notifications(sqs_event_dict, LambdaContext()) diff --git a/tests/unit/parser/test_s3.py b/tests/unit/parser/test_s3.py index 6d11ba8b9fd..42124a8d058 100644 --- a/tests/unit/parser/test_s3.py +++ b/tests/unit/parser/test_s3.py @@ -1,7 +1,12 @@ +import json from datetime import datetime +import pytest + +from aws_lambda_powertools.utilities.parser import ValidationError from aws_lambda_powertools.utilities.parser.models import ( S3EventNotificationEventBridgeModel, + S3SqsEventNotificationModel, ) from tests.functional.utils import load_event @@ -105,3 +110,33 @@ def test_s3_eventbridge_notification_object_restore_completed_event(): assert model.detail.requester == raw_event["detail"]["requester"] assert model.detail.restore_expiry_time == raw_event["detail"]["restore-expiry-time"] assert model.detail.source_storage_class == raw_event["detail"]["source-storage-class"] + + +def test_s3_sqs_event_notification(): + raw_event = load_event("sqsS3Event.json") + model = S3SqsEventNotificationModel(**raw_event) + + body = json.loads(raw_event["Records"][0]["body"]) + + assert model.Records[0].body.Records[0].eventVersion == body["Records"][0]["eventVersion"] + assert model.Records[0].body.Records[0].eventSource == body["Records"][0]["eventSource"] + assert model.Records[0].body.Records[0].eventTime == datetime.fromisoformat( + body["Records"][0]["eventTime"].replace("Z", "+00:00") + ) + assert model.Records[0].body.Records[0].eventName == body["Records"][0]["eventName"] + + +def test_s3_sqs_event_notification_body_invalid_json(): + raw_event = load_event("s3Event.json") + + with pytest.raises(ValidationError): + S3SqsEventNotificationModel(**raw_event) + + +def test_s3_sqs_event_notification_body_containing_arbitrary_json(): + raw_event = load_event("sqsS3Event.json") + for record in raw_event["Records"]: + record["body"] = {"foo": "bar"} + + with pytest.raises(ValidationError): + S3SqsEventNotificationModel(**raw_event) From f847564ad209261b510e501da6bab6435ec813b6 Mon Sep 17 00:00:00 2001 From: Heitor Lessa Date: Wed, 26 Apr 2023 22:54:33 +0200 Subject: [PATCH 078/100] docs(tutorial): use newer sam cli template; update to py3.10 (#2167) --- docs/index.md | 2 +- docs/tutorial/index.md | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/docs/index.md b/docs/index.md index d25c9e7caf0..b8a7791154f 100644 --- a/docs/index.md +++ b/docs/index.md @@ -670,7 +670,7 @@ Compared with the [public Layer ARN](#lambda-layer) option, SAR allows you to ch ## Quick getting started ```bash title="Hello world example using SAM CLI" -sam init --location https://github.com/aws-samples/cookiecutter-aws-sam-python +sam init --app-template hello-world-powertools-python --name sam-app --package-type Zip --runtime python3.10 --no-tracing ``` ## Features diff --git a/docs/tutorial/index.md b/docs/tutorial/index.md index 8ae49544419..9965d70d267 100644 --- a/docs/tutorial/index.md +++ b/docs/tutorial/index.md @@ -17,10 +17,14 @@ This tutorial progressively introduces Lambda Powertools core utilities by using Let's clone our sample project before we add one feature at a time. ???+ tip "Tip: Want to skip to the final project?" - Bootstrap directly via SAM CLI: `sam init --location https://github.com/aws-samples/cookiecutter-aws-sam-python` + Bootstrap directly via SAM CLI: + + ```shell + sam init --app-template hello-world-powertools-python --name sam-app --package-type Zip --runtime python3.10 --no-tracing` + ``` ```bash title="Use SAM CLI to initialize the sample project" -sam init --runtime python3.9 --dependency-manager pip --app-template hello-world --name powertools-quickstart +sam init --runtime python3.10 --dependency-manager pip --app-template hello-world --name powertools-quickstart ``` ### Project structure From 0d2d061ba29d5579f45a51303e4a56916285380f Mon Sep 17 00:00:00 2001 From: Release bot Date: Wed, 26 Apr 2023 20:54:55 +0000 Subject: [PATCH 079/100] update changelog with latest changes --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6961f5ed743..fd5fde3f2d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ ## Documentation * **homepage:** add customer references section ([#2159](https://github.com/awslabs/aws-lambda-powertools-python/issues/2159)) +* **tutorial:** use newer sam cli template; update to py3.10 ([#2167](https://github.com/awslabs/aws-lambda-powertools-python/issues/2167)) ## Features From 81f04d8cded324464d56fea680b7d4dc4dd1d764 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 27 Apr 2023 21:03:42 +0000 Subject: [PATCH 080/100] chore(deps-dev): bump mypy-boto3-lambda from 1.26.115 to 1.26.122 (#2172) Bumps [mypy-boto3-lambda](https://github.com/youtype/mypy_boto3_builder) from 1.26.115 to 1.26.122. - [Release notes](https://github.com/youtype/mypy_boto3_builder/releases) - [Commits](https://github.com/youtype/mypy_boto3_builder/commits) --- updated-dependencies: - dependency-name: mypy-boto3-lambda dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 10 +++++----- pyproject.toml | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/poetry.lock b/poetry.lock index 614a377adc9..d643941c429 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1750,14 +1750,14 @@ typing-extensions = {version = ">=4.1.0", markers = "python_version < \"3.9\""} [[package]] name = "mypy-boto3-lambda" -version = "1.26.115" -description = "Type annotations for boto3.Lambda 1.26.115 service generated with mypy-boto3-builder 7.14.5" +version = "1.26.122" +description = "Type annotations for boto3.Lambda 1.26.122 service generated with mypy-boto3-builder 7.14.5" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "mypy-boto3-lambda-1.26.115.tar.gz", hash = "sha256:f612eca8f0e418e66d577b5609f0119c4934a7637ce1342d3c1cfc0d065cd42d"}, - {file = "mypy_boto3_lambda-1.26.115-py3-none-any.whl", hash = "sha256:0d418bb0d6c16c6a83e159dae71f8c6dff663c50dab125bb1518bf6c29f2ed83"}, + {file = "mypy-boto3-lambda-1.26.122.tar.gz", hash = "sha256:b46d153f69b407c76d17ba97390fad9285215fa3dcf484bb7d6ffa0880fca746"}, + {file = "mypy_boto3_lambda-1.26.122-py3-none-any.whl", hash = "sha256:2839045d23b48f7a99ac3fdc71bcecde15998245c6e515b1cf2e8f589a9ae23e"}, ] [package.dependencies] @@ -3035,4 +3035,4 @@ validation = ["fastjsonschema"] [metadata] lock-version = "2.0" python-versions = "^3.7.4" -content-hash = "0ec22c8c2a10a974b5e9dd5acc5314cd646524b59019bcaea28364c0f898d697" +content-hash = "d39a3f32834179cf82e836f73d2ac4af87b8be7368ee4becb97cbc2a8e585357" diff --git a/pyproject.toml b/pyproject.toml index 6f893fc2e88..61ca9b222e2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -74,7 +74,7 @@ mypy-boto3-appconfig = "^1.26.71" mypy-boto3-cloudformation = "^1.26.108" mypy-boto3-cloudwatch = "^1.26.99" mypy-boto3-dynamodb = "^1.26.115" -mypy-boto3-lambda = "^1.26.115" +mypy-boto3-lambda = "^1.26.122" mypy-boto3-logs = "^1.26.53" mypy-boto3-secretsmanager = "^1.26.116" mypy-boto3-ssm = "^1.26.97" From 939f891e08a3edbaa95a5652f6e7e9fbd6044ce5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 27 Apr 2023 22:10:51 +0100 Subject: [PATCH 081/100] chore(deps-dev): bump aws-cdk from 2.76.0 to 2.77.0 (#2174) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 14 +++++++------- package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index a206f7a7b7b..944c28b98a2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,13 +8,13 @@ "name": "aws-lambda-powertools-python-e2e", "version": "1.0.0", "devDependencies": { - "aws-cdk": "^2.76.0" + "aws-cdk": "^2.77.0" } }, "node_modules/aws-cdk": { - "version": "2.76.0", - "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.76.0.tgz", - "integrity": "sha512-y6VHtqUpYenn6mGIBFbcGGXIoXfKA3o0eGL/eeD/gUJ9TcPrgMLQM1NxSMb5JVsOk5BPPXzGmvB0gBu40utGqg==", + "version": "2.77.0", + "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.77.0.tgz", + "integrity": "sha512-f0UpWjBxrFkINqlwL50OpIIC03V39hTzg4+NEBlfUc/ftFX8WQQYyT6h29IfxT9Tgo+YoEMlM1nnH/s1c+VKSw==", "dev": true, "bin": { "cdk": "bin/cdk" @@ -43,9 +43,9 @@ }, "dependencies": { "aws-cdk": { - "version": "2.76.0", - "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.76.0.tgz", - "integrity": "sha512-y6VHtqUpYenn6mGIBFbcGGXIoXfKA3o0eGL/eeD/gUJ9TcPrgMLQM1NxSMb5JVsOk5BPPXzGmvB0gBu40utGqg==", + "version": "2.77.0", + "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.77.0.tgz", + "integrity": "sha512-f0UpWjBxrFkINqlwL50OpIIC03V39hTzg4+NEBlfUc/ftFX8WQQYyT6h29IfxT9Tgo+YoEMlM1nnH/s1c+VKSw==", "dev": true, "requires": { "fsevents": "2.3.2" diff --git a/package.json b/package.json index 9536d277acb..0a074487100 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,6 @@ "name": "aws-lambda-powertools-python-e2e", "version": "1.0.0", "devDependencies": { - "aws-cdk": "^2.76.0" + "aws-cdk": "^2.77.0" } } From 14147cb519cdd84b2a88babbe7af3051e26a0ad1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 27 Apr 2023 21:11:49 +0000 Subject: [PATCH 082/100] chore(deps-dev): bump mypy-boto3-xray from 1.26.11.post1 to 1.26.122 (#2173) Bumps [mypy-boto3-xray](https://github.com/youtype/mypy_boto3_builder) from 1.26.11.post1 to 1.26.122. - [Release notes](https://github.com/youtype/mypy_boto3_builder/releases) - [Commits](https://github.com/youtype/mypy_boto3_builder/commits) --- updated-dependencies: - dependency-name: mypy-boto3-xray dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 12 ++++++------ pyproject.toml | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/poetry.lock b/poetry.lock index d643941c429..c1fb241b48a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1825,18 +1825,18 @@ typing-extensions = ">=4.1.0" [[package]] name = "mypy-boto3-xray" -version = "1.26.11.post1" -description = "Type annotations for boto3.XRay 1.26.11 service generated with mypy-boto3-builder 7.11.10" +version = "1.26.122" +description = "Type annotations for boto3.XRay 1.26.122 service generated with mypy-boto3-builder 7.14.5" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "mypy-boto3-xray-1.26.11.post1.tar.gz", hash = "sha256:e720a766571b4f3e1e35193de74e6dfae21b0f641286aa39f7b938be43150ac0"}, - {file = "mypy_boto3_xray-1.26.11.post1-py3-none-any.whl", hash = "sha256:e22bf1e7fa6a43c52ff6cd3e82892674929b75bb62ab3b0fe3d4c91ede710e1f"}, + {file = "mypy-boto3-xray-1.26.122.tar.gz", hash = "sha256:0231b717443e6eafe4ff689423c5b54a5ee47682f7c19d3f66bfe7e00e87bf7c"}, + {file = "mypy_boto3_xray-1.26.122-py3-none-any.whl", hash = "sha256:6cfe3167ecb92942519d8334bb145d83a6d727bdb7b812c1d9692f938caf6a7f"}, ] [package.dependencies] -typing-extensions = ">=4.1.0" +typing-extensions = {version = ">=4.1.0", markers = "python_version < \"3.9\""} [[package]] name = "mypy-extensions" @@ -3035,4 +3035,4 @@ validation = ["fastjsonschema"] [metadata] lock-version = "2.0" python-versions = "^3.7.4" -content-hash = "d39a3f32834179cf82e836f73d2ac4af87b8be7368ee4becb97cbc2a8e585357" +content-hash = "49c54d14ea5161d78c7ec255921c3ddadf20fd2a4b08f050030d5c4e71da55b7" diff --git a/pyproject.toml b/pyproject.toml index 61ca9b222e2..d4a17946c3a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -79,7 +79,7 @@ mypy-boto3-logs = "^1.26.53" mypy-boto3-secretsmanager = "^1.26.116" mypy-boto3-ssm = "^1.26.97" mypy-boto3-s3 = "^1.26.116" -mypy-boto3-xray = "^1.26.11" +mypy-boto3-xray = "^1.26.122" types-requests = "^2.28.11" typing-extensions = "^4.4.0" mkdocs-material = "^9.1.8" From d4607f39c6ea5bdcbfc7b6f61e135759f107f24f Mon Sep 17 00:00:00 2001 From: Ruben Fonseca Date: Fri, 28 Apr 2023 15:46:23 +0200 Subject: [PATCH 083/100] feat(metrics): add flush_metrics() method to allow manual flushing of metrics (#2171) Co-authored-by: Heitor Lessa Co-authored-by: Leandro Damascena --- aws_lambda_powertools/metrics/base.py | 33 +++++++++++++------ docs/core/metrics.md | 10 +++--- .../src/{manual_flush.py => flush_metrics.py} | 16 +++++---- tests/functional/test_metrics.py | 20 +++++++++++ 4 files changed, 59 insertions(+), 20 deletions(-) rename examples/metrics/src/{manual_flush.py => flush_metrics.py} (62%) diff --git a/aws_lambda_powertools/metrics/base.py b/aws_lambda_powertools/metrics/base.py index b96356192ab..59daafa0bb1 100644 --- a/aws_lambda_powertools/metrics/base.py +++ b/aws_lambda_powertools/metrics/base.py @@ -328,6 +328,28 @@ def clear_metrics(self) -> None: self.dimension_set.clear() self.metadata_set.clear() + def flush_metrics(self, raise_on_empty_metrics: bool = False) -> None: + """Manually flushes the metrics. This is normally not necessary, + unless you're running on other runtimes besides Lambda, where the @log_metrics + decorator already handles things for you. + + Parameters + ---------- + raise_on_empty_metrics : bool, optional + raise exception if no metrics are emitted, by default False + """ + if not raise_on_empty_metrics and not self.metric_set: + warnings.warn( + "No application metrics to publish. The cold-start metric may be published if enabled. " + "If application metrics should never be empty, consider using 'raise_on_empty_metrics'", + stacklevel=2, + ) + else: + logger.debug("Flushing existing metrics") + metrics = self.serialize_metric_set() + print(json.dumps(metrics, separators=(",", ":"))) + self.clear_metrics() + def log_metrics( self, lambda_handler: Union[Callable[[Dict, Any], Any], Optional[Callable[[Dict, Any, Optional[Dict]], Any]]] = None, @@ -390,16 +412,7 @@ def decorate(event, context): if capture_cold_start_metric: self._add_cold_start_metric(context=context) finally: - if not raise_on_empty_metrics and not self.metric_set: - warnings.warn( - "No application metrics to publish. The cold-start metric may be published if enabled. " - "If application metrics should never be empty, consider using 'raise_on_empty_metrics'", - stacklevel=2, - ) - else: - metrics = self.serialize_metric_set() - self.clear_metrics() - print(json.dumps(metrics, separators=(",", ":"))) + self.flush_metrics(raise_on_empty_metrics=raise_on_empty_metrics) return response diff --git a/docs/core/metrics.md b/docs/core/metrics.md index 81acd8999d8..ba9f746e867 100644 --- a/docs/core/metrics.md +++ b/docs/core/metrics.md @@ -251,13 +251,15 @@ By default it will skip all previously defined dimensions including default dime ### Flushing metrics manually -If you prefer not to use `log_metrics` because you might want to encapsulate additional logic when doing so, you can manually flush and clear metrics as follows: +If you are using the AWS Lambda Web Adapter project, or a middleware with custom metric logic, you can use `flush_metrics()`. This method will serialize, print metrics available to standard output, and clear in-memory metrics data. ???+ warning - Metrics, dimensions and namespace validation still applies + This does not capture Cold Start metrics, and metric data validation still applies. -```python hl_lines="11-14" title="Manually flushing and clearing metrics from memory" ---8<-- "examples/metrics/src/single_metric.py" +Contrary to the `log_metrics` decorator, you are now also responsible to flush metrics in the event of an exception. + +```python hl_lines="18" title="Manually flushing and clearing metrics from memory" +--8<-- "examples/metrics/src/flush_metrics.py" ``` ### Metrics isolation diff --git a/examples/metrics/src/manual_flush.py b/examples/metrics/src/flush_metrics.py similarity index 62% rename from examples/metrics/src/manual_flush.py rename to examples/metrics/src/flush_metrics.py index def0f845d08..a66ce07cbf7 100644 --- a/examples/metrics/src/manual_flush.py +++ b/examples/metrics/src/flush_metrics.py @@ -1,5 +1,3 @@ -import json - from aws_lambda_powertools import Metrics from aws_lambda_powertools.metrics import MetricUnit from aws_lambda_powertools.utilities.typing import LambdaContext @@ -7,8 +5,14 @@ metrics = Metrics() -def lambda_handler(event: dict, context: LambdaContext): +def book_flight(flight_id: str, **kwargs): + # logic to book flight + ... metrics.add_metric(name="SuccessfulBooking", unit=MetricUnit.Count, value=1) - your_metrics_object = metrics.serialize_metric_set() - metrics.clear_metrics() - print(json.dumps(your_metrics_object)) + + +def lambda_handler(event: dict, context: LambdaContext): + try: + book_flight(flight_id=event.get("flight_id", "")) + finally: + metrics.flush_metrics() diff --git a/tests/functional/test_metrics.py b/tests/functional/test_metrics.py index c0c41f3bf88..964af99ce6e 100644 --- a/tests/functional/test_metrics.py +++ b/tests/functional/test_metrics.py @@ -249,6 +249,26 @@ def lambda_handler(evt, ctx): assert expected == output +def test_log_metrics_manual_flush(capsys, metrics, dimensions, namespace): + # GIVEN Metrics is initialized + my_metrics = Metrics(namespace=namespace) + for metric in metrics: + my_metrics.add_metric(**metric) + for dimension in dimensions: + my_metrics.add_dimension(**dimension) + + # WHEN we manually the metrics + my_metrics.flush_metrics() + + output = capture_metrics_output(capsys) + expected = serialize_metrics(metrics=metrics, dimensions=dimensions, namespace=namespace) + + # THEN we should have no exceptions + # and a valid EMF object should be flushed correctly + remove_timestamp(metrics=[output, expected]) + assert expected == output + + def test_namespace_env_var(monkeypatch, capsys, metric, dimension, namespace): # GIVEN POWERTOOLS_METRICS_NAMESPACE is set monkeypatch.setenv("POWERTOOLS_METRICS_NAMESPACE", namespace) From acd4a8935e1eb894e168c8c1938fb35cc655fa26 Mon Sep 17 00:00:00 2001 From: Release bot Date: Fri, 28 Apr 2023 13:46:46 +0000 Subject: [PATCH 084/100] update changelog with latest changes --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fd5fde3f2d1..690144b2b19 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,13 +17,17 @@ * **ci:** dispatch GitHub analytics action ([#2161](https://github.com/awslabs/aws-lambda-powertools-python/issues/2161)) * **event_sources:** Add __str__ to Data Classes base DictWrapper ([#2129](https://github.com/awslabs/aws-lambda-powertools-python/issues/2129)) +* **metrics:** add flush_metrics() method to allow manual flushing of metrics ([#2171](https://github.com/awslabs/aws-lambda-powertools-python/issues/2171)) ## Maintenance * add dummy reusable dispatch analytics job +* **deps-dev:** bump aws-cdk from 2.76.0 to 2.77.0 ([#2174](https://github.com/awslabs/aws-lambda-powertools-python/issues/2174)) +* **deps-dev:** bump mypy-boto3-lambda from 1.26.115 to 1.26.122 ([#2172](https://github.com/awslabs/aws-lambda-powertools-python/issues/2172)) * **deps-dev:** bump cfn-lint from 0.77.2 to 0.77.3 ([#2165](https://github.com/awslabs/aws-lambda-powertools-python/issues/2165)) * **deps-dev:** bump mkdocs-material from 9.1.6 to 9.1.8 ([#2162](https://github.com/awslabs/aws-lambda-powertools-python/issues/2162)) * **deps-dev:** bump importlib-metadata from 6.5.0 to 6.6.0 ([#2163](https://github.com/awslabs/aws-lambda-powertools-python/issues/2163)) +* **deps-dev:** bump mypy-boto3-xray from 1.26.11.post1 to 1.26.122 ([#2173](https://github.com/awslabs/aws-lambda-powertools-python/issues/2173)) From 62fa81f48f5f6d6d318c4a89a6615996ff39b39e Mon Sep 17 00:00:00 2001 From: leif ye <94335271+leif-ye@users.noreply.github.com> Date: Fri, 28 Apr 2023 23:34:16 +0800 Subject: [PATCH 085/100] feat(event_source): add support for dynamic partitions in the Api Gateway Authorizer event (#2176) Co-authored-by: Leandro Damascena --- .../data_classes/api_gateway_authorizer_event.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/aws_lambda_powertools/utilities/data_classes/api_gateway_authorizer_event.py b/aws_lambda_powertools/utilities/data_classes/api_gateway_authorizer_event.py index 51f8f74b56a..431d678e9b6 100644 --- a/aws_lambda_powertools/utilities/data_classes/api_gateway_authorizer_event.py +++ b/aws_lambda_powertools/utilities/data_classes/api_gateway_authorizer_event.py @@ -21,8 +21,9 @@ def __init__( stage: str, http_method: str, resource: str, + partition: str = "aws", ): - self.partition = "aws" + self.partition = partition self.region = region self.aws_account_id = aws_account_id self.api_id = api_id @@ -55,6 +56,7 @@ def parse_api_gateway_arn(arn: str) -> APIGatewayRouteArn: arn_parts = arn.split(":") api_gateway_arn_parts = arn_parts[5].split("/") return APIGatewayRouteArn( + partition=arn_parts[1], region=arn_parts[3], aws_account_id=arn_parts[4], api_id=api_gateway_arn_parts[0], @@ -369,6 +371,7 @@ def __init__( stage: str, context: Optional[Dict] = None, usage_identifier_key: Optional[str] = None, + partition: str = "aws", ): """ Parameters @@ -401,6 +404,9 @@ def __init__( If the API uses a usage plan (the apiKeySource is set to `AUTHORIZER`), the Lambda authorizer function must return one of the usage plan's API keys as the usageIdentifierKey property value. > **Note:** This only applies for REST APIs. + partition: str, optional + Optional, arn partition. + See https://docs.aws.amazon.com/IAM/latest/UserGuide/reference-arns.html """ self.principal_id = principal_id self.region = region @@ -412,6 +418,7 @@ def __init__( self._allow_routes: List[Dict] = [] self._deny_routes: List[Dict] = [] self._resource_pattern = re.compile(self.path_regex) + self.partition = partition @staticmethod def from_route_arn( @@ -443,7 +450,7 @@ def _add_route(self, effect: str, http_method: str, resource: str, conditions: O raise ValueError(f"Invalid resource path: {resource}. Path should match {self.path_regex}") resource_arn = APIGatewayRouteArn( - self.region, self.aws_account_id, self.api_id, self.stage, http_method, resource + self.region, self.aws_account_id, self.api_id, self.stage, http_method, resource, self.partition ).arn route = {"resourceArn": resource_arn, "conditions": conditions} From 220cba4aae7341d56331f3d8acdad37f360453cb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 28 Apr 2023 22:02:17 +0100 Subject: [PATCH 086/100] chore(deps-dev): bump cfn-lint from 0.77.3 to 0.77.4 (#2178) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 18 +++++++++--------- pyproject.toml | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/poetry.lock b/poetry.lock index c1fb241b48a..e3142cb1790 100644 --- a/poetry.lock +++ b/poetry.lock @@ -189,14 +189,14 @@ requests = ">=0.14.0" [[package]] name = "aws-sam-translator" -version = "1.64.0" +version = "1.66.0" description = "AWS SAM Translator is a library that transform SAM templates into AWS CloudFormation templates" category = "dev" optional = false python-versions = ">=3.7, <=4.0, !=4.0" files = [ - {file = "aws-sam-translator-1.64.0.tar.gz", hash = "sha256:0cc5b07dd6ef1de3525d887a3b9557168e04cb44327706a43661653bad30687f"}, - {file = "aws_sam_translator-1.64.0-py3-none-any.whl", hash = "sha256:c44725f12b05d4881e3bc077f70e23ebce56ea78c729acf0ca9f51302b27d304"}, + {file = "aws-sam-translator-1.66.0.tar.gz", hash = "sha256:0b9e9684ea0384fd84f5e722f7fea61896c514b95d3403aa782b69acd485dbbf"}, + {file = "aws_sam_translator-1.66.0-py3-none-any.whl", hash = "sha256:dc4f38cd7ce2a4875d943bf10ba0745901a3a7b7fec1e40b8d13072641630c58"}, ] [package.dependencies] @@ -206,7 +206,7 @@ pydantic = ">=1.8,<2.0" typing-extensions = ">=4.4,<5" [package.extras] -dev = ["black (==23.1.0)", "boto3 (>=1.23,<2)", "boto3-stubs[appconfig,serverlessrepo] (>=1.19.5,<2.0.0)", "coverage (>=5.3,<8)", "dateparser (>=1.1,<2.0)", "mypy (>=1.1.0,<1.2.0)", "parameterized (>=0.7,<1.0)", "pytest (>=6.2,<8)", "pytest-cov (>=2.10,<5)", "pytest-env (>=0.6,<1)", "pytest-rerunfailures (>=9.1,<12)", "pytest-xdist (>=2.5,<4)", "pyyaml (>=6.0,<7.0)", "requests (>=2.28,<3.0)", "ruamel.yaml (==0.17.21)", "ruff (==0.0.254)", "tenacity (>=8.0,<9.0)", "types-PyYAML (>=6.0,<7.0)", "types-jsonschema (>=3.2,<4.0)"] +dev = ["black (==23.1.0)", "boto3 (>=1.23,<2)", "boto3-stubs[appconfig,serverlessrepo] (>=1.19.5,<2.0.0)", "coverage (>=5.3,<8)", "dateparser (>=1.1,<2.0)", "mypy (>=1.1.0,<1.2.0)", "parameterized (>=0.7,<1.0)", "pytest (>=6.2,<8)", "pytest-cov (>=2.10,<5)", "pytest-env (>=0.6,<1)", "pytest-rerunfailures (>=9.1,<12)", "pytest-xdist (>=2.5,<4)", "pyyaml (>=6.0,<7.0)", "requests (>=2.28,<3.0)", "ruamel.yaml (==0.17.21)", "ruff (==0.0.261)", "tenacity (>=8.0,<9.0)", "types-PyYAML (>=6.0,<7.0)", "types-jsonschema (>=3.2,<4.0)"] [[package]] name = "aws-xray-sdk" @@ -370,18 +370,18 @@ files = [ [[package]] name = "cfn-lint" -version = "0.77.3" +version = "0.77.4" description = "Checks CloudFormation templates for practices and behaviour that could potentially be improved" category = "dev" optional = false python-versions = ">=3.7, <=4.0, !=4.0" files = [ - {file = "cfn-lint-0.77.3.tar.gz", hash = "sha256:d2a51a0ee222f3772fd87c3e4de82c59539172db34c2e5dc60ead7ce354365e0"}, - {file = "cfn_lint-0.77.3-py3-none-any.whl", hash = "sha256:cad9219416acc198d162ece4a1039e914852e71b96c9022b0b6f5faa676daa89"}, + {file = "cfn-lint-0.77.4.tar.gz", hash = "sha256:0aa67e28c992b84ad286539de59a9185f51d721d54ad539f6afe1b477836d8cd"}, + {file = "cfn_lint-0.77.4-py3-none-any.whl", hash = "sha256:b348589be12c12dc5ab4ba801fb430f441bffe76e5ffdf907088abcbeb74271d"}, ] [package.dependencies] -aws-sam-translator = ">=1.64.0" +aws-sam-translator = ">=1.65.0" jschema-to-python = ">=1.2.3,<1.3.0" jsonpatch = "*" jsonschema = ">=3.0,<5" @@ -3035,4 +3035,4 @@ validation = ["fastjsonschema"] [metadata] lock-version = "2.0" python-versions = "^3.7.4" -content-hash = "49c54d14ea5161d78c7ec255921c3ddadf20fd2a4b08f050030d5c4e71da55b7" +content-hash = "95d239c02c517fac0f3359f75f34b871e6ca4699538cd290e669e83b3f108ae7" diff --git a/pyproject.toml b/pyproject.toml index d4a17946c3a..62e7e0b61b7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -101,7 +101,7 @@ all = ["pydantic", "aws-xray-sdk", "fastjsonschema"] aws-sdk = ["boto3"] [tool.poetry.group.dev.dependencies] -cfn-lint = "0.77.3" +cfn-lint = "0.77.4" mypy = "^1.1.1" types-python-dateutil = "^2.8.19.6" httpx = ">=0.23.3,<0.25.0" From 4cd6a6a6d5a43e4f702973929e718cc58cf5e18f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 28 Apr 2023 22:04:59 +0100 Subject: [PATCH 087/100] chore(deps-dev): bump coverage from 7.2.3 to 7.2.4 (#2179) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 104 ++++++++++++++++++++++++++-------------------------- 1 file changed, 52 insertions(+), 52 deletions(-) diff --git a/poetry.lock b/poetry.lock index e3142cb1790..1b4bf602c82 100644 --- a/poetry.lock +++ b/poetry.lock @@ -536,63 +536,63 @@ typeguard = ">=2.13.3,<2.14.0" [[package]] name = "coverage" -version = "7.2.3" +version = "7.2.4" description = "Code coverage measurement for Python" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "coverage-7.2.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e58c0d41d336569d63d1b113bd573db8363bc4146f39444125b7f8060e4e04f5"}, - {file = "coverage-7.2.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:344e714bd0fe921fc72d97404ebbdbf9127bac0ca1ff66d7b79efc143cf7c0c4"}, - {file = "coverage-7.2.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:974bc90d6f6c1e59ceb1516ab00cf1cdfbb2e555795d49fa9571d611f449bcb2"}, - {file = "coverage-7.2.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0743b0035d4b0e32bc1df5de70fba3059662ace5b9a2a86a9f894cfe66569013"}, - {file = "coverage-7.2.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d0391fb4cfc171ce40437f67eb050a340fdbd0f9f49d6353a387f1b7f9dd4fa"}, - {file = "coverage-7.2.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4a42e1eff0ca9a7cb7dc9ecda41dfc7cbc17cb1d02117214be0561bd1134772b"}, - {file = "coverage-7.2.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:be19931a8dcbe6ab464f3339966856996b12a00f9fe53f346ab3be872d03e257"}, - {file = "coverage-7.2.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:72fcae5bcac3333a4cf3b8f34eec99cea1187acd55af723bcbd559adfdcb5535"}, - {file = "coverage-7.2.3-cp310-cp310-win32.whl", hash = "sha256:aeae2aa38395b18106e552833f2a50c27ea0000122bde421c31d11ed7e6f9c91"}, - {file = "coverage-7.2.3-cp310-cp310-win_amd64.whl", hash = "sha256:83957d349838a636e768251c7e9979e899a569794b44c3728eaebd11d848e58e"}, - {file = "coverage-7.2.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:dfd393094cd82ceb9b40df4c77976015a314b267d498268a076e940fe7be6b79"}, - {file = "coverage-7.2.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:182eb9ac3f2b4874a1f41b78b87db20b66da6b9cdc32737fbbf4fea0c35b23fc"}, - {file = "coverage-7.2.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1bb1e77a9a311346294621be905ea8a2c30d3ad371fc15bb72e98bfcfae532df"}, - {file = "coverage-7.2.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca0f34363e2634deffd390a0fef1aa99168ae9ed2af01af4a1f5865e362f8623"}, - {file = "coverage-7.2.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:55416d7385774285b6e2a5feca0af9652f7f444a4fa3d29d8ab052fafef9d00d"}, - {file = "coverage-7.2.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:06ddd9c0249a0546997fdda5a30fbcb40f23926df0a874a60a8a185bc3a87d93"}, - {file = "coverage-7.2.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:fff5aaa6becf2c6a1699ae6a39e2e6fb0672c2d42eca8eb0cafa91cf2e9bd312"}, - {file = "coverage-7.2.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ea53151d87c52e98133eb8ac78f1206498c015849662ca8dc246255265d9c3c4"}, - {file = "coverage-7.2.3-cp311-cp311-win32.whl", hash = "sha256:8f6c930fd70d91ddee53194e93029e3ef2aabe26725aa3c2753df057e296b925"}, - {file = "coverage-7.2.3-cp311-cp311-win_amd64.whl", hash = "sha256:fa546d66639d69aa967bf08156eb8c9d0cd6f6de84be9e8c9819f52ad499c910"}, - {file = "coverage-7.2.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b2317d5ed777bf5a033e83d4f1389fd4ef045763141d8f10eb09a7035cee774c"}, - {file = "coverage-7.2.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be9824c1c874b73b96288c6d3de793bf7f3a597770205068c6163ea1f326e8b9"}, - {file = "coverage-7.2.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2c3b2803e730dc2797a017335827e9da6da0e84c745ce0f552e66400abdfb9a1"}, - {file = "coverage-7.2.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f69770f5ca1994cb32c38965e95f57504d3aea96b6c024624fdd5bb1aa494a1"}, - {file = "coverage-7.2.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:1127b16220f7bfb3f1049ed4a62d26d81970a723544e8252db0efde853268e21"}, - {file = "coverage-7.2.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:aa784405f0c640940595fa0f14064d8e84aff0b0f762fa18393e2760a2cf5841"}, - {file = "coverage-7.2.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:3146b8e16fa60427e03884301bf8209221f5761ac754ee6b267642a2fd354c48"}, - {file = "coverage-7.2.3-cp37-cp37m-win32.whl", hash = "sha256:1fd78b911aea9cec3b7e1e2622c8018d51c0d2bbcf8faaf53c2497eb114911c1"}, - {file = "coverage-7.2.3-cp37-cp37m-win_amd64.whl", hash = "sha256:0f3736a5d34e091b0a611964c6262fd68ca4363df56185902528f0b75dbb9c1f"}, - {file = "coverage-7.2.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:981b4df72c93e3bc04478153df516d385317628bd9c10be699c93c26ddcca8ab"}, - {file = "coverage-7.2.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c0045f8f23a5fb30b2eb3b8a83664d8dc4fb58faddf8155d7109166adb9f2040"}, - {file = "coverage-7.2.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f760073fcf8f3d6933178d67754f4f2d4e924e321f4bb0dcef0424ca0215eba1"}, - {file = "coverage-7.2.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c86bd45d1659b1ae3d0ba1909326b03598affbc9ed71520e0ff8c31a993ad911"}, - {file = "coverage-7.2.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:172db976ae6327ed4728e2507daf8a4de73c7cc89796483e0a9198fd2e47b462"}, - {file = "coverage-7.2.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:d2a3a6146fe9319926e1d477842ca2a63fe99af5ae690b1f5c11e6af074a6b5c"}, - {file = "coverage-7.2.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:f649dd53833b495c3ebd04d6eec58479454a1784987af8afb77540d6c1767abd"}, - {file = "coverage-7.2.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:7c4ed4e9f3b123aa403ab424430b426a1992e6f4c8fd3cb56ea520446e04d152"}, - {file = "coverage-7.2.3-cp38-cp38-win32.whl", hash = "sha256:eb0edc3ce9760d2f21637766c3aa04822030e7451981ce569a1b3456b7053f22"}, - {file = "coverage-7.2.3-cp38-cp38-win_amd64.whl", hash = "sha256:63cdeaac4ae85a179a8d6bc09b77b564c096250d759eed343a89d91bce8b6367"}, - {file = "coverage-7.2.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:20d1a2a76bb4eb00e4d36b9699f9b7aba93271c9c29220ad4c6a9581a0320235"}, - {file = "coverage-7.2.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4ea748802cc0de4de92ef8244dd84ffd793bd2e7be784cd8394d557a3c751e21"}, - {file = "coverage-7.2.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21b154aba06df42e4b96fc915512ab39595105f6c483991287021ed95776d934"}, - {file = "coverage-7.2.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fd214917cabdd6f673a29d708574e9fbdb892cb77eb426d0eae3490d95ca7859"}, - {file = "coverage-7.2.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c2e58e45fe53fab81f85474e5d4d226eeab0f27b45aa062856c89389da2f0d9"}, - {file = "coverage-7.2.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:87ecc7c9a1a9f912e306997ffee020297ccb5ea388421fe62a2a02747e4d5539"}, - {file = "coverage-7.2.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:387065e420aed3c71b61af7e82c7b6bc1c592f7e3c7a66e9f78dd178699da4fe"}, - {file = "coverage-7.2.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ea3f5bc91d7d457da7d48c7a732beaf79d0c8131df3ab278e6bba6297e23c6c4"}, - {file = "coverage-7.2.3-cp39-cp39-win32.whl", hash = "sha256:ae7863a1d8db6a014b6f2ff9c1582ab1aad55a6d25bac19710a8df68921b6e30"}, - {file = "coverage-7.2.3-cp39-cp39-win_amd64.whl", hash = "sha256:3f04becd4fcda03c0160d0da9c8f0c246bc78f2f7af0feea1ec0930e7c93fa4a"}, - {file = "coverage-7.2.3-pp37.pp38.pp39-none-any.whl", hash = "sha256:965ee3e782c7892befc25575fa171b521d33798132692df428a09efacaffe8d0"}, - {file = "coverage-7.2.3.tar.gz", hash = "sha256:d298c2815fa4891edd9abe5ad6e6cb4207104c7dd9fd13aea3fdebf6f9b91259"}, + {file = "coverage-7.2.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9e5eedde6e6e241ec3816f05767cc77e7456bf5ec6b373fb29917f0990e2078f"}, + {file = "coverage-7.2.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5c6c6e3b8fb6411a2035da78d86516bfcfd450571d167304911814407697fb7a"}, + {file = "coverage-7.2.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f7668a621afc52db29f6867e0e9c72a1eec9f02c94a7c36599119d557cf6e471"}, + {file = "coverage-7.2.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cdfb53bef4b2739ff747ebbd76d6ac5384371fd3c7a8af08899074eba034d483"}, + {file = "coverage-7.2.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a5c4f2e44a2ae15fa6883898e756552db5105ca4bd918634cbd5b7c00e19e8a1"}, + {file = "coverage-7.2.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:700bc9fb1074e0c67c09fe96a803de66663830420781df8dc9fb90d7421d4ccb"}, + {file = "coverage-7.2.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:ac4861241e693e21b280f07844ae0e0707665e1dfcbf9466b793584984ae45c4"}, + {file = "coverage-7.2.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:3d6f3c5b6738a494f17c73b4aa3aa899865cc33a74aa85e3b5695943b79ad3ce"}, + {file = "coverage-7.2.4-cp310-cp310-win32.whl", hash = "sha256:437da7d2fcc35bf45e04b7e9cfecb7c459ec6f6dc17a8558ed52e8d666c2d9ab"}, + {file = "coverage-7.2.4-cp310-cp310-win_amd64.whl", hash = "sha256:1d3893f285fd76f56651f04d1efd3bdce251c32992a64c51e5d6ec3ba9e3f9c9"}, + {file = "coverage-7.2.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6a17bf32e9e3333d78606ac1073dd20655dc0752d5b923fa76afd3bc91674ab4"}, + {file = "coverage-7.2.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f7ffdb3af2a01ce91577f84fc0faa056029fe457f3183007cffe7b11ea78b23c"}, + {file = "coverage-7.2.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:89e63b38c7b888e00fd42ce458f838dccb66de06baea2da71801b0fc9070bfa0"}, + {file = "coverage-7.2.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4522dd9aeb9cc2c4c54ce23933beb37a4e106ec2ba94f69138c159024c8a906a"}, + {file = "coverage-7.2.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:29c7d88468f01a75231797173b52dc66d20a8d91b8bb75c88fc5861268578f52"}, + {file = "coverage-7.2.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bc47015fc0455753e8aba1f38b81b731aaf7f004a0c390b404e0fcf1d6c1d72f"}, + {file = "coverage-7.2.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:5c122d120c11a236558c339a59b4b60947b38ac9e3ad30a0e0e02540b37bf536"}, + {file = "coverage-7.2.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:50fda3d33b705b9c01e3b772cfa7d14de8aec2ec2870e4320992c26d057fde12"}, + {file = "coverage-7.2.4-cp311-cp311-win32.whl", hash = "sha256:ab08af91cf4d847a6e15d7d5eeae5fead1487caf16ff3a2056dbe64d058fd246"}, + {file = "coverage-7.2.4-cp311-cp311-win_amd64.whl", hash = "sha256:876e4ef3eff00b50787867c5bae84857a9af4c369a9d5b266cd9b19f61e48ef7"}, + {file = "coverage-7.2.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3fc9cde48de956bfbacea026936fbd4974ff1dc2f83397c6f1968f0142c9d50b"}, + {file = "coverage-7.2.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:12bc9127c8aca2f7c25c9acca53da3db6799b2999b40f28c2546237b7ea28459"}, + {file = "coverage-7.2.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2857894c22833d3da6e113623a9b7440159b2295280b4e0d954cadbfa724b85a"}, + {file = "coverage-7.2.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d4db4e6c115d869cd5397d3d21fd99e4c7053205c33a4ae725c90d19dcd178af"}, + {file = "coverage-7.2.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:f37ae1804596f13d811e0247ffc8219f5261b3565bdf45fcbb4fc091b8e9ff35"}, + {file = "coverage-7.2.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:cdee9a77fd0ce000781680b6a1f4b721c567f66f2f73a49be1843ff439d634f3"}, + {file = "coverage-7.2.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:0b65a6a5484b7f2970393d6250553c05b2ede069e0e18abe907fdc7f3528252e"}, + {file = "coverage-7.2.4-cp37-cp37m-win32.whl", hash = "sha256:1a3e8697cb40f28e5bcfb6f4bda7852d96dbb6f6fd7cc306aba4ae690c9905ab"}, + {file = "coverage-7.2.4-cp37-cp37m-win_amd64.whl", hash = "sha256:4078939c4b7053e14e87c65aa68dbed7867e326e450f94038bfe1a1b22078ff9"}, + {file = "coverage-7.2.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:603a2b172126e3b08c11ca34200143089a088cd0297d4cfc4922d2c1c3a892f9"}, + {file = "coverage-7.2.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:72751d117ceaad3b1ea3bcb9e85f5409bbe9fb8a40086e17333b994dbccc0718"}, + {file = "coverage-7.2.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f19ba9301e6fb0b94ba71fda9a1b02d11f0aab7f8e2455122a4e2921b6703c2f"}, + {file = "coverage-7.2.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2d784177a7fb9d0f58d24d3e60638c8b729c3693963bf67fa919120f750db237"}, + {file = "coverage-7.2.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1d2a9180beff1922b09bd7389e23454928e108449e646c26da5c62e29b0bf4e3"}, + {file = "coverage-7.2.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:39747afc854a7ee14e5e132da7db179d6281faf97dc51e6d7806651811c47538"}, + {file = "coverage-7.2.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:60feb703abc8d78e9427d873bcf924c9e30cf540a21971ef5a17154da763b60f"}, + {file = "coverage-7.2.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:c2becddfcbf3d994a8f4f9dd2b6015cae3a3eff50dedc6e4a17c3cccbe8f93d4"}, + {file = "coverage-7.2.4-cp38-cp38-win32.whl", hash = "sha256:56a674ad18d6b04008283ca03c012be913bf89d91c0803c54c24600b300d9e51"}, + {file = "coverage-7.2.4-cp38-cp38-win_amd64.whl", hash = "sha256:ab08e03add2cf5793e66ac1bbbb24acfa90c125476f5724f5d44c56eeec1d635"}, + {file = "coverage-7.2.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:92b565c51732ea2e7e541709ccce76391b39f4254260e5922e08e00971e88e33"}, + {file = "coverage-7.2.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8769a67e8816c7e94d5bf446fc0501641fde78fdff362feb28c2c64d45d0e9b1"}, + {file = "coverage-7.2.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:56d74d6fbd5a98a5629e8467b719b0abea9ca01a6b13555d125c84f8bf4ea23d"}, + {file = "coverage-7.2.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d9f770c6052d9b5c9b0e824fd8c003fe33276473b65b4f10ece9565ceb62438e"}, + {file = "coverage-7.2.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3023ce23e41a6f006c09f7e6d62b6c069c36bdc9f7de16a5ef823acc02e6c63"}, + {file = "coverage-7.2.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:fabd1f4d12dfd6b4f309208c2f31b116dc5900e0b42dbafe4ee1bc7c998ffbb0"}, + {file = "coverage-7.2.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:e41a7f44e73b37c6f0132ecfdc1c8b67722f42a3d9b979e6ebc150c8e80cf13a"}, + {file = "coverage-7.2.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:864e36947289be05abd83267c4bade35e772526d3e9653444a9dc891faf0d698"}, + {file = "coverage-7.2.4-cp39-cp39-win32.whl", hash = "sha256:ea534200efbf600e60130c48552f99f351cae2906898a9cd924c1c7f2fb02853"}, + {file = "coverage-7.2.4-cp39-cp39-win_amd64.whl", hash = "sha256:00f8fd8a5fe1ffc3aef78ea2dbf553e5c0f4664324e878995e38d41f037eb2b3"}, + {file = "coverage-7.2.4-pp37.pp38.pp39-none-any.whl", hash = "sha256:856bcb837e96adede31018a0854ce7711a5d6174db1a84e629134970676c54fa"}, + {file = "coverage-7.2.4.tar.gz", hash = "sha256:7283f78d07a201ac7d9dc2ac2e4faaea99c4d302f243ee5b4e359f3e170dc008"}, ] [package.dependencies] From 3b3ca1eaeb53a337b6c6eaa8715f6ee6c5196286 Mon Sep 17 00:00:00 2001 From: Leandro Damascena Date: Mon, 1 May 2023 11:56:23 +0100 Subject: [PATCH 088/100] feat(jmespath): new built-in envelopes to unwrap S3 events (#2169) Co-authored-by: Ruben Fonseca Co-authored-by: Heitor Lessa --- .../utilities/jmespath_utils/envelopes.py | 5 ++++ docs/utilities/jmespath_functions.md | 28 ++++++++++++------- docs/utilities/validation.md | 20 ++++++------- .../src/extract_data_from_builtin_envelope.py | 12 ++++++-- 4 files changed, 42 insertions(+), 23 deletions(-) diff --git a/aws_lambda_powertools/utilities/jmespath_utils/envelopes.py b/aws_lambda_powertools/utilities/jmespath_utils/envelopes.py index df50e5f98d4..f4aecb24bae 100644 --- a/aws_lambda_powertools/utilities/jmespath_utils/envelopes.py +++ b/aws_lambda_powertools/utilities/jmespath_utils/envelopes.py @@ -6,3 +6,8 @@ CLOUDWATCH_EVENTS_SCHEDULED = EVENTBRIDGE KINESIS_DATA_STREAM = "Records[*].kinesis.powertools_json(powertools_base64(data))" CLOUDWATCH_LOGS = "awslogs.powertools_base64_gzip(data) | powertools_json(@).logEvents[*]" +S3_SNS_SQS = "Records[*].powertools_json(body).powertools_json(Message).Records[0]" +S3_SQS = "Records[*].powertools_json(body).Records[0]" +S3_SNS_KINESIS_FIREHOSE = "records[*].powertools_json(powertools_base64(data)).powertools_json(Message).Records[0]" +S3_KINESIS_FIREHOSE = "records[*].powertools_json(powertools_base64(data)).Records[0]" +S3_EVENTBRIDGE_SQS = "Records[*].powertools_json(body).detail" diff --git a/docs/utilities/jmespath_functions.md b/docs/utilities/jmespath_functions.md index a01a72ced16..41b8c3704ce 100644 --- a/docs/utilities/jmespath_functions.md +++ b/docs/utilities/jmespath_functions.md @@ -64,16 +64,24 @@ We provide built-in envelopes for popular AWS Lambda event sources to easily dec These are all built-in envelopes you can use along with their expression as a reference: -| Envelope | JMESPath expression | -| --------------------------------- | ------------------------------------------------------------- | -| **`API_GATEWAY_REST`** | `powertools_json(body)` | -| **`API_GATEWAY_HTTP`** | `API_GATEWAY_REST` | -| **`SQS`** | `Records[*].powertools_json(body)` | -| **`SNS`** | `Records[0].Sns.Message | powertools_json(@)` | -| **`EVENTBRIDGE`** | `detail` | -| **`CLOUDWATCH_EVENTS_SCHEDULED`** | `EVENTBRIDGE` | -| **`KINESIS_DATA_STREAM`** | `Records[*].kinesis.powertools_json(powertools_base64(data))` | -| **`CLOUDWATCH_LOGS`** | `awslogs.powertools_base64_gzip(data) | powertools_json(@).logEvents[*]` | +| Envelope | JMESPath expression | +| --------------------------------- | ------------------------------------------------------------------------------------------ | +| **`API_GATEWAY_HTTP`** | `powertools_json(body)` | +| **`API_GATEWAY_REST`** | `powertools_json(body)` | +| **`CLOUDWATCH_EVENTS_SCHEDULED`** | `detail` | +| **`CLOUDWATCH_LOGS`** | `awslogs.powertools_base64_gzip(data) | powertools_json(@).logEvents[*]` | +| **`EVENTBRIDGE`** | `detail` | +| **`KINESIS_DATA_STREAM`** | `Records[*].kinesis.powertools_json(powertools_base64(data))` | +| **`S3_EVENTBRIDGE_SQS`** | `Records[*].powertools_json(body).detail` | +| **`S3_KINESIS_FIREHOSE`** | `records[*].powertools_json(powertools_base64(data)).Records[0]` | +| **`S3_SNS_KINESIS_FIREHOSE`** | `records[*].powertools_json(powertools_base64(data)).powertools_json(Message).Records[0]` | +| **`S3_SNS_SQS`** | `Records[*].powertools_json(body).powertools_json(Message).Records[0]` | +| **`S3_SQS`** | `Records[*].powertools_json(body).Records[0]` | +| **`SNS`** | `Records[0].Sns.Message | powertools_json(@)` | +| **`SQS`** | `Records[*].powertools_json(body)` | + +???+ tip "Using SNS?" + If you don't require SNS metadata, enable [raw message delivery](https://docs.aws.amazon.com/sns/latest/dg/sns-large-payload-raw-message-delivery.html){target="_blank"}. It will reduce multiple payload layers and size, when using SNS in combination with other services _(e.g., SQS, S3, etc)_. ## Advanced diff --git a/docs/utilities/validation.md b/docs/utilities/validation.md index ca5907a5fe1..277a1f91f81 100644 --- a/docs/utilities/validation.md +++ b/docs/utilities/validation.md @@ -141,16 +141,16 @@ We provide built-in envelopes to easily extract the payload from popular event s Here is a handy table with built-in envelopes along with their JMESPath expressions in case you want to build your own. -| Envelope name | JMESPath expression | -| ------------------------------- | ------------------------------------------------------------- | -| **API_GATEWAY_REST** | "powertools_json(body)" | -| **API_GATEWAY_HTTP** | "powertools_json(body)" | -| **SQS** | "Records[*].powertools_json(body)" | -| **SNS** | "Records[0].Sns.Message | powertools_json(@)" | -| **EVENTBRIDGE** | "detail" | -| **CLOUDWATCH_EVENTS_SCHEDULED** | "detail" | -| **KINESIS_DATA_STREAM** | "Records[*].kinesis.powertools_json(powertools_base64(data))" | -| **CLOUDWATCH_LOGS** | "awslogs.powertools_base64_gzip(data) | powertools_json(@).logEvents[*]" | +| Envelope | JMESPath expression | +| --------------------------------- | ------------------------------------------------------------------------ | +| **`API_GATEWAY_HTTP`** | `powertools_json(body)` | +| **`API_GATEWAY_REST`** | `powertools_json(body)` | +| **`CLOUDWATCH_EVENTS_SCHEDULED`** | `detail` | +| **`CLOUDWATCH_LOGS`** | `awslogs.powertools_base64_gzip(data) | powertools_json(@).logEvents[*]` | +| **`EVENTBRIDGE`** | `detail` | +| **`KINESIS_DATA_STREAM`** | `Records[*].kinesis.powertools_json(powertools_base64(data))` | +| **`SNS`** | `Records[0].Sns.Message | powertools_json(@)` | +| **`SQS`** | `Records[*].powertools_json(body)` | ## Advanced diff --git a/examples/jmespath_functions/src/extract_data_from_builtin_envelope.py b/examples/jmespath_functions/src/extract_data_from_builtin_envelope.py index 31ae6cf268c..d078e396519 100644 --- a/examples/jmespath_functions/src/extract_data_from_builtin_envelope.py +++ b/examples/jmespath_functions/src/extract_data_from_builtin_envelope.py @@ -1,12 +1,18 @@ +from __future__ import annotations + +from aws_lambda_powertools import Logger from aws_lambda_powertools.utilities.jmespath_utils import ( envelopes, extract_data_from_envelope, ) from aws_lambda_powertools.utilities.typing import LambdaContext +logger = Logger() + def handler(event: dict, context: LambdaContext) -> dict: - payload = extract_data_from_envelope(data=event, envelope=envelopes.SQS) - customer_id = payload.get("customerId") # now deserialized + records: list = extract_data_from_envelope(data=event, envelope=envelopes.SQS) + for record in records: # records is a list + logger.info(record.get("customerId")) # now deserialized - return {"customer_id": customer_id, "message": "success", "statusCode": 200} + return {"message": "success", "statusCode": 200} From af4679e5e0031a7ae4ab96ef9a9b0a0e1674a42c Mon Sep 17 00:00:00 2001 From: Release bot Date: Mon, 1 May 2023 10:56:44 +0000 Subject: [PATCH 089/100] update changelog with latest changes --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 690144b2b19..cea08f71071 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,12 +16,16 @@ ## Features * **ci:** dispatch GitHub analytics action ([#2161](https://github.com/awslabs/aws-lambda-powertools-python/issues/2161)) +* **event_source:** add support for dynamic partitions in the Api Gateway Authorizer event ([#2176](https://github.com/awslabs/aws-lambda-powertools-python/issues/2176)) * **event_sources:** Add __str__ to Data Classes base DictWrapper ([#2129](https://github.com/awslabs/aws-lambda-powertools-python/issues/2129)) +* **jmespath:** new built-in envelopes to unwrap S3 events ([#2169](https://github.com/awslabs/aws-lambda-powertools-python/issues/2169)) * **metrics:** add flush_metrics() method to allow manual flushing of metrics ([#2171](https://github.com/awslabs/aws-lambda-powertools-python/issues/2171)) ## Maintenance * add dummy reusable dispatch analytics job +* **deps-dev:** bump coverage from 7.2.3 to 7.2.4 ([#2179](https://github.com/awslabs/aws-lambda-powertools-python/issues/2179)) +* **deps-dev:** bump cfn-lint from 0.77.3 to 0.77.4 ([#2178](https://github.com/awslabs/aws-lambda-powertools-python/issues/2178)) * **deps-dev:** bump aws-cdk from 2.76.0 to 2.77.0 ([#2174](https://github.com/awslabs/aws-lambda-powertools-python/issues/2174)) * **deps-dev:** bump mypy-boto3-lambda from 1.26.115 to 1.26.122 ([#2172](https://github.com/awslabs/aws-lambda-powertools-python/issues/2172)) * **deps-dev:** bump cfn-lint from 0.77.2 to 0.77.3 ([#2165](https://github.com/awslabs/aws-lambda-powertools-python/issues/2165)) From 26cf2b76178bdd510e1e405d24fc09e33a1b94ec Mon Sep 17 00:00:00 2001 From: Leandro Damascena Date: Mon, 1 May 2023 18:55:45 +0100 Subject: [PATCH 090/100] tests: addressing Ruben's feedback --- tests/events/{sqsS3Event.json => s3SqsEvent.json} | 0 tests/unit/parser/test_s3.py | 9 ++++++--- 2 files changed, 6 insertions(+), 3 deletions(-) rename tests/events/{sqsS3Event.json => s3SqsEvent.json} (100%) diff --git a/tests/events/sqsS3Event.json b/tests/events/s3SqsEvent.json similarity index 100% rename from tests/events/sqsS3Event.json rename to tests/events/s3SqsEvent.json diff --git a/tests/unit/parser/test_s3.py b/tests/unit/parser/test_s3.py index 42124a8d058..6ae2656ddd2 100644 --- a/tests/unit/parser/test_s3.py +++ b/tests/unit/parser/test_s3.py @@ -113,7 +113,7 @@ def test_s3_eventbridge_notification_object_restore_completed_event(): def test_s3_sqs_event_notification(): - raw_event = load_event("sqsS3Event.json") + raw_event = load_event("s3SqsEvent.json") model = S3SqsEventNotificationModel(**raw_event) body = json.loads(raw_event["Records"][0]["body"]) @@ -127,14 +127,17 @@ def test_s3_sqs_event_notification(): def test_s3_sqs_event_notification_body_invalid_json(): - raw_event = load_event("s3Event.json") + raw_event = load_event("s3SqsEvent.json") + + for record in raw_event["Records"]: + record["body"] = "invalid body" with pytest.raises(ValidationError): S3SqsEventNotificationModel(**raw_event) def test_s3_sqs_event_notification_body_containing_arbitrary_json(): - raw_event = load_event("sqsS3Event.json") + raw_event = load_event("s3SqsEvent.json") for record in raw_event["Records"]: record["body"] = {"foo": "bar"} From 280e6ef3b425fe8aec74391f40a8fe6d9728d3f4 Mon Sep 17 00:00:00 2001 From: Heitor Lessa Date: Mon, 1 May 2023 21:11:02 +0200 Subject: [PATCH 091/100] feat(logger): add DatadogLogFormatter and observability provider (#2183) --- aws_lambda_powertools/logging/formatter.py | 4 +- .../logging/formatters/__init__.py | 5 ++ .../logging/formatters/datadog.py | 77 +++++++++++++++++++ docs/core/logger.md | 20 +++++ ...servability_provider_builtin_formatters.py | 5 ++ .../test_logger_powertools_formatter.py | 20 +++++ 6 files changed, 129 insertions(+), 2 deletions(-) create mode 100644 aws_lambda_powertools/logging/formatters/__init__.py create mode 100644 aws_lambda_powertools/logging/formatters/datadog.py create mode 100644 examples/logger/src/observability_provider_builtin_formatters.py diff --git a/aws_lambda_powertools/logging/formatter.py b/aws_lambda_powertools/logging/formatter.py index 93e91e0dc8d..db80876c798 100644 --- a/aws_lambda_powertools/logging/formatter.py +++ b/aws_lambda_powertools/logging/formatter.py @@ -139,11 +139,11 @@ def __init__( if self.utc: self.converter = time.gmtime - super(LambdaPowertoolsFormatter, self).__init__(datefmt=self.datefmt) - self.keys_combined = {**self._build_default_keys(), **kwargs} self.log_format.update(**self.keys_combined) + super().__init__(datefmt=self.datefmt) + def serialize(self, log: Dict) -> str: """Serialize structured log dict to JSON str""" return self.json_serializer(log) diff --git a/aws_lambda_powertools/logging/formatters/__init__.py b/aws_lambda_powertools/logging/formatters/__init__.py new file mode 100644 index 00000000000..b6974414f4c --- /dev/null +++ b/aws_lambda_powertools/logging/formatters/__init__.py @@ -0,0 +1,5 @@ +"""Built-in Logger formatters for Observability Providers that require custom config.""" + +# NOTE: we don't expose formatters directly (barrel import) +# as we cannot know if they'll need additional dependencies in the future +# so we isolate to avoid a performance hit and workarounds like lazy imports diff --git a/aws_lambda_powertools/logging/formatters/datadog.py b/aws_lambda_powertools/logging/formatters/datadog.py new file mode 100644 index 00000000000..fa92bf74598 --- /dev/null +++ b/aws_lambda_powertools/logging/formatters/datadog.py @@ -0,0 +1,77 @@ +from __future__ import annotations + +from typing import Any, Callable + +from aws_lambda_powertools.logging.formatter import LambdaPowertoolsFormatter + + +class DatadogLogFormatter(LambdaPowertoolsFormatter): + def __init__( + self, + json_serializer: Callable[[dict], str] | None = None, + json_deserializer: Callable[[dict | str | bool | int | float], str] | None = None, + json_default: Callable[[Any], Any] | None = None, + datefmt: str | None = None, + use_datetime_directive: bool = False, + log_record_order: list[str] | None = None, + utc: bool = False, + use_rfc3339: bool = True, # NOTE: The only change from our base formatter + **kwargs, + ): + """Datadog formatter to comply with Datadog log parsing + + Changes compared to the default Logger Formatter: + + - timestamp format to use RFC3339 e.g., "2023-05-01T15:34:26.841+0200" + + + Parameters + ---------- + log_record_order : list[str] | None, optional + _description_, by default None + + Parameters + ---------- + json_serializer : Callable, optional + function to serialize `obj` to a JSON formatted `str`, by default json.dumps + json_deserializer : Callable, optional + function to deserialize `str`, `bytes`, bytearray` containing a JSON document to a Python `obj`, + by default json.loads + json_default : Callable, optional + function to coerce unserializable values, by default str + + Only used when no custom JSON encoder is set + + datefmt : str, optional + String directives (strftime) to format log timestamp. + + See https://docs.python.org/3/library/time.html#time.strftime or + use_datetime_directive: str, optional + Interpret `datefmt` as a format string for `datetime.datetime.strftime`, rather than + `time.strftime` - Only useful when used alongside `datefmt`. + + See https://docs.python.org/3/library/datetime.html#strftime-strptime-behavior . This + also supports a custom %F directive for milliseconds. + + log_record_order : list, optional + set order of log keys when logging, by default ["level", "location", "message", "timestamp"] + + utc : bool, optional + set logging timestamp to UTC, by default False to continue to use local time as per stdlib + use_rfc3339: bool, optional + Whether to use a popular dateformat that complies with both RFC3339 and ISO8601. + e.g., 2022-10-27T16:27:43.738+02:00. + kwargs + Key-value to persist in all log messages + """ + super().__init__( + json_serializer=json_serializer, + json_deserializer=json_deserializer, + json_default=json_default, + datefmt=datefmt, + use_datetime_directive=use_datetime_directive, + log_record_order=log_record_order, + utc=utc, + use_rfc3339=use_rfc3339, + **kwargs, + ) diff --git a/docs/core/logger.md b/docs/core/logger.md index 8bccdafeec3..2f0472368c3 100644 --- a/docs/core/logger.md +++ b/docs/core/logger.md @@ -445,6 +445,26 @@ If you prefer configuring it separately, or you'd want to bring this JSON Format --8<-- "examples/logger/src/powertools_formatter_setup.py" ``` +### Observability providers + +!!! note "In this context, an observability provider is an [AWS Lambda Partner](https://go.aws/3HtU6CZ){target="_blank"} offering a platform for logging, metrics, traces, etc." + +You can send logs to the observability provider of your choice via [Lambda Extensions](https://aws.amazon.com/blogs/compute/using-aws-lambda-extensions-to-send-logs-to-custom-destinations/){target="_blank"}. In most cases, you shouldn't need any custom Logger configuration, and logs will be shipped async without any performance impact. + +#### Built-in formatters + +In rare circumstances where JSON logs are not parsed correctly by your provider, we offer built-in formatters to make this transition easier. + +| Provider | Formatter | Notes | +| -------- | --------------------- | ---------------------------------------------------- | +| Datadog | `DatadogLogFormatter` | Modifies default timestamp to use RFC3339 by default | + +You can use import and use them as any other Logger formatter via `logger_formatter` parameter: + +```python hl_lines="2 4" title="Using built-in Logger Formatters" +--8<-- "examples/logger/src/observability_provider_builtin_formatters.py" +``` + ### Migrating from other Loggers If you're migrating from other Loggers, there are few key points to be aware of: [Service parameter](#the-service-parameter), [Inheriting Loggers](#inheriting-loggers), [Overriding Log records](#overriding-log-records), and [Logging exceptions](#logging-exceptions). diff --git a/examples/logger/src/observability_provider_builtin_formatters.py b/examples/logger/src/observability_provider_builtin_formatters.py new file mode 100644 index 00000000000..3817f1f1b55 --- /dev/null +++ b/examples/logger/src/observability_provider_builtin_formatters.py @@ -0,0 +1,5 @@ +from aws_lambda_powertools import Logger +from aws_lambda_powertools.logging.formatters.datadog import DatadogLogFormatter + +logger = Logger(service="payment", logger_formatter=DatadogLogFormatter()) +logger.info("hello") diff --git a/tests/functional/test_logger_powertools_formatter.py b/tests/functional/test_logger_powertools_formatter.py index 7276f49d487..8b874894e27 100644 --- a/tests/functional/test_logger_powertools_formatter.py +++ b/tests/functional/test_logger_powertools_formatter.py @@ -3,12 +3,14 @@ import json import os import random +import re import string import time import pytest from aws_lambda_powertools import Logger +from aws_lambda_powertools.logging.formatters.datadog import DatadogLogFormatter @pytest.fixture @@ -22,6 +24,10 @@ def service_name(): return "".join(random.SystemRandom().choice(chars) for _ in range(15)) +def capture_logging_output(stdout): + return json.loads(stdout.getvalue().strip()) + + @pytest.mark.parametrize("level", ["DEBUG", "WARNING", "ERROR", "INFO", "CRITICAL"]) def test_setup_with_valid_log_levels(stdout, level, service_name): logger = Logger(service=service_name, level=level, stream=stdout, request_id="request id!", another="value") @@ -309,3 +315,17 @@ def test_log_json_pretty_indent(stdout, service_name, monkeypatch): # THEN the json should contain more than line new_lines = stdout.getvalue().count(os.linesep) assert new_lines > 1 + + +def test_datadog_formatter_use_rfc3339_date(stdout, service_name): + # GIVEN Datadog Log Formatter is used + logger = Logger(service=service_name, stream=stdout, logger_formatter=DatadogLogFormatter()) + RFC3339_REGEX = r"^((?:(\d{4}-\d{2}-\d{2})T(\d{2}:\d{2}:\d{2}(?:\.\d+)?))(Z|[\+-]\d{2}:\d{2})?)$" + + # WHEN a log statement happens + logger.info({}) + + # THEN the timestamp uses RFC3339 by default + log = capture_logging_output(stdout) + + assert re.fullmatch(RFC3339_REGEX, log["timestamp"]) # "2022-10-27T17:42:26.841+0200" From 91e95943da49b7a0548a561cd642fca5222ffbcb Mon Sep 17 00:00:00 2001 From: Release bot Date: Mon, 1 May 2023 19:11:33 +0000 Subject: [PATCH 092/100] update changelog with latest changes --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index cea08f71071..5bc8e10e2a5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ * **event_source:** add support for dynamic partitions in the Api Gateway Authorizer event ([#2176](https://github.com/awslabs/aws-lambda-powertools-python/issues/2176)) * **event_sources:** Add __str__ to Data Classes base DictWrapper ([#2129](https://github.com/awslabs/aws-lambda-powertools-python/issues/2129)) * **jmespath:** new built-in envelopes to unwrap S3 events ([#2169](https://github.com/awslabs/aws-lambda-powertools-python/issues/2169)) +* **logger:** add DatadogLogFormatter and observability provider ([#2183](https://github.com/awslabs/aws-lambda-powertools-python/issues/2183)) * **metrics:** add flush_metrics() method to allow manual flushing of metrics ([#2171](https://github.com/awslabs/aws-lambda-powertools-python/issues/2171)) ## Maintenance From 22eb702ec926d789505b80679df30fb1d702c08a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 May 2023 22:23:10 +0100 Subject: [PATCH 093/100] chore(deps-dev): bump coverage from 7.2.4 to 7.2.5 (#2186) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 104 ++++++++++++++++++++++++++-------------------------- 1 file changed, 52 insertions(+), 52 deletions(-) diff --git a/poetry.lock b/poetry.lock index 1b4bf602c82..8b674111e5b 100644 --- a/poetry.lock +++ b/poetry.lock @@ -536,63 +536,63 @@ typeguard = ">=2.13.3,<2.14.0" [[package]] name = "coverage" -version = "7.2.4" +version = "7.2.5" description = "Code coverage measurement for Python" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "coverage-7.2.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9e5eedde6e6e241ec3816f05767cc77e7456bf5ec6b373fb29917f0990e2078f"}, - {file = "coverage-7.2.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5c6c6e3b8fb6411a2035da78d86516bfcfd450571d167304911814407697fb7a"}, - {file = "coverage-7.2.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f7668a621afc52db29f6867e0e9c72a1eec9f02c94a7c36599119d557cf6e471"}, - {file = "coverage-7.2.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cdfb53bef4b2739ff747ebbd76d6ac5384371fd3c7a8af08899074eba034d483"}, - {file = "coverage-7.2.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a5c4f2e44a2ae15fa6883898e756552db5105ca4bd918634cbd5b7c00e19e8a1"}, - {file = "coverage-7.2.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:700bc9fb1074e0c67c09fe96a803de66663830420781df8dc9fb90d7421d4ccb"}, - {file = "coverage-7.2.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:ac4861241e693e21b280f07844ae0e0707665e1dfcbf9466b793584984ae45c4"}, - {file = "coverage-7.2.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:3d6f3c5b6738a494f17c73b4aa3aa899865cc33a74aa85e3b5695943b79ad3ce"}, - {file = "coverage-7.2.4-cp310-cp310-win32.whl", hash = "sha256:437da7d2fcc35bf45e04b7e9cfecb7c459ec6f6dc17a8558ed52e8d666c2d9ab"}, - {file = "coverage-7.2.4-cp310-cp310-win_amd64.whl", hash = "sha256:1d3893f285fd76f56651f04d1efd3bdce251c32992a64c51e5d6ec3ba9e3f9c9"}, - {file = "coverage-7.2.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6a17bf32e9e3333d78606ac1073dd20655dc0752d5b923fa76afd3bc91674ab4"}, - {file = "coverage-7.2.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f7ffdb3af2a01ce91577f84fc0faa056029fe457f3183007cffe7b11ea78b23c"}, - {file = "coverage-7.2.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:89e63b38c7b888e00fd42ce458f838dccb66de06baea2da71801b0fc9070bfa0"}, - {file = "coverage-7.2.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4522dd9aeb9cc2c4c54ce23933beb37a4e106ec2ba94f69138c159024c8a906a"}, - {file = "coverage-7.2.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:29c7d88468f01a75231797173b52dc66d20a8d91b8bb75c88fc5861268578f52"}, - {file = "coverage-7.2.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bc47015fc0455753e8aba1f38b81b731aaf7f004a0c390b404e0fcf1d6c1d72f"}, - {file = "coverage-7.2.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:5c122d120c11a236558c339a59b4b60947b38ac9e3ad30a0e0e02540b37bf536"}, - {file = "coverage-7.2.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:50fda3d33b705b9c01e3b772cfa7d14de8aec2ec2870e4320992c26d057fde12"}, - {file = "coverage-7.2.4-cp311-cp311-win32.whl", hash = "sha256:ab08af91cf4d847a6e15d7d5eeae5fead1487caf16ff3a2056dbe64d058fd246"}, - {file = "coverage-7.2.4-cp311-cp311-win_amd64.whl", hash = "sha256:876e4ef3eff00b50787867c5bae84857a9af4c369a9d5b266cd9b19f61e48ef7"}, - {file = "coverage-7.2.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3fc9cde48de956bfbacea026936fbd4974ff1dc2f83397c6f1968f0142c9d50b"}, - {file = "coverage-7.2.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:12bc9127c8aca2f7c25c9acca53da3db6799b2999b40f28c2546237b7ea28459"}, - {file = "coverage-7.2.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2857894c22833d3da6e113623a9b7440159b2295280b4e0d954cadbfa724b85a"}, - {file = "coverage-7.2.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d4db4e6c115d869cd5397d3d21fd99e4c7053205c33a4ae725c90d19dcd178af"}, - {file = "coverage-7.2.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:f37ae1804596f13d811e0247ffc8219f5261b3565bdf45fcbb4fc091b8e9ff35"}, - {file = "coverage-7.2.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:cdee9a77fd0ce000781680b6a1f4b721c567f66f2f73a49be1843ff439d634f3"}, - {file = "coverage-7.2.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:0b65a6a5484b7f2970393d6250553c05b2ede069e0e18abe907fdc7f3528252e"}, - {file = "coverage-7.2.4-cp37-cp37m-win32.whl", hash = "sha256:1a3e8697cb40f28e5bcfb6f4bda7852d96dbb6f6fd7cc306aba4ae690c9905ab"}, - {file = "coverage-7.2.4-cp37-cp37m-win_amd64.whl", hash = "sha256:4078939c4b7053e14e87c65aa68dbed7867e326e450f94038bfe1a1b22078ff9"}, - {file = "coverage-7.2.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:603a2b172126e3b08c11ca34200143089a088cd0297d4cfc4922d2c1c3a892f9"}, - {file = "coverage-7.2.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:72751d117ceaad3b1ea3bcb9e85f5409bbe9fb8a40086e17333b994dbccc0718"}, - {file = "coverage-7.2.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f19ba9301e6fb0b94ba71fda9a1b02d11f0aab7f8e2455122a4e2921b6703c2f"}, - {file = "coverage-7.2.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2d784177a7fb9d0f58d24d3e60638c8b729c3693963bf67fa919120f750db237"}, - {file = "coverage-7.2.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1d2a9180beff1922b09bd7389e23454928e108449e646c26da5c62e29b0bf4e3"}, - {file = "coverage-7.2.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:39747afc854a7ee14e5e132da7db179d6281faf97dc51e6d7806651811c47538"}, - {file = "coverage-7.2.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:60feb703abc8d78e9427d873bcf924c9e30cf540a21971ef5a17154da763b60f"}, - {file = "coverage-7.2.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:c2becddfcbf3d994a8f4f9dd2b6015cae3a3eff50dedc6e4a17c3cccbe8f93d4"}, - {file = "coverage-7.2.4-cp38-cp38-win32.whl", hash = "sha256:56a674ad18d6b04008283ca03c012be913bf89d91c0803c54c24600b300d9e51"}, - {file = "coverage-7.2.4-cp38-cp38-win_amd64.whl", hash = "sha256:ab08e03add2cf5793e66ac1bbbb24acfa90c125476f5724f5d44c56eeec1d635"}, - {file = "coverage-7.2.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:92b565c51732ea2e7e541709ccce76391b39f4254260e5922e08e00971e88e33"}, - {file = "coverage-7.2.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8769a67e8816c7e94d5bf446fc0501641fde78fdff362feb28c2c64d45d0e9b1"}, - {file = "coverage-7.2.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:56d74d6fbd5a98a5629e8467b719b0abea9ca01a6b13555d125c84f8bf4ea23d"}, - {file = "coverage-7.2.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d9f770c6052d9b5c9b0e824fd8c003fe33276473b65b4f10ece9565ceb62438e"}, - {file = "coverage-7.2.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3023ce23e41a6f006c09f7e6d62b6c069c36bdc9f7de16a5ef823acc02e6c63"}, - {file = "coverage-7.2.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:fabd1f4d12dfd6b4f309208c2f31b116dc5900e0b42dbafe4ee1bc7c998ffbb0"}, - {file = "coverage-7.2.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:e41a7f44e73b37c6f0132ecfdc1c8b67722f42a3d9b979e6ebc150c8e80cf13a"}, - {file = "coverage-7.2.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:864e36947289be05abd83267c4bade35e772526d3e9653444a9dc891faf0d698"}, - {file = "coverage-7.2.4-cp39-cp39-win32.whl", hash = "sha256:ea534200efbf600e60130c48552f99f351cae2906898a9cd924c1c7f2fb02853"}, - {file = "coverage-7.2.4-cp39-cp39-win_amd64.whl", hash = "sha256:00f8fd8a5fe1ffc3aef78ea2dbf553e5c0f4664324e878995e38d41f037eb2b3"}, - {file = "coverage-7.2.4-pp37.pp38.pp39-none-any.whl", hash = "sha256:856bcb837e96adede31018a0854ce7711a5d6174db1a84e629134970676c54fa"}, - {file = "coverage-7.2.4.tar.gz", hash = "sha256:7283f78d07a201ac7d9dc2ac2e4faaea99c4d302f243ee5b4e359f3e170dc008"}, + {file = "coverage-7.2.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:883123d0bbe1c136f76b56276074b0c79b5817dd4238097ffa64ac67257f4b6c"}, + {file = "coverage-7.2.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d2fbc2a127e857d2f8898aaabcc34c37771bf78a4d5e17d3e1f5c30cd0cbc62a"}, + {file = "coverage-7.2.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f3671662dc4b422b15776cdca89c041a6349b4864a43aa2350b6b0b03bbcc7f"}, + {file = "coverage-7.2.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:780551e47d62095e088f251f5db428473c26db7829884323e56d9c0c3118791a"}, + {file = "coverage-7.2.5-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:066b44897c493e0dcbc9e6a6d9f8bbb6607ef82367cf6810d387c09f0cd4fe9a"}, + {file = "coverage-7.2.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b9a4ee55174b04f6af539218f9f8083140f61a46eabcaa4234f3c2a452c4ed11"}, + {file = "coverage-7.2.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:706ec567267c96717ab9363904d846ec009a48d5f832140b6ad08aad3791b1f5"}, + {file = "coverage-7.2.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ae453f655640157d76209f42c62c64c4d4f2c7f97256d3567e3b439bd5c9b06c"}, + {file = "coverage-7.2.5-cp310-cp310-win32.whl", hash = "sha256:f81c9b4bd8aa747d417407a7f6f0b1469a43b36a85748145e144ac4e8d303cb5"}, + {file = "coverage-7.2.5-cp310-cp310-win_amd64.whl", hash = "sha256:dc945064a8783b86fcce9a0a705abd7db2117d95e340df8a4333f00be5efb64c"}, + {file = "coverage-7.2.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:40cc0f91c6cde033da493227797be2826cbf8f388eaa36a0271a97a332bfd7ce"}, + {file = "coverage-7.2.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a66e055254a26c82aead7ff420d9fa8dc2da10c82679ea850d8feebf11074d88"}, + {file = "coverage-7.2.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c10fbc8a64aa0f3ed136b0b086b6b577bc64d67d5581acd7cc129af52654384e"}, + {file = "coverage-7.2.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9a22cbb5ede6fade0482111fa7f01115ff04039795d7092ed0db43522431b4f2"}, + {file = "coverage-7.2.5-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:292300f76440651529b8ceec283a9370532f4ecba9ad67d120617021bb5ef139"}, + {file = "coverage-7.2.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:7ff8f3fb38233035028dbc93715551d81eadc110199e14bbbfa01c5c4a43f8d8"}, + {file = "coverage-7.2.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:a08c7401d0b24e8c2982f4e307124b671c6736d40d1c39e09d7a8687bddf83ed"}, + {file = "coverage-7.2.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ef9659d1cda9ce9ac9585c045aaa1e59223b143f2407db0eaee0b61a4f266fb6"}, + {file = "coverage-7.2.5-cp311-cp311-win32.whl", hash = "sha256:30dcaf05adfa69c2a7b9f7dfd9f60bc8e36b282d7ed25c308ef9e114de7fc23b"}, + {file = "coverage-7.2.5-cp311-cp311-win_amd64.whl", hash = "sha256:97072cc90f1009386c8a5b7de9d4fc1a9f91ba5ef2146c55c1f005e7b5c5e068"}, + {file = "coverage-7.2.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:bebea5f5ed41f618797ce3ffb4606c64a5de92e9c3f26d26c2e0aae292f015c1"}, + {file = "coverage-7.2.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:828189fcdda99aae0d6bf718ea766b2e715eabc1868670a0a07bf8404bf58c33"}, + {file = "coverage-7.2.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e8a95f243d01ba572341c52f89f3acb98a3b6d1d5d830efba86033dd3687ade"}, + {file = "coverage-7.2.5-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e8834e5f17d89e05697c3c043d3e58a8b19682bf365048837383abfe39adaed5"}, + {file = "coverage-7.2.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d1f25ee9de21a39b3a8516f2c5feb8de248f17da7eead089c2e04aa097936b47"}, + {file = "coverage-7.2.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:1637253b11a18f453e34013c665d8bf15904c9e3c44fbda34c643fbdc9d452cd"}, + {file = "coverage-7.2.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8e575a59315a91ccd00c7757127f6b2488c2f914096077c745c2f1ba5b8c0969"}, + {file = "coverage-7.2.5-cp37-cp37m-win32.whl", hash = "sha256:509ecd8334c380000d259dc66feb191dd0a93b21f2453faa75f7f9cdcefc0718"}, + {file = "coverage-7.2.5-cp37-cp37m-win_amd64.whl", hash = "sha256:12580845917b1e59f8a1c2ffa6af6d0908cb39220f3019e36c110c943dc875b0"}, + {file = "coverage-7.2.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b5016e331b75310610c2cf955d9f58a9749943ed5f7b8cfc0bb89c6134ab0a84"}, + {file = "coverage-7.2.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:373ea34dca98f2fdb3e5cb33d83b6d801007a8074f992b80311fc589d3e6b790"}, + {file = "coverage-7.2.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a063aad9f7b4c9f9da7b2550eae0a582ffc7623dca1c925e50c3fbde7a579771"}, + {file = "coverage-7.2.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:38c0a497a000d50491055805313ed83ddba069353d102ece8aef5d11b5faf045"}, + {file = "coverage-7.2.5-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a2b3b05e22a77bb0ae1a3125126a4e08535961c946b62f30985535ed40e26614"}, + {file = "coverage-7.2.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:0342a28617e63ad15d96dca0f7ae9479a37b7d8a295f749c14f3436ea59fdcb3"}, + {file = "coverage-7.2.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:cf97ed82ca986e5c637ea286ba2793c85325b30f869bf64d3009ccc1a31ae3fd"}, + {file = "coverage-7.2.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:c2c41c1b1866b670573657d584de413df701f482574bad7e28214a2362cb1fd1"}, + {file = "coverage-7.2.5-cp38-cp38-win32.whl", hash = "sha256:10b15394c13544fce02382360cab54e51a9e0fd1bd61ae9ce012c0d1e103c813"}, + {file = "coverage-7.2.5-cp38-cp38-win_amd64.whl", hash = "sha256:a0b273fe6dc655b110e8dc89b8ec7f1a778d78c9fd9b4bda7c384c8906072212"}, + {file = "coverage-7.2.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5c587f52c81211d4530fa6857884d37f514bcf9453bdeee0ff93eaaf906a5c1b"}, + {file = "coverage-7.2.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4436cc9ba5414c2c998eaedee5343f49c02ca93b21769c5fdfa4f9d799e84200"}, + {file = "coverage-7.2.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6599bf92f33ab041e36e06d25890afbdf12078aacfe1f1d08c713906e49a3fe5"}, + {file = "coverage-7.2.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:857abe2fa6a4973f8663e039ead8d22215d31db613ace76e4a98f52ec919068e"}, + {file = "coverage-7.2.5-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6f5cab2d7f0c12f8187a376cc6582c477d2df91d63f75341307fcdcb5d60303"}, + {file = "coverage-7.2.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:aa387bd7489f3e1787ff82068b295bcaafbf6f79c3dad3cbc82ef88ce3f48ad3"}, + {file = "coverage-7.2.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:156192e5fd3dbbcb11cd777cc469cf010a294f4c736a2b2c891c77618cb1379a"}, + {file = "coverage-7.2.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:bd3b4b8175c1db502adf209d06136c000df4d245105c8839e9d0be71c94aefe1"}, + {file = "coverage-7.2.5-cp39-cp39-win32.whl", hash = "sha256:ddc5a54edb653e9e215f75de377354e2455376f416c4378e1d43b08ec50acc31"}, + {file = "coverage-7.2.5-cp39-cp39-win_amd64.whl", hash = "sha256:338aa9d9883aaaad53695cb14ccdeb36d4060485bb9388446330bef9c361c252"}, + {file = "coverage-7.2.5-pp37.pp38.pp39-none-any.whl", hash = "sha256:8877d9b437b35a85c18e3c6499b23674684bf690f5d96c1006a1ef61f9fdf0f3"}, + {file = "coverage-7.2.5.tar.gz", hash = "sha256:f99ef080288f09ffc687423b8d60978cf3a465d3f404a18d1a05474bd8575a47"}, ] [package.dependencies] From 32666e4c56a875a4faab3890042e54eefa84f6b9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 May 2023 22:23:25 +0100 Subject: [PATCH 094/100] chore(deps-dev): bump types-requests from 2.28.11.17 to 2.29.0.0 (#2187) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 8 ++++---- pyproject.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/poetry.lock b/poetry.lock index 8b674111e5b..cba1912511a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2798,14 +2798,14 @@ files = [ [[package]] name = "types-requests" -version = "2.28.11.17" +version = "2.29.0.0" description = "Typing stubs for requests" category = "dev" optional = false python-versions = "*" files = [ - {file = "types-requests-2.28.11.17.tar.gz", hash = "sha256:0d580652ce903f643f8c3b494dd01d29367ea57cea0c7ad7f65cf3169092edb0"}, - {file = "types_requests-2.28.11.17-py3-none-any.whl", hash = "sha256:cc1aba862575019306b2ed134eb1ea994cab1c887a22e18d3383e6dd42e9789b"}, + {file = "types-requests-2.29.0.0.tar.gz", hash = "sha256:c86f4a955d943d2457120dbe719df24ef0924e11177164d10a0373cf311d7b4d"}, + {file = "types_requests-2.29.0.0-py3-none-any.whl", hash = "sha256:4cf6e323e856c779fbe8815bb977a5bf5d6c5034713e4c17ff2a9a20610f5b27"}, ] [package.dependencies] @@ -3035,4 +3035,4 @@ validation = ["fastjsonschema"] [metadata] lock-version = "2.0" python-versions = "^3.7.4" -content-hash = "95d239c02c517fac0f3359f75f34b871e6ca4699538cd290e669e83b3f108ae7" +content-hash = "1b65a257f53a8c00d851795c7f6a984ab07676494ebe26777db71525eb03c436" diff --git a/pyproject.toml b/pyproject.toml index 62e7e0b61b7..4540fc83ec7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -80,7 +80,7 @@ mypy-boto3-secretsmanager = "^1.26.116" mypy-boto3-ssm = "^1.26.97" mypy-boto3-s3 = "^1.26.116" mypy-boto3-xray = "^1.26.122" -types-requests = "^2.28.11" +types-requests = "^2.29.0" typing-extensions = "^4.4.0" mkdocs-material = "^9.1.8" filelock = "^3.12.0" From d109c6c372eae8605a95a389683ce1b15511156d Mon Sep 17 00:00:00 2001 From: arjanschaaf Date: Tue, 2 May 2023 09:28:56 +0200 Subject: [PATCH 095/100] docs(batch): fixed typo in DynamoDB Streams section (#2189) --- docs/utilities/batch.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/utilities/batch.md b/docs/utilities/batch.md index 296ce4f02ac..c4d7dc26e6c 100644 --- a/docs/utilities/batch.md +++ b/docs/utilities/batch.md @@ -508,7 +508,7 @@ Processing batches from Kinesis works in three stages: ### Processing messages from DynamoDB -Processing batches from Kinesis works in three stages: +Processing batches from DynamoDB Streams works in three stages: 1. Instantiate **`BatchProcessor`** and choose **`EventType.DynamoDBStreams`** for the event type 2. Define your function to handle each batch record, and use [`DynamoDBRecord`](data_classes.md#dynamodb-streams){target="_blank"} type annotation for autocompletion From 2be654ced383762442c08ff4820d18761e9b8e41 Mon Sep 17 00:00:00 2001 From: Release bot Date: Tue, 2 May 2023 07:29:18 +0000 Subject: [PATCH 096/100] update changelog with latest changes --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5bc8e10e2a5..056c7041a49 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ ## Documentation +* **batch:** fixed typo in DynamoDB Streams section ([#2189](https://github.com/awslabs/aws-lambda-powertools-python/issues/2189)) * **homepage:** add customer references section ([#2159](https://github.com/awslabs/aws-lambda-powertools-python/issues/2159)) * **tutorial:** use newer sam cli template; update to py3.10 ([#2167](https://github.com/awslabs/aws-lambda-powertools-python/issues/2167)) @@ -25,6 +26,8 @@ ## Maintenance * add dummy reusable dispatch analytics job +* **deps-dev:** bump types-requests from 2.28.11.17 to 2.29.0.0 ([#2187](https://github.com/awslabs/aws-lambda-powertools-python/issues/2187)) +* **deps-dev:** bump coverage from 7.2.4 to 7.2.5 ([#2186](https://github.com/awslabs/aws-lambda-powertools-python/issues/2186)) * **deps-dev:** bump coverage from 7.2.3 to 7.2.4 ([#2179](https://github.com/awslabs/aws-lambda-powertools-python/issues/2179)) * **deps-dev:** bump cfn-lint from 0.77.3 to 0.77.4 ([#2178](https://github.com/awslabs/aws-lambda-powertools-python/issues/2178)) * **deps-dev:** bump aws-cdk from 2.76.0 to 2.77.0 ([#2174](https://github.com/awslabs/aws-lambda-powertools-python/issues/2174)) From 28ca40a0e4f4e9961ffe6be10e8473e4aac4b08c Mon Sep 17 00:00:00 2001 From: Ruben Fonseca Date: Tue, 2 May 2023 11:05:29 +0200 Subject: [PATCH 097/100] docs(we-made-this): add serverless transactional message app (#2182) --- docs/we_made_this.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/we_made_this.md b/docs/we_made_this.md index 950a8c9f24d..a9022b68e5d 100644 --- a/docs/we_made_this.md +++ b/docs/we_made_this.md @@ -133,3 +133,13 @@ This repository provides a working, deployable, open source based, AWS Lambda ha This handler embodies Serverless best practices and has all the bells and whistles for a proper production ready handler. It uses many of the AWS Lambda Powertools utilities for Python. :material-github: [github.com/ran-isenberg/aws-lambda-handler-cookbook](https://github.com/ran-isenberg/aws-lambda-handler-cookbook){:target="_blank"} + +### Serverless Transactional Message App + +> **Author: [Santiago Garcia Arango](mailto:san99tiago@gmail.com) [:material-web:](https://san99tiago.com/){target="_blank"} [:material-linkedin:](https://www.linkedin.com/in/san99tiago/){target="_blank"}** + +This repository contains a well documented example of a Transactional Messages App that illustrates how to use Lambda PowerTools to process SQS messages in batches (with IaC on top of CDK). + +It uses LambdaPowerTools Logger, Tracing, DataClasses and includes unit tests. + +:material-github: [github.com/san99tiago/aws-cdk-transactional-messages](https://github.com/san99tiago/aws-cdk-transactional-messages){:target="_blank"} From 8f302f680906719fd3712be4076a16d59ab9cd08 Mon Sep 17 00:00:00 2001 From: Release bot Date: Tue, 2 May 2023 09:05:55 +0000 Subject: [PATCH 098/100] update changelog with latest changes --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 056c7041a49..8e6379462bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ * **batch:** fixed typo in DynamoDB Streams section ([#2189](https://github.com/awslabs/aws-lambda-powertools-python/issues/2189)) * **homepage:** add customer references section ([#2159](https://github.com/awslabs/aws-lambda-powertools-python/issues/2159)) * **tutorial:** use newer sam cli template; update to py3.10 ([#2167](https://github.com/awslabs/aws-lambda-powertools-python/issues/2167)) +* **we-made-this:** add serverless transactional message app ([#2182](https://github.com/awslabs/aws-lambda-powertools-python/issues/2182)) ## Features From a2529c735fcc1efef32c29e44401541c5cff2b7d Mon Sep 17 00:00:00 2001 From: heitorlessa Date: Tue, 2 May 2023 11:50:25 +0200 Subject: [PATCH 099/100] docs(jmespath): fix MD037/no-space-in-emphasis --- docs/utilities/jmespath_functions.md | 32 ++++++++++++++-------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/docs/utilities/jmespath_functions.md b/docs/utilities/jmespath_functions.md index 41b8c3704ce..e86fb824faf 100644 --- a/docs/utilities/jmespath_functions.md +++ b/docs/utilities/jmespath_functions.md @@ -64,24 +64,24 @@ We provide built-in envelopes for popular AWS Lambda event sources to easily dec These are all built-in envelopes you can use along with their expression as a reference: -| Envelope | JMESPath expression | -| --------------------------------- | ------------------------------------------------------------------------------------------ | -| **`API_GATEWAY_HTTP`** | `powertools_json(body)` | -| **`API_GATEWAY_REST`** | `powertools_json(body)` | -| **`CLOUDWATCH_EVENTS_SCHEDULED`** | `detail` | -| **`CLOUDWATCH_LOGS`** | `awslogs.powertools_base64_gzip(data) | powertools_json(@).logEvents[*]` | -| **`EVENTBRIDGE`** | `detail` | -| **`KINESIS_DATA_STREAM`** | `Records[*].kinesis.powertools_json(powertools_base64(data))` | -| **`S3_EVENTBRIDGE_SQS`** | `Records[*].powertools_json(body).detail` | -| **`S3_KINESIS_FIREHOSE`** | `records[*].powertools_json(powertools_base64(data)).Records[0]` | -| **`S3_SNS_KINESIS_FIREHOSE`** | `records[*].powertools_json(powertools_base64(data)).powertools_json(Message).Records[0]` | -| **`S3_SNS_SQS`** | `Records[*].powertools_json(body).powertools_json(Message).Records[0]` | -| **`S3_SQS`** | `Records[*].powertools_json(body).Records[0]` | -| **`SNS`** | `Records[0].Sns.Message | powertools_json(@)` | -| **`SQS`** | `Records[*].powertools_json(body)` | +| Envelope | JMESPath expression | +| --------------------------------- | ----------------------------------------------------------------------------------------- | +| **`API_GATEWAY_HTTP`** | `powertools_json(body)` | +| **`API_GATEWAY_REST`** | `powertools_json(body)` | +| **`CLOUDWATCH_EVENTS_SCHEDULED`** | `detail` | +| **`CLOUDWATCH_LOGS`** | `awslogs.powertools_base64_gzip(data) | powertools_json(@).logEvents[*]` | +| **`EVENTBRIDGE`** | `detail` | +| **`KINESIS_DATA_STREAM`** | `Records[*].kinesis.powertools_json(powertools_base64(data))` | +| **`S3_EVENTBRIDGE_SQS`** | `Records[*].powertools_json(body).detail` | +| **`S3_KINESIS_FIREHOSE`** | `records[*].powertools_json(powertools_base64(data)).Records[0]` | +| **`S3_SNS_KINESIS_FIREHOSE`** | `records[*].powertools_json(powertools_base64(data)).powertools_json(Message).Records[0]` | +| **`S3_SNS_SQS`** | `Records[*].powertools_json(body).powertools_json(Message).Records[0]` | +| **`S3_SQS`** | `Records[*].powertools_json(body).Records[0]` | +| **`SNS`** | `Records[0].Sns.Message | powertools_json(@)` | +| **`SQS`** | `Records[*].powertools_json(body)` | ???+ tip "Using SNS?" - If you don't require SNS metadata, enable [raw message delivery](https://docs.aws.amazon.com/sns/latest/dg/sns-large-payload-raw-message-delivery.html){target="_blank"}. It will reduce multiple payload layers and size, when using SNS in combination with other services _(e.g., SQS, S3, etc)_. + If you don't require SNS metadata, enable [raw message delivery](https://docs.aws.amazon.com/sns/latest/dg/sns-large-payload-raw-message-delivery.html){target="_blank"}. It will reduce multiple payload layers and size, when using SNS in combination with other services (_e.g., SQS, S3, etc_). ## Advanced From 7b158ef063d1355a53136ee2778d41f5cccf1128 Mon Sep 17 00:00:00 2001 From: Release bot Date: Tue, 2 May 2023 09:51:11 +0000 Subject: [PATCH 100/100] update changelog with latest changes --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8e6379462bd..63cbf342771 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ * **batch:** fixed typo in DynamoDB Streams section ([#2189](https://github.com/awslabs/aws-lambda-powertools-python/issues/2189)) * **homepage:** add customer references section ([#2159](https://github.com/awslabs/aws-lambda-powertools-python/issues/2159)) +* **jmespath:** fix MD037/no-space-in-emphasis * **tutorial:** use newer sam cli template; update to py3.10 ([#2167](https://github.com/awslabs/aws-lambda-powertools-python/issues/2167)) * **we-made-this:** add serverless transactional message app ([#2182](https://github.com/awslabs/aws-lambda-powertools-python/issues/2182))