From 4b4dd5974f5b430acfb7502ea50d1533309ee677 Mon Sep 17 00:00:00 2001 From: Michael Brewer Date: Thu, 21 Oct 2021 07:14:20 -0700 Subject: [PATCH 01/14] Update docs/core/event_handler/api_gateway.md Co-authored-by: Dani Comnea --- docs/core/event_handler/api_gateway.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/core/event_handler/api_gateway.md b/docs/core/event_handler/api_gateway.md index a31cc6deee5..47c8f91d6d3 100644 --- a/docs/core/event_handler/api_gateway.md +++ b/docs/core/event_handler/api_gateway.md @@ -855,7 +855,7 @@ You can instruct API Gateway handler to use a custom serializer to best suit you ### Splitting routes across multiple files -When building a larger application, sometimes to helps to split out your routes into multiple file. Also +When building a larger application, sometimes it helps to split out your routes into multiple file. Also there might be cases where you have some shared routes for multiple lambdas like a `health` status lambda to be used with Application Load Balancer. From dc45fd87b005a3a2aa733d4a7d009eaaf138174b Mon Sep 17 00:00:00 2001 From: Steve Cook Date: Sat, 23 Oct 2021 15:58:11 +1000 Subject: [PATCH 02/14] Removed unused import, added typing imports, fixed typo in example. (#774) --- docs/utilities/parser.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/utilities/parser.md b/docs/utilities/parser.md index 9f1bed3c0cb..7c9af95896f 100644 --- a/docs/utilities/parser.md +++ b/docs/utilities/parser.md @@ -57,8 +57,9 @@ Use the decorator for fail fast scenarios where you want your Lambda function to === "event_parser_decorator.py" ```python hl_lines="18" - from aws_lambda_powertools.utilities.parser import event_parser, BaseModel, ValidationError + from aws_lambda_powertools.utilities.parser import event_parser, BaseModel from aws_lambda_powertools.utilities.typing import LambdaContext + from typing import List, Optional import json @@ -80,7 +81,7 @@ Use the decorator for fail fast scenarios where you want your Lambda function to print(event.description) print(event.items) - order_items = [items for item in event.items] + order_items = [item for item in event.items] ... payload = { @@ -107,6 +108,7 @@ Use this standalone function when you want more control over the data validation ```python hl_lines="21 30" from aws_lambda_powertools.utilities.parser import parse, BaseModel, ValidationError + from typing import List, Optional class OrderItem(BaseModel): id: int From c3769f3a11f7bc81ee5ead8c2a111efdbf506379 Mon Sep 17 00:00:00 2001 From: Arthur Freund Date: Sat, 23 Oct 2021 07:59:15 +0200 Subject: [PATCH 03/14] Fix middleware sample (#772) --- docs/utilities/middleware_factory.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/utilities/middleware_factory.md b/docs/utilities/middleware_factory.md index 366ae7eda66..253bf6157c3 100644 --- a/docs/utilities/middleware_factory.md +++ b/docs/utilities/middleware_factory.md @@ -47,9 +47,8 @@ You can also have your own keyword arguments after the mandatory arguments. # Obfuscate email before calling Lambda handler if fields: for field in fields: - field = event.get(field, "") if field in event: - event[field] = obfuscate(field) + event[field] = obfuscate(event[field]) return handler(event, context) From dd9c3d6388d537e3c0dba71490605aa9d59c2711 Mon Sep 17 00:00:00 2001 From: Steve Cook Date: Sat, 23 Oct 2021 15:58:11 +1000 Subject: [PATCH 04/14] Removed unused import, added typing imports, fixed typo in example. (#774) --- docs/utilities/parser.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/utilities/parser.md b/docs/utilities/parser.md index 9f1bed3c0cb..7c9af95896f 100644 --- a/docs/utilities/parser.md +++ b/docs/utilities/parser.md @@ -57,8 +57,9 @@ Use the decorator for fail fast scenarios where you want your Lambda function to === "event_parser_decorator.py" ```python hl_lines="18" - from aws_lambda_powertools.utilities.parser import event_parser, BaseModel, ValidationError + from aws_lambda_powertools.utilities.parser import event_parser, BaseModel from aws_lambda_powertools.utilities.typing import LambdaContext + from typing import List, Optional import json @@ -80,7 +81,7 @@ Use the decorator for fail fast scenarios where you want your Lambda function to print(event.description) print(event.items) - order_items = [items for item in event.items] + order_items = [item for item in event.items] ... payload = { @@ -107,6 +108,7 @@ Use this standalone function when you want more control over the data validation ```python hl_lines="21 30" from aws_lambda_powertools.utilities.parser import parse, BaseModel, ValidationError + from typing import List, Optional class OrderItem(BaseModel): id: int From 48aceb014681e6a3a83ce57f790bba7e36787cbc Mon Sep 17 00:00:00 2001 From: Arthur Freund Date: Sat, 23 Oct 2021 07:59:15 +0200 Subject: [PATCH 05/14] Fix middleware sample (#772) --- docs/utilities/middleware_factory.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/utilities/middleware_factory.md b/docs/utilities/middleware_factory.md index 366ae7eda66..253bf6157c3 100644 --- a/docs/utilities/middleware_factory.md +++ b/docs/utilities/middleware_factory.md @@ -47,9 +47,8 @@ You can also have your own keyword arguments after the mandatory arguments. # Obfuscate email before calling Lambda handler if fields: for field in fields: - field = event.get(field, "") if field in event: - event[field] = obfuscate(field) + event[field] = obfuscate(event[field]) return handler(event, context) From 4c41ec5c0b8f4864819561bc71494029131135c9 Mon Sep 17 00:00:00 2001 From: Jonas Neubert Date: Sun, 24 Oct 2021 23:21:50 -0700 Subject: [PATCH 06/14] docs: fix indentation of SAM snippets in install section (#778) --- docs/index.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/index.md b/docs/index.md index c67ef2fc6fe..70a35fb5506 100644 --- a/docs/index.md +++ b/docs/index.md @@ -43,8 +43,8 @@ Include Lambda Powertools in your function using the [AWS Lambda Console](https: MyLambdaFunction: Type: AWS::Serverless::Function Properties: - Layers: - - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPython:3 + Layers: + - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPython:3 ``` === "Serverless framework" @@ -196,16 +196,16 @@ If using SAM, you can include this SAR App as part of your shared Layers stack, AwsLambdaPowertoolsPythonLayer: Type: AWS::Serverless::Application Properties: - Location: - ApplicationId: arn:aws:serverlessrepo:eu-west-1:057560766410:applications/aws-lambda-powertools-python-layer - SemanticVersion: 1.21.1 # change to latest semantic version available in SAR + Location: + ApplicationId: arn:aws:serverlessrepo:eu-west-1:057560766410:applications/aws-lambda-powertools-python-layer + SemanticVersion: 1.21.1 # change to latest semantic version available in SAR MyLambdaFunction: Type: AWS::Serverless::Function Properties: - Layers: - # fetch Layer ARN from SAR App stack output - - !GetAtt AwsLambdaPowertoolsPythonLayer.Outputs.LayerVersionArn + Layers: + # fetch Layer ARN from SAR App stack output + - !GetAtt AwsLambdaPowertoolsPythonLayer.Outputs.LayerVersionArn ``` === "Serverless framework" @@ -223,10 +223,10 @@ If using SAM, you can include this SAR App as part of your shared Layers stack, AwsLambdaPowertoolsPythonLayer: Type: AWS::Serverless::Application Properties: - Location: - ApplicationId: arn:aws:serverlessrepo:eu-west-1:057560766410:applications/aws-lambda-powertools-python-layer - # Find latest from github.com/awslabs/aws-lambda-powertools-python/releases - SemanticVersion: 1.21.1 + Location: + ApplicationId: arn:aws:serverlessrepo:eu-west-1:057560766410:applications/aws-lambda-powertools-python-layer + # Find latest from github.com/awslabs/aws-lambda-powertools-python/releases + SemanticVersion: 1.21.1 ``` === "CDK" From bbd8b6370803b91d481e70af99a6a5de842eb016 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 29 Oct 2021 09:39:51 +0200 Subject: [PATCH 07/14] chore(deps-dev): bump pytest-asyncio from 0.15.1 to 0.16.0 (#782) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 23 +++++++++++++++++++---- pyproject.toml | 2 +- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/poetry.lock b/poetry.lock index e13747793c1..63f11b1dd0e 100644 --- a/poetry.lock +++ b/poetry.lock @@ -772,7 +772,7 @@ testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xm [[package]] name = "pytest-asyncio" -version = "0.15.1" +version = "0.16.0" description = "Pytest support for asyncio." category = "dev" optional = false @@ -1055,7 +1055,7 @@ pydantic = ["pydantic", "email-validator"] [metadata] lock-version = "1.1" python-versions = "^3.6.1" -content-hash = "dc363cbaa0be00b64c588301bebd0e83dd7c34a48132711cdd5d573a08d0a05b" +content-hash = "2f666f603e288e7c556b1dbe3b101e513c8054f2ec8e0e46373f37eb1d119630" [metadata.files] appdirs = [ @@ -1255,6 +1255,9 @@ markupsafe = [ {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d7d807855b419fc2ed3e631034685db6079889a1f01d5d9dac950f764da3dad"}, {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:add36cb2dbb8b736611303cd3bfcee00afd96471b09cda130da3581cbdc56a6d"}, {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:168cd0a3642de83558a5153c8bd34f175a9a6e7f6dc6384b9655d2697312a646"}, + {file = "MarkupSafe-2.0.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4dc8f9fb58f7364b63fd9f85013b780ef83c11857ae79f2feda41e270468dd9b"}, + {file = "MarkupSafe-2.0.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:20dca64a3ef2d6e4d5d615a3fd418ad3bde77a47ec8a23d984a12b5b4c74491a"}, + {file = "MarkupSafe-2.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:cdfba22ea2f0029c9261a4bd07e830a8da012291fbe44dc794e488b6c9bb353a"}, {file = "MarkupSafe-2.0.1-cp310-cp310-win32.whl", hash = "sha256:99df47edb6bda1249d3e80fdabb1dab8c08ef3975f69aed437cb69d0a5de1e28"}, {file = "MarkupSafe-2.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:e0f138900af21926a02425cf736db95be9f4af72ba1bb21453432a07f6082134"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f9081981fe268bd86831e5c75f7de206ef275defcb82bc70740ae6dc507aee51"}, @@ -1266,6 +1269,9 @@ markupsafe = [ {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf5d821ffabf0ef3533c39c518f3357b171a1651c1ff6827325e4489b0e46c3c"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0d4b31cc67ab36e3392bbf3862cfbadac3db12bdd8b02a2731f509ed5b829724"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:baa1a4e8f868845af802979fcdbf0bb11f94f1cb7ced4c4b8a351bb60d108145"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:deb993cacb280823246a026e3b2d81c493c53de6acfd5e6bfe31ab3402bb37dd"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:63f3268ba69ace99cab4e3e3b5840b03340efed0948ab8f78d2fd87ee5442a4f"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:8d206346619592c6200148b01a2142798c989edcb9c896f9ac9722a99d4e77e6"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-win32.whl", hash = "sha256:6c4ca60fa24e85fe25b912b01e62cb969d69a23a5d5867682dd3e80b5b02581d"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b2f4bf27480f5e5e8ce285a8c8fd176c0b03e93dcc6646477d4630e83440c6a9"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0717a7390a68be14b8c793ba258e075c6f4ca819f15edfc2a3a027c823718567"}, @@ -1277,6 +1283,9 @@ markupsafe = [ {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e9936f0b261d4df76ad22f8fee3ae83b60d7c3e871292cd42f40b81b70afae85"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:2a7d351cbd8cfeb19ca00de495e224dea7e7d919659c2841bbb7f420ad03e2d6"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:60bf42e36abfaf9aff1f50f52644b336d4f0a3fd6d8a60ca0d054ac9f713a864"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d6c7ebd4e944c85e2c3421e612a7057a2f48d478d79e61800d81468a8d842207"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f0567c4dc99f264f49fe27da5f735f414c4e7e7dd850cfd8e69f0862d7c74ea9"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:89c687013cb1cd489a0f0ac24febe8c7a666e6e221b783e53ac50ebf68e45d86"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-win32.whl", hash = "sha256:a30e67a65b53ea0a5e62fe23682cfe22712e01f453b95233b25502f7c61cb415"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:611d1ad9a4288cf3e3c16014564df047fe08410e628f89805e475368bd304914"}, {file = "MarkupSafe-2.0.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5bb28c636d87e840583ee3adeb78172efc47c8b26127267f54a9c0ec251d41a9"}, @@ -1289,6 +1298,9 @@ markupsafe = [ {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6fcf051089389abe060c9cd7caa212c707e58153afa2c649f00346ce6d260f1b"}, {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5855f8438a7d1d458206a2466bf82b0f104a3724bf96a1c781ab731e4201731a"}, {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3dd007d54ee88b46be476e293f48c85048603f5f516008bee124ddd891398ed6"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:aca6377c0cb8a8253e493c6b451565ac77e98c2951c45f913e0b52facdcff83f"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:04635854b943835a6ea959e948d19dcd311762c5c0c6e1f0e16ee57022669194"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6300b8454aa6930a24b9618fbb54b5a68135092bc666f7b06901f897fa5c2fee"}, {file = "MarkupSafe-2.0.1-cp38-cp38-win32.whl", hash = "sha256:023cb26ec21ece8dc3907c0e8320058b2e0cb3c55cf9564da612bc325bed5e64"}, {file = "MarkupSafe-2.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:984d76483eb32f1bcb536dc27e4ad56bba4baa70be32fa87152832cdd9db0833"}, {file = "MarkupSafe-2.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2ef54abee730b502252bcdf31b10dacb0a416229b72c18b19e24a4509f273d26"}, @@ -1301,6 +1313,9 @@ markupsafe = [ {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c47adbc92fc1bb2b3274c4b3a43ae0e4573d9fbff4f54cd484555edbf030baf1"}, {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:37205cac2a79194e3750b0af2a5720d95f786a55ce7df90c3af697bfa100eaac"}, {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1f2ade76b9903f39aa442b4aadd2177decb66525062db244b35d71d0ee8599b6"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4296f2b1ce8c86a6aea78613c34bb1a672ea0e3de9c6ba08a960efe0b0a09047"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f02365d4e99430a12647f09b6cc8bab61a6564363f313126f775eb4f6ef798e"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5b6d930f030f8ed98e3e6c98ffa0652bdb82601e7a016ec2ab5d7ff23baa78d1"}, {file = "MarkupSafe-2.0.1-cp39-cp39-win32.whl", hash = "sha256:10f82115e21dc0dfec9ab5c0223652f7197feb168c940f3ef61563fc2d6beb74"}, {file = "MarkupSafe-2.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:693ce3f9e70a6cf7d2fb9e6c9d8b204b6b39897a2c4a1aa65728d5ac97dcc1d8"}, {file = "MarkupSafe-2.0.1.tar.gz", hash = "sha256:594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a"}, @@ -1434,8 +1449,8 @@ pytest = [ {file = "pytest-6.2.5.tar.gz", hash = "sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89"}, ] pytest-asyncio = [ - {file = "pytest-asyncio-0.15.1.tar.gz", hash = "sha256:2564ceb9612bbd560d19ca4b41347b54e7835c2f792c504f698e05395ed63f6f"}, - {file = "pytest_asyncio-0.15.1-py3-none-any.whl", hash = "sha256:3042bcdf1c5d978f6b74d96a151c4cfb9dcece65006198389ccd7e6c60eb1eea"}, + {file = "pytest-asyncio-0.16.0.tar.gz", hash = "sha256:7496c5977ce88c34379df64a66459fe395cd05543f0a2f837016e7144391fcfb"}, + {file = "pytest_asyncio-0.16.0-py3-none-any.whl", hash = "sha256:5f2a21273c47b331ae6aa5b36087047b4899e40f03f18397c0e65fa5cca54e9b"}, ] pytest-cov = [ {file = "pytest-cov-3.0.0.tar.gz", hash = "sha256:e7f0f5b1617d2210a2cabc266dfe2f4c75a8d32fb89eafb7ad9d06f6d076d470"}, diff --git a/pyproject.toml b/pyproject.toml index 53dfa42b912..450731bbfdc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -44,7 +44,7 @@ isort = "^5.9.3" pytest-cov = "^3.0.0" pytest-mock = "^3.5.1" pdoc3 = "^0.10.0" -pytest-asyncio = "^0.15.1" +pytest-asyncio = "^0.16.0" bandit = "^1.7.0" radon = "^5.1.0" xenon = "^0.8.0" From 1816f660e2e7b1a0378591ed113d724e1da13749 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 29 Oct 2021 07:40:27 +0000 Subject: [PATCH 08/14] chore(deps): bump boto3 from 1.18.61 to 1.19.6 (#783) Bumps [boto3](https://github.com/boto/boto3) from 1.18.61 to 1.19.6.
Changelog

Sourced from boto3's changelog.

1.19.6

  • api-change:gamelift: [botocore] Added support for Arm-based AWS Graviton2 instances, such as M6g, C6g, and R6g.
  • api-change:ecs: [botocore] Amazon ECS now supports running Fargate tasks on Windows Operating Systems Families which includes Windows Server 2019 Core and Windows Server 2019 Full.
  • api-change:sagemaker: [botocore] This release adds support for RStudio on SageMaker.
  • api-change:connectparticipant: [botocore] This release adds a new boolean attribute - Connect Participant - to the CreateParticipantConnection API, which can be used to mark the participant as connected.
  • api-change:ec2: [botocore] Added new read-only DenyAllIGWTraffic network interface attribute. Added support for DL1 24xlarge instances powered by Habana Gaudi Accelerators for deep learning model training workloads
  • api-change:ssm-incidents: [botocore] Updating documentation, adding new field to ConflictException to indicate earliest retry timestamp for some operations, increase maximum length of nextToken fields

1.19.5

  • api-change:autoscaling: [botocore] This release adds support for attribute-based instance type selection, a new EC2 Auto Scaling feature that lets customers express their instance requirements as a set of attributes, such as vCPU, memory, and storage.
  • api-change:ec2: [botocore] This release adds: attribute-based instance type selection for EC2 Fleet, Spot Fleet, a feature that lets customers express instance requirements as attributes like vCPU, memory, and storage; and Spot placement score, a feature that helps customers identify an optimal location to run Spot workloads.
  • enhancement:Session: Added get_partition_for_region to lookup partition for a given region_name
  • api-change:eks: [botocore] EKS managed node groups now support BOTTLEROCKET_x86_64 and BOTTLEROCKET_ARM_64 AMI types.
  • api-change:sagemaker: [botocore] This release allows customers to describe one or more versioned model packages through BatchDescribeModelPackage, update project via UpdateProject, modify and read customer metadata properties using Create, Update and Describe ModelPackage and enables cross account registration of model packages.
  • enhancement:Session: [botocore] Added get_partition_for_region allowing partition lookup by region name.
  • api-change:textract: [botocore] This release adds support for asynchronously analyzing invoice and receipt documents through two new APIs: StartExpenseAnalysis and GetExpenseAnalysis
  • enchancement:s3: TransferConfig now supports the max_bandwidth argument.

1.19.4

  • api-change:emr-containers: [botocore] This feature enables auto-generation of certificate to secure the managed-endpoint and removes the need for customer provided certificate-arn during managed-endpoint setup.
  • api-change:chime-sdk-messaging: [botocore] The Amazon Chime SDK now supports push notifications through Amazon Pinpoint
  • api-change:chime-sdk-identity: [botocore] The Amazon Chime SDK now supports push notifications through Amazon Pinpoint

1.19.3

  • api-change:rds: [botocore] This release adds support for Amazon RDS Custom, which is a new RDS management type that gives you full access to your database and operating system. For more information, see https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/rds-custom.html
  • api-change:auditmanager: [botocore] This release introduces a new feature for Audit Manager: Custom framework sharing. You can now share your custom frameworks with another AWS account, or replicate them into another AWS Region under your own account.
  • api-change:ec2: [botocore] This release adds support to create a VPN Connection that is not attached to a Gateway at the time of creation. Use this to create VPNs associated with Core Networks, or modify your VPN and attach a gateway using the modify API after creation.
  • api-change:route53resolver: [botocore] New API for ResolverConfig, which allows autodefined rules for reverse DNS resolution to be disabled for a VPC

1.19.2

  • api-change:quicksight: [botocore] Added QSearchBar option for GenerateEmbedUrlForRegisteredUser ExperienceConfiguration to support Q search bar embedding
  • api-change:auditmanager: [botocore] This release introduces character restrictions for ControlSet names. We updated regex patterns for the following attributes: ControlSet, CreateAssessmentFrameworkControlSet, and UpdateAssessmentFrameworkControlSet.
  • api-change:chime: [botocore] Chime VoiceConnector and VoiceConnectorGroup APIs will now return an ARN.

1.19.1

... (truncated)

Commits
  • 4e94e99 Merge branch 'release-1.19.6'
  • 43a8076 Bumping version to 1.19.6
  • 27de205 Add changelog entries from botocore
  • 527297d Merge branch 'release-1.19.5'
  • e25b889 Merge branch 'release-1.19.5' into develop
  • 6967a2d Bumping version to 1.19.5
  • 5d20ca0 Add changelog entries from botocore
  • 371f6d3 Add get_partition_for_region to Session (#3060)
  • c5487b5 Add max_bandwidth to TransferConfig (#3059)
  • a426ea0 Merge branch 'release-1.19.4'
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=boto3&package-manager=pip&previous-version=1.18.61&new-version=1.19.6)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- poetry.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/poetry.lock b/poetry.lock index 63f11b1dd0e..f4ea5457bdd 100644 --- a/poetry.lock +++ b/poetry.lock @@ -81,14 +81,14 @@ d = ["aiohttp (>=3.3.2)", "aiohttp-cors"] [[package]] name = "boto3" -version = "1.18.61" +version = "1.19.6" description = "The AWS SDK for Python" category = "main" optional = false python-versions = ">= 3.6" [package.dependencies] -botocore = ">=1.21.61,<1.22.0" +botocore = ">=1.22.6,<1.23.0" jmespath = ">=0.7.1,<1.0.0" s3transfer = ">=0.5.0,<0.6.0" @@ -97,7 +97,7 @@ crt = ["botocore[crt] (>=1.21.0,<2.0a0)"] [[package]] name = "botocore" -version = "1.21.61" +version = "1.22.6" description = "Low-level, data-driven core of boto 3." category = "main" optional = false @@ -109,7 +109,7 @@ python-dateutil = ">=2.1,<3.0.0" urllib3 = ">=1.25.4,<1.27" [package.extras] -crt = ["awscrt (==0.11.24)"] +crt = ["awscrt (==0.12.5)"] [[package]] name = "certifi" @@ -1082,12 +1082,12 @@ black = [ {file = "black-20.8b1.tar.gz", hash = "sha256:1c02557aa099101b9d21496f8a914e9ed2222ef70336404eeeac8edba836fbea"}, ] boto3 = [ - {file = "boto3-1.18.61-py3-none-any.whl", hash = "sha256:d2a8f8cd0a53093b2f1ab5a4b233533f1aa04e751209266597a05f50a46f6683"}, - {file = "boto3-1.18.61.tar.gz", hash = "sha256:08dc897299ecc9eef6df3cd296864154dfbc9f78edb8995b93258b59d747cbdc"}, + {file = "boto3-1.19.6-py3-none-any.whl", hash = "sha256:79e40de74faaf4b36fc885b10a2a39adb242ab499ba6d9506c6f91d0054b5338"}, + {file = "boto3-1.19.6.tar.gz", hash = "sha256:e8e20230fd8dfd991fa8459696ff2da96b15ba720f05f96d43174b2f04b328a9"}, ] botocore = [ - {file = "botocore-1.21.61-py3-none-any.whl", hash = "sha256:eda50985c229b01c7de6f0a0ccb561dfa52ded06c8c59044f624133a33357b94"}, - {file = "botocore-1.21.61.tar.gz", hash = "sha256:92ae0ca56a6582bddf42aca199ac3f67579910860bcd86166ae10f7a83f8841b"}, + {file = "botocore-1.22.6-py3-none-any.whl", hash = "sha256:5fa5de2deef817d0ef52b97dec2bc6e4489a3145afa3f5f4ec0ad6a3b213a019"}, + {file = "botocore-1.22.6.tar.gz", hash = "sha256:9210881ee5eef6fff30a2e1acfe9dea068a0885a13731ab2034e35775379637f"}, ] certifi = [ {file = "certifi-2020.12.5-py2.py3-none-any.whl", hash = "sha256:719a74fb9e33b9bd44cc7f3a8d94bc35e4049deebe19ba7d8e108280cfd59830"}, From 6e29ce74c9258978e420210047837706fbf3c9fd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 29 Oct 2021 07:46:17 +0000 Subject: [PATCH 09/14] chore(deps-dev): bump flake8-eradicate from 1.1.0 to 1.2.0 (#784) Bumps [flake8-eradicate](https://github.com/wemake-services/flake8-eradicate) from 1.1.0 to 1.2.0.
Release notes

Sourced from flake8-eradicate's releases.

Version 1.2.0

  • Adds flake8@4.0.0 support
  • Adds python3.10 support
Changelog

Sourced from flake8-eradicate's changelog.

1.2.0

Features

  • Adds flake8@4.0.0 support
  • Adds python3.10 support
Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=flake8-eradicate&package-manager=pip&previous-version=1.1.0&new-version=1.2.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- poetry.lock | 10 +++++----- pyproject.toml | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/poetry.lock b/poetry.lock index f4ea5457bdd..5e390f15008 100644 --- a/poetry.lock +++ b/poetry.lock @@ -298,7 +298,7 @@ six = "*" [[package]] name = "flake8-eradicate" -version = "1.1.0" +version = "1.2.0" description = "Flake8 plugin to find commented out code" category = "dev" optional = false @@ -307,7 +307,7 @@ python-versions = ">=3.6,<4.0" [package.dependencies] attrs = "*" eradicate = ">=2.0,<3.0" -flake8 = ">=3.5,<4.0" +flake8 = ">=3.5,<5" [[package]] name = "flake8-fixme" @@ -1055,7 +1055,7 @@ pydantic = ["pydantic", "email-validator"] [metadata] lock-version = "1.1" python-versions = "^3.6.1" -content-hash = "2f666f603e288e7c556b1dbe3b101e513c8054f2ec8e0e46373f37eb1d119630" +content-hash = "f927582047e5798e1add412681ae3e5f9388d38841455164f24a5d8104463664" [metadata.files] appdirs = [ @@ -1184,8 +1184,8 @@ flake8-debugger = [ {file = "flake8_debugger-4.0.0-py3-none-any.whl", hash = "sha256:82e64faa72e18d1bdd0000407502ebb8ecffa7bc027c62b9d4110ce27c091032"}, ] flake8-eradicate = [ - {file = "flake8-eradicate-1.1.0.tar.gz", hash = "sha256:f5917d6dbca352efcd10c15fdab9c55c48f0f26f6a8d47898b25d39101f170a8"}, - {file = "flake8_eradicate-1.1.0-py3-none-any.whl", hash = "sha256:d8e39b684a37c257a53cda817d86e2d96c9ba3450ddc292742623a5dfee04d9e"}, + {file = "flake8-eradicate-1.2.0.tar.gz", hash = "sha256:acaa1b6839ff00d284b805c432fdfa6047262bd15a5504ec945797e87b4de1fa"}, + {file = "flake8_eradicate-1.2.0-py3-none-any.whl", hash = "sha256:51dc660d0c1c1ed93af0f813540bbbf72ab2d3466c14e3f3bac371c618b6042f"}, ] flake8-fixme = [ {file = "flake8-fixme-1.1.1.tar.gz", hash = "sha256:50cade07d27a4c30d4f12351478df87339e67640c83041b664724bda6d16f33a"}, diff --git a/pyproject.toml b/pyproject.toml index 450731bbfdc..e72f6b5a3ed 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -48,7 +48,7 @@ pytest-asyncio = "^0.16.0" bandit = "^1.7.0" radon = "^5.1.0" xenon = "^0.8.0" -flake8-eradicate = "^1.1.0" +flake8-eradicate = "^1.2.0" flake8-bugbear = "^21.9.2" mkdocs-material = "^7.3.3" mkdocs-git-revision-date-plugin = "^0.3.1" From 9bc3a286cdc60adfb08066b42655729ff61fd5fb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 29 Oct 2021 07:46:22 +0000 Subject: [PATCH 10/14] chore(deps): bump urllib3 from 1.26.4 to 1.26.5 (#787) Bumps [urllib3](https://github.com/urllib3/urllib3) from 1.26.4 to 1.26.5.
Release notes

Sourced from urllib3's releases.

1.26.5

:warning: IMPORTANT: urllib3 v2.0 will drop support for Python 2: Read more in the v2.0 Roadmap

  • Fixed deprecation warnings emitted in Python 3.10.
  • Updated vendored six library to 1.16.0.
  • Improved performance of URL parser when splitting the authority component.

If you or your organization rely on urllib3 consider supporting us via GitHub Sponsors

Changelog

Sourced from urllib3's changelog.

1.26.5 (2021-05-26)

  • Fixed deprecation warnings emitted in Python 3.10.
  • Updated vendored six library to 1.16.0.
  • Improved performance of URL parser when splitting the authority component.
Commits
  • d161647 Release 1.26.5
  • 2d4a3fe Improve performance of sub-authority splitting in URL
  • 2698537 Update vendored six to 1.16.0
  • 07bed79 Fix deprecation warnings for Python 3.10 ssl module
  • d725a9b Add Python 3.10 to GitHub Actions
  • 339ad34 Use pytest==6.2.4 on Python 3.10+
  • f271c9c Apply latest Black formatting
  • 1884878 [1.26] Properly proxy EOF on the SSLTransport test suite
  • See full diff in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=urllib3&package-manager=pip&previous-version=1.26.4&new-version=1.26.5)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/awslabs/aws-lambda-powertools-python/network/alerts).
--- poetry.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/poetry.lock b/poetry.lock index 5e390f15008..53d306be248 100644 --- a/poetry.lock +++ b/poetry.lock @@ -994,16 +994,16 @@ python-versions = "*" [[package]] name = "urllib3" -version = "1.26.4" +version = "1.26.5" description = "HTTP library with thread-safe connection pooling, file post, and more." category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" [package.extras] +brotli = ["brotlipy (>=0.6.0)"] secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"] socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] -brotli = ["brotlipy (>=0.6.0)"] [[package]] name = "watchdog" @@ -1653,8 +1653,8 @@ typing-extensions = [ {file = "typing_extensions-3.10.0.0.tar.gz", hash = "sha256:50b6f157849174217d0656f99dc82fe932884fb250826c18350e159ec6cdf342"}, ] urllib3 = [ - {file = "urllib3-1.26.4-py2.py3-none-any.whl", hash = "sha256:2f4da4594db7e1e110a944bb1b551fdf4e6c136ad42e4234131391e21eb5b0df"}, - {file = "urllib3-1.26.4.tar.gz", hash = "sha256:e7b021f7241115872f92f43c6508082facffbd1c048e3c6e2bb9c2a157e28937"}, + {file = "urllib3-1.26.5-py2.py3-none-any.whl", hash = "sha256:753a0374df26658f99d826cfe40394a686d05985786d946fbe4165b5148f5a7c"}, + {file = "urllib3-1.26.5.tar.gz", hash = "sha256:a7acd0977125325f516bda9735fa7142b909a8d01e8b2e4c8108d0984e6e0098"}, ] watchdog = [ {file = "watchdog-2.1.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:9628f3f85375a17614a2ab5eac7665f7f7be8b6b0a2a228e6f6a2e91dd4bfe26"}, From 1fa6a7c8b9194303e901c2d786bbf15fc5e90a4d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 29 Oct 2021 07:48:15 +0000 Subject: [PATCH 11/14] chore(deps-dev): bump flake8-isort from 4.0.0 to 4.1.1 (#785) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [//]: # (dependabot-start) ⚠️ **Dependabot is rebasing this PR** ⚠️ Rebasing might not happen immediately, so don't worry if this takes some time. Note: if you make any changes to this PR yourself, they will take precedence over the rebase. --- [//]: # (dependabot-end) Bumps [flake8-isort](https://github.com/gforcada/flake8-isort) from 4.0.0 to 4.1.1.
Changelog

Sourced from flake8-isort's changelog.

4.1.1 (2021-10-14)

  • Release py3 only wheels..

4.1.0 (2021-10-14)

  • Support flake8 4.x [g-as]

  • Switch from travis-ci to github actions. [g-as]

  • Drop python 2.7 support and 3.5 as well [g-as]

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=flake8-isort&package-manager=pip&previous-version=4.0.0&new-version=4.1.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- poetry.lock | 12 ++++++------ pyproject.toml | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/poetry.lock b/poetry.lock index 53d306be248..0bb99d068ae 100644 --- a/poetry.lock +++ b/poetry.lock @@ -319,19 +319,19 @@ python-versions = "*" [[package]] name = "flake8-isort" -version = "4.0.0" +version = "4.1.1" description = "flake8 plugin that integrates isort ." category = "dev" optional = false python-versions = "*" [package.dependencies] -flake8 = ">=3.2.1,<4" +flake8 = ">=3.2.1,<5" isort = ">=4.3.5,<6" testfixtures = ">=6.8.0,<7" [package.extras] -test = ["pytest (>=4.0.2,<6)", "toml"] +test = ["pytest-cov"] [[package]] name = "flake8-variables-names" @@ -1055,7 +1055,7 @@ pydantic = ["pydantic", "email-validator"] [metadata] lock-version = "1.1" python-versions = "^3.6.1" -content-hash = "f927582047e5798e1add412681ae3e5f9388d38841455164f24a5d8104463664" +content-hash = "faa554f1cb4eafe6a4308fc71d3a64443d6cb65088c0937b4c90a4af10f31487" [metadata.files] appdirs = [ @@ -1192,8 +1192,8 @@ flake8-fixme = [ {file = "flake8_fixme-1.1.1-py2.py3-none-any.whl", hash = "sha256:226a6f2ef916730899f29ac140bed5d4a17e5aba79f00a0e3ae1eff1997cb1ac"}, ] flake8-isort = [ - {file = "flake8-isort-4.0.0.tar.gz", hash = "sha256:2b91300f4f1926b396c2c90185844eb1a3d5ec39ea6138832d119da0a208f4d9"}, - {file = "flake8_isort-4.0.0-py2.py3-none-any.whl", hash = "sha256:729cd6ef9ba3659512dee337687c05d79c78e1215fdf921ed67e5fe46cce2f3c"}, + {file = "flake8-isort-4.1.1.tar.gz", hash = "sha256:d814304ab70e6e58859bc5c3e221e2e6e71c958e7005239202fee19c24f82717"}, + {file = "flake8_isort-4.1.1-py3-none-any.whl", hash = "sha256:c4e8b6dcb7be9b71a02e6e5d4196cefcef0f3447be51e82730fb336fff164949"}, ] flake8-variables-names = [ {file = "flake8_variables_names-0.0.4.tar.gz", hash = "sha256:d6fa0571a807c72940b5773827c5760421ea6f8206595ff0a8ecfa01e42bf2cf"}, diff --git a/pyproject.toml b/pyproject.toml index e72f6b5a3ed..007eac4242e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,7 +38,7 @@ flake8-builtins = "^1.5.3" flake8-comprehensions = "^3.7.0" flake8-debugger = "^4.0.0" flake8-fixme = "^1.1.1" -flake8-isort = "^4.0.0" +flake8-isort = "^4.1.1" flake8-variables-names = "^0.0.4" isort = "^5.9.3" pytest-cov = "^3.0.0" From bb8e3b62d9ee0a43ad198a8635bd68d3449b557d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 29 Oct 2021 07:52:19 +0000 Subject: [PATCH 12/14] chore(deps-dev): bump mkdocs-material from 7.3.3 to 7.3.5 (#781) Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 7.3.3 to 7.3.5.
Release notes

Sourced from mkdocs-material's releases.

mkdocs-material-7.3.5

  • Added support for setting table of contents title via mkdocs.yml
  • Fixed back-to-top button position for right-to-left languages

mkdocs-material-7.3.4

  • Bumped MkDocs version to 1.2.3 to mitigate CVE-2021-40978
  • Fixed spacing issues when using integrate table of contents with tabs
  • Fixed some spacings issues for right-to-left languages
  • Fixed race condition in search initialization
Changelog

Sourced from mkdocs-material's changelog.

mkdocs-material-7.3.5 (2021-10-27)

  • Added support for setting table of contents title via mkdocs.yml
  • Fixed back-to-top button position for right-to-left languages

mkdocs-material-7.3.4+insiders-3.1.4 (2021-10-17)

  • Fixed #2974: Text cropped with other fonts than Roboto in social plugin
  • Fixed #3099: Encoding problems with non-latin character in social plugin
  • Fixed #3112: Japanese segmenter not executed as part of new tokenizer
  • Fixed tags (front matter) appearing in search with disabled tags plugin

mkdocs-material-7.3.4 (2021-10-17)

  • Bumped MkDocs version to 1.2.3 to mitigate CVE-2021-40978
  • Fixed spacing issues when using integrate table of contents with tabs
  • Fixed some spacings issues for right-to-left languages
  • Fixed race condition in search initialization

mkdocs-material-7.3.3+insiders-3.1.3 (2021-10-12)

  • Added warnings to search plugin for unsupported options and syntax
  • Fixed #3503: Search sometimes returns entire page
  • Fixed #3089: Single-line code annotations disappear when printing

mkdocs-material-7.3.3 (2021-10-11)

  • Rewrite of entire documentation
  • Adjusted height of new content tabs to match single line code blocks
  • Fixed new content tabs missing right padding in some browsers on overflow
  • Fixed new content tabs bleeding out of flex container on overflow
  • Fixed new content tabs overflow scrolling bugs on some browsers
  • Fixed new content tabs stealing keyboard access when active
  • Fixed some spacings issues for right-to-left languages

mkdocs-material-7.3.2+insiders-3.1.2 (2021-10-06)

  • Fixed incorrect path separators for social cards on Windows

mkdocs-material-7.3.2 (2021-10-06)

  • Deprecated prebuilding of search index
  • Improved graceful handling of broken search for file://
  • Added minimum Jinja version to list of requirements
  • Fixed #3071: Section index pages render empty directories
  • Fixed margin issues when using navigation tabs (7.3.1 regression)
  • Fixed search placeholder sometimes being shown too early

mkdocs-material-7.3.1 (2021-10-02)

... (truncated)

Commits
  • cda30e8 Prepare 7.3.5 release
  • 3daf8e2 Improved social cards documentation
  • 403580b Fixed back-to-top button position for right-to-left languages
  • cffb592 Updated custom translations example
  • 541c51e Documentation
  • 25c91b9 Formatting
  • 4bdfef4 Added support for setting table of contents title via mkdocs.yml
  • 8f382d9 Added documentation for permanent link title
  • 9d1f5c9 Switched to numeric values
  • db1739e Enabled feedback for testing
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=mkdocs-material&package-manager=pip&previous-version=7.3.3&new-version=7.3.5)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- poetry.lock | 16 ++++++++-------- pyproject.toml | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/poetry.lock b/poetry.lock index 0bb99d068ae..bfda332dd0a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -541,7 +541,7 @@ test = ["coverage", "flake8 (>=3.0)"] [[package]] name = "mkdocs" -version = "1.2.2" +version = "1.2.3" description = "Project documentation with Markdown." category = "dev" optional = false @@ -577,7 +577,7 @@ mkdocs = ">=0.17" [[package]] name = "mkdocs-material" -version = "7.3.3" +version = "7.3.5" description = "A Material Design theme for MkDocs" category = "dev" optional = false @@ -586,7 +586,7 @@ python-versions = "*" [package.dependencies] jinja2 = ">=2.11.1" markdown = ">=3.2" -mkdocs = ">=1.2.2" +mkdocs = ">=1.2.3" mkdocs-material-extensions = ">=1.0" pygments = ">=2.4" pymdown-extensions = ">=9.0" @@ -1055,7 +1055,7 @@ pydantic = ["pydantic", "email-validator"] [metadata] lock-version = "1.1" python-versions = "^3.6.1" -content-hash = "faa554f1cb4eafe6a4308fc71d3a64443d6cb65088c0937b4c90a4af10f31487" +content-hash = "6eb7e379d0b2b14d0a9f374b66c6b6d2f236f0d23cffc0b4375835ba853ac5ae" [metadata.files] appdirs = [ @@ -1333,16 +1333,16 @@ mike = [ {file = "mike-0.6.0.tar.gz", hash = "sha256:6d6239de2a60d733da2f34617e9b9a14c4b5437423b47e524f14dc96d6ce5f2f"}, ] mkdocs = [ - {file = "mkdocs-1.2.2-py3-none-any.whl", hash = "sha256:d019ff8e17ec746afeb54eb9eb4112b5e959597aebc971da46a5c9486137f0ff"}, - {file = "mkdocs-1.2.2.tar.gz", hash = "sha256:a334f5bd98ec960638511366eb8c5abc9c99b9083a0ed2401d8791b112d6b078"}, + {file = "mkdocs-1.2.3-py3-none-any.whl", hash = "sha256:a1fa8c2d0c1305d7fc2b9d9f607c71778572a8b110fb26642aa00296c9e6d072"}, + {file = "mkdocs-1.2.3.tar.gz", hash = "sha256:89f5a094764381cda656af4298727c9f53dc3e602983087e1fe96ea1df24f4c1"}, ] mkdocs-git-revision-date-plugin = [ {file = "mkdocs-git-revision-date-plugin-0.3.1.tar.gz", hash = "sha256:4abaef720763a64c952bed6829dcc180f67c97c60dd73914e90715e05d1cfb23"}, {file = "mkdocs_git_revision_date_plugin-0.3.1-py3-none-any.whl", hash = "sha256:8ae50b45eb75d07b150a69726041860801615aae5f4adbd6b1cf4d51abaa03d5"}, ] mkdocs-material = [ - {file = "mkdocs-material-7.3.3.tar.gz", hash = "sha256:3444b681f47e62c0ec7166bfb6f12360a26c751224cd6d3b3816f7310827073f"}, - {file = "mkdocs_material-7.3.3-py2.py3-none-any.whl", hash = "sha256:56bcc4e43356b97caa07706b0f446a3d9c39eb9aa1ad64131686d555270fc65e"}, + {file = "mkdocs-material-7.3.5.tar.gz", hash = "sha256:5edbf86b4249f413d54b8e2f1f2f8f1d2a9345f45e928303f4541e1d51f362c0"}, + {file = "mkdocs_material-7.3.5-py2.py3-none-any.whl", hash = "sha256:9fc09d2636d3249a7d75813c16360f3aa6987dff792c0e19f218fc80d48c2296"}, ] mkdocs-material-extensions = [ {file = "mkdocs-material-extensions-1.0.1.tar.gz", hash = "sha256:6947fb7f5e4291e3c61405bad3539d81e0b3cd62ae0d66ced018128af509c68f"}, diff --git a/pyproject.toml b/pyproject.toml index 007eac4242e..c177e4b5820 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -50,7 +50,7 @@ radon = "^5.1.0" xenon = "^0.8.0" flake8-eradicate = "^1.2.0" flake8-bugbear = "^21.9.2" -mkdocs-material = "^7.3.3" +mkdocs-material = "^7.3.5" mkdocs-git-revision-date-plugin = "^0.3.1" mike = "^0.6.0" mypy = "^0.910" From 8b01fc5f02390d4cab2cd64b72381e2d785aec4f Mon Sep 17 00:00:00 2001 From: Michael Brewer Date: Fri, 29 Oct 2021 02:58:57 -0700 Subject: [PATCH 13/14] feat(appsync): add Router to allow large resolver composition (#776) --- .../event_handler/appsync.py | 75 ++++++++++++------- .../functional/event_handler/test_appsync.py | 27 +++++++ 2 files changed, 75 insertions(+), 27 deletions(-) diff --git a/aws_lambda_powertools/event_handler/appsync.py b/aws_lambda_powertools/event_handler/appsync.py index 69b90c4cbb6..6a4bf989169 100644 --- a/aws_lambda_powertools/event_handler/appsync.py +++ b/aws_lambda_powertools/event_handler/appsync.py @@ -1,4 +1,5 @@ import logging +from abc import ABC from typing import Any, Callable, Optional, Type, TypeVar from aws_lambda_powertools.utilities.data_classes import AppSyncResolverEvent @@ -9,7 +10,33 @@ AppSyncResolverEventT = TypeVar("AppSyncResolverEventT", bound=AppSyncResolverEvent) -class AppSyncResolver: +class BaseRouter(ABC): + current_event: AppSyncResolverEventT # type: ignore[valid-type] + lambda_context: LambdaContext + + def __init__(self): + self._resolvers: dict = {} + + def resolver(self, type_name: str = "*", field_name: Optional[str] = None): + """Registers the resolver for field_name + + Parameters + ---------- + type_name : str + Type name + field_name : str + Field name + """ + + def register_resolver(func): + logger.debug(f"Adding resolver `{func.__name__}` for field `{type_name}.{field_name}`") + self._resolvers[f"{type_name}.{field_name}"] = {"func": func} + return func + + return register_resolver + + +class AppSyncResolver(BaseRouter): """ AppSync resolver decorator @@ -40,29 +67,8 @@ def common_field() -> str: return str(uuid.uuid4()) """ - current_event: AppSyncResolverEventT # type: ignore[valid-type] - lambda_context: LambdaContext - def __init__(self): - self._resolvers: dict = {} - - def resolver(self, type_name: str = "*", field_name: Optional[str] = None): - """Registers the resolver for field_name - - Parameters - ---------- - type_name : str - Type name - field_name : str - Field name - """ - - def register_resolver(func): - logger.debug(f"Adding resolver `{func.__name__}` for field `{type_name}.{field_name}`") - self._resolvers[f"{type_name}.{field_name}"] = {"func": func} - return func - - return register_resolver + super().__init__() def resolve( self, event: dict, context: LambdaContext, data_model: Type[AppSyncResolverEvent] = AppSyncResolverEvent @@ -136,10 +142,10 @@ def lambda_handler(event, context): ValueError If we could not find a field resolver """ - self.current_event = data_model(event) - self.lambda_context = context - resolver = self._get_resolver(self.current_event.type_name, self.current_event.field_name) - return resolver(**self.current_event.arguments) + BaseRouter.current_event = data_model(event) + BaseRouter.lambda_context = context + resolver = self._get_resolver(BaseRouter.current_event.type_name, BaseRouter.current_event.field_name) + return resolver(**BaseRouter.current_event.arguments) def _get_resolver(self, type_name: str, field_name: str) -> Callable: """Get resolver for field_name @@ -167,3 +173,18 @@ def __call__( ) -> Any: """Implicit lambda handler which internally calls `resolve`""" return self.resolve(event, context, data_model) + + def include_router(self, router: "Router") -> None: + """Adds all resolvers defined in a router + + Parameters + ---------- + router : Router + A router containing a dict of field resolvers + """ + self._resolvers.update(router._resolvers) + + +class Router(BaseRouter): + def __init__(self): + super().__init__() diff --git a/tests/functional/event_handler/test_appsync.py b/tests/functional/event_handler/test_appsync.py index 26a3ffdcb1f..79173e55825 100644 --- a/tests/functional/event_handler/test_appsync.py +++ b/tests/functional/event_handler/test_appsync.py @@ -4,6 +4,7 @@ import pytest from aws_lambda_powertools.event_handler import AppSyncResolver +from aws_lambda_powertools.event_handler.appsync import Router from aws_lambda_powertools.utilities.data_classes import AppSyncResolverEvent from aws_lambda_powertools.utilities.typing import LambdaContext from tests.functional.utils import load_event @@ -161,3 +162,29 @@ def create_something(id: str): # noqa AA03 VNE003 assert result == "my identifier" assert app.current_event.country_viewer == "US" + + +def test_resolver_include_resolver(): + # GIVEN + app = AppSyncResolver() + router = Router() + + @router.resolver(type_name="Query", field_name="listLocations") + def get_locations(name: str): + return "get_locations#" + name + + @app.resolver(field_name="listLocations2") + def get_locations2(name: str): + return "get_locations2#" + name + + app.include_router(router) + + # WHEN + mock_event1 = {"typeName": "Query", "fieldName": "listLocations", "arguments": {"name": "value"}} + mock_event2 = {"typeName": "Query", "fieldName": "listLocations2", "arguments": {"name": "value"}} + result1 = app.resolve(mock_event1, LambdaContext()) + result2 = app.resolve(mock_event2, LambdaContext()) + + # THEN + assert result1 == "get_locations#value" + assert result2 == "get_locations2#value" From 1bcd4ff7202ab31c33f4d5a6ec26d497ad5433a1 Mon Sep 17 00:00:00 2001 From: Michael Brewer Date: Fri, 29 Oct 2021 02:59:31 -0700 Subject: [PATCH 14/14] feat(data-classes): ActiveMQ and RabbitMQ support (#770) Co-authored-by: heitorlessa --- .../utilities/data_classes/active_mq_event.py | 125 ++++++++++++++++++ .../utilities/data_classes/rabbit_mq_event.py | 121 +++++++++++++++++ docs/utilities/data_classes.md | 54 ++++++++ tests/events/activeMQEvent.json | 45 +++++++ tests/events/rabbitMQEvent.json | 51 +++++++ .../functional/data_classes/test_amazon_mq.py | 69 ++++++++++ 6 files changed, 465 insertions(+) create mode 100644 aws_lambda_powertools/utilities/data_classes/active_mq_event.py create mode 100644 aws_lambda_powertools/utilities/data_classes/rabbit_mq_event.py create mode 100644 tests/events/activeMQEvent.json create mode 100644 tests/events/rabbitMQEvent.json create mode 100644 tests/functional/data_classes/test_amazon_mq.py diff --git a/aws_lambda_powertools/utilities/data_classes/active_mq_event.py b/aws_lambda_powertools/utilities/data_classes/active_mq_event.py new file mode 100644 index 00000000000..058a6a6ecf4 --- /dev/null +++ b/aws_lambda_powertools/utilities/data_classes/active_mq_event.py @@ -0,0 +1,125 @@ +import base64 +import json +from typing import Any, Iterator, Optional + +from aws_lambda_powertools.utilities.data_classes.common import DictWrapper + + +class ActiveMQMessage(DictWrapper): + @property + def message_id(self) -> str: + """Unique identifier for the message""" + return self["messageID"] + + @property + def message_type(self) -> str: + return self["messageType"] + + @property + def data(self) -> str: + return self["data"] + + @property + def decoded_data(self) -> str: + """Decodes the data as a str""" + return base64.b64decode(self.data.encode()).decode() + + @property + def json_data(self) -> Any: + """Parses the data as json""" + return json.loads(self.decoded_data) + + @property + def connection_id(self) -> str: + return self["connectionId"] + + @property + def redelivered(self) -> bool: + """true if the message is being resent to the consumer""" + return self["redelivered"] + + @property + def timestamp(self) -> int: + """Time in milliseconds.""" + return self["timestamp"] + + @property + def broker_in_time(self) -> int: + """Time stamp (in milliseconds) for when the message arrived at the broker.""" + return self["brokerInTime"] + + @property + def broker_out_time(self) -> int: + """Time stamp (in milliseconds) for when the message left the broker.""" + return self["brokerOutTime"] + + @property + def destination_physicalname(self) -> str: + return self["destination"]["physicalname"] + + @property + def delivery_mode(self) -> Optional[int]: + """persistent or non-persistent delivery""" + return self.get("deliveryMode") + + @property + def correlation_id(self) -> Optional[str]: + """User defined correlation id""" + return self.get("correlationID") + + @property + def reply_to(self) -> Optional[str]: + """User defined reply to""" + return self.get("replyTo") + + @property + def get_type(self) -> Optional[str]: + """User defined message type""" + return self.get("type") + + @property + def expiration(self) -> Optional[int]: + """Expiration attribute whose value is given in milliseconds""" + return self.get("expiration") + + @property + def priority(self) -> Optional[int]: + """ + JMS defines a ten-level priority value, with 0 as the lowest priority and 9 + as the highest. In addition, clients should consider priorities 0-4 as + gradations of normal priority and priorities 5-9 as gradations of expedited + priority. + + JMS does not require that a provider strictly implement priority ordering + of messages; however, it should do its best to deliver expedited messages + ahead of normal messages. + """ + return self.get("priority") + + +class ActiveMQEvent(DictWrapper): + """Represents an Active MQ event sent to Lambda + + Documentation: + -------------- + - https://docs.aws.amazon.com/lambda/latest/dg/with-mq.html + - https://aws.amazon.com/blogs/compute/using-amazon-mq-as-an-event-source-for-aws-lambda/ + """ + + @property + def event_source(self) -> str: + return self["eventSource"] + + @property + def event_source_arn(self) -> str: + """The Amazon Resource Name (ARN) of the event source""" + return self["eventSourceArn"] + + @property + def messages(self) -> Iterator[ActiveMQMessage]: + for record in self["messages"]: + yield ActiveMQMessage(record) + + @property + def message(self) -> ActiveMQMessage: + return next(self.messages) diff --git a/aws_lambda_powertools/utilities/data_classes/rabbit_mq_event.py b/aws_lambda_powertools/utilities/data_classes/rabbit_mq_event.py new file mode 100644 index 00000000000..7676e6ff9b5 --- /dev/null +++ b/aws_lambda_powertools/utilities/data_classes/rabbit_mq_event.py @@ -0,0 +1,121 @@ +import base64 +import json +from typing import Any, Dict, List + +from aws_lambda_powertools.utilities.data_classes.common import DictWrapper + + +class BasicProperties(DictWrapper): + @property + def content_type(self) -> str: + return self["contentType"] + + @property + def content_encoding(self) -> str: + return self["contentEncoding"] + + @property + def headers(self) -> Dict[str, Any]: + return self["headers"] + + @property + def delivery_mode(self) -> int: + return self["deliveryMode"] + + @property + def priority(self) -> int: + return self["priority"] + + @property + def correlation_id(self) -> str: + return self["correlationId"] + + @property + def reply_to(self) -> str: + return self["replyTo"] + + @property + def expiration(self) -> str: + return self["expiration"] + + @property + def message_id(self) -> str: + return self["messageId"] + + @property + def timestamp(self) -> str: + return self["timestamp"] + + @property + def get_type(self) -> str: + return self["type"] + + @property + def user_id(self) -> str: + return self["userId"] + + @property + def app_id(self) -> str: + return self["appId"] + + @property + def cluster_id(self) -> str: + return self["clusterId"] + + @property + def body_size(self) -> int: + return self["bodySize"] + + +class RabbitMessage(DictWrapper): + @property + def basic_properties(self) -> BasicProperties: + return BasicProperties(self["basicProperties"]) + + @property + def redelivered(self) -> bool: + return self["redelivered"] + + @property + def data(self) -> str: + return self["data"] + + @property + def decoded_data(self) -> str: + """Decodes the data as a str""" + return base64.b64decode(self.data.encode()).decode() + + @property + def json_data(self) -> Any: + """Parses the data as json""" + return json.loads(self.decoded_data) + + +class RabbitMQEvent(DictWrapper): + """Represents a Rabbit MQ event sent to Lambda + + Documentation: + -------------- + - https://docs.aws.amazon.com/lambda/latest/dg/with-mq.html + - https://aws.amazon.com/blogs/compute/using-amazon-mq-for-rabbitmq-as-an-event-source-for-lambda/ + """ + + def __init__(self, data: Dict[str, Any]): + super().__init__(data) + self._rmq_messages_by_queue = { + key: [RabbitMessage(message) for message in messages] + for key, messages in self["rmqMessagesByQueue"].items() + } + + @property + def event_source(self) -> str: + return self["eventSource"] + + @property + def event_source_arn(self) -> str: + """The Amazon Resource Name (ARN) of the event source""" + return self["eventSourceArn"] + + @property + def rmq_messages_by_queue(self) -> Dict[str, List[RabbitMessage]]: + return self._rmq_messages_by_queue diff --git a/docs/utilities/data_classes.md b/docs/utilities/data_classes.md index e05193c7702..cbe874d4b94 100644 --- a/docs/utilities/data_classes.md +++ b/docs/utilities/data_classes.md @@ -58,6 +58,7 @@ Same example as above, but using the `event_source` decorator Event Source | Data_class ------------------------------------------------- | --------------------------------------------------------------------------------- +[Active MQ](#active-mq) | `ActiveMQEvent` [API Gateway Authorizer](#api-gateway-authorizer) | `APIGatewayAuthorizerRequestEvent` [API Gateway Authorizer V2](#api-gateway-authorizer-v2) | `APIGatewayAuthorizerEventV2` [API Gateway Proxy](#api-gateway-proxy) | `APIGatewayProxyEvent` @@ -72,6 +73,7 @@ Event Source | Data_class [DynamoDB streams](#dynamodb-streams) | `DynamoDBStreamEvent`, `DynamoDBRecordEventName` [EventBridge](#eventbridge) | `EventBridgeEvent` [Kinesis Data Stream](#kinesis-streams) | `KinesisStreamEvent` +[Rabbit MQ](#rabbit-mq) | `RabbitMQEvent` [S3](#s3) | `S3Event` [S3 Object Lambda](#s3-object-lambda) | `S3ObjectLambdaEvent` [SES](#ses) | `SESEvent` @@ -82,6 +84,31 @@ Event Source | Data_class The examples provided below are far from exhaustive - the data classes themselves are designed to provide a form of documentation inherently (via autocompletion, types and docstrings). +### Active MQ + +It is used for [Active MQ payloads](https://docs.aws.amazon.com/lambda/latest/dg/with-mq.html){target="_blank"}, also see +the [AWS blog post](https://aws.amazon.com/blogs/compute/using-amazon-mq-as-an-event-source-for-aws-lambda/){target="_blank"} +for more details. + +=== "app.py" + + ```python hl_lines="4-5 9-10" + from typing import Dict + + from aws_lambda_powertools import Logger + from aws_lambda_powertools.utilities.data_classes import event_source + from aws_lambda_powertools.utilities.data_classes.active_mq_event import ActiveMQEvent + + logger = Logger() + + @event_source(data_class=ActiveMQEvent) + def lambda_handler(event: ActiveMQEvent, context): + for message in event.messages: + logger.debug(f"MessageID: {message.message_id}") + data: Dict = message.json_data + logger.debug("Process json in base64 encoded data str", data) + ``` + ### API Gateway Authorizer > New in 1.20.0 @@ -810,6 +837,33 @@ or plain text, depending on the original payload. do_something_with(data) ``` +### Rabbit MQ + +It is used for [Rabbit MQ payloads](https://docs.aws.amazon.com/lambda/latest/dg/with-mq.html){target="_blank"}, also see +the [blog post](https://aws.amazon.com/blogs/compute/using-amazon-mq-for-rabbitmq-as-an-event-source-for-lambda/){target="_blank"} +for more details. + +=== "app.py" + + ```python hl_lines="4-5 9-10" + from typing import Dict + + from aws_lambda_powertools import Logger + from aws_lambda_powertools.utilities.data_classes import event_source + from aws_lambda_powertools.utilities.data_classes.rabbit_mq_event import RabbitMQEvent + + logger = Logger() + + @event_source(data_class=RabbitMQEvent) + def lambda_handler(event: RabbitMQEvent, context): + for queue_name, messages in event.rmq_messages_by_queue.items(): + logger.debug(f"Messages for queue: {queue_name}") + for message in messages: + logger.debug(f"MessageID: {message.basic_properties.message_id}") + data: Dict = message.json_data + logger.debug("Process json in base64 encoded data str", data) + ``` + ### S3 === "app.py" diff --git a/tests/events/activeMQEvent.json b/tests/events/activeMQEvent.json new file mode 100644 index 00000000000..290ada184c9 --- /dev/null +++ b/tests/events/activeMQEvent.json @@ -0,0 +1,45 @@ +{ + "eventSource": "aws:amq", + "eventSourceArn": "arn:aws:mq:us-west-2:112556298976:broker:test:b-9bcfa592-423a-4942-879d-eb284b418fc8", + "messages": [ + { + "messageID": "ID:b-9bcfa592-423a-4942-879d-eb284b418fc8-1.mq.us-west-2.amazonaws.com-37557-1234520418293-4:1:1:1:1", + "messageType": "jms/text-message", + "data": "QUJDOkFBQUE=", + "connectionId": "myJMSCoID", + "redelivered": false, + "destination": { + "physicalname": "testQueue" + }, + "timestamp": 1598827811958, + "brokerInTime": 1598827811958, + "brokerOutTime": 1598827811959 + }, + { + "messageID": "ID:b-9bcfa592-423a-4942-879d-eb284b418fc8-1.mq.us-west-2.amazonaws.com-37557-1234520418293-4:1:1:1:1", + "messageType": "jms/text-message", + "data": "eyJ0aW1lb3V0IjowLCJkYXRhIjoiQ1pybWYwR3c4T3Y0YnFMUXhENEUifQ==", + "connectionId": "myJMSCoID2", + "redelivered": false, + "destination": { + "physicalname": "testQueue" + }, + "timestamp": 1598827811958, + "brokerInTime": 1598827811958, + "brokerOutTime": 1598827811959 + }, + { + "messageID": "ID:b-9bcfa592-423a-4942-879d-eb284b418fc8-1.mq.us-west-2.amazonaws.com-37557-1234520418293-4:1:1:1:1", + "messageType": "jms/bytes-message", + "data": "3DTOOW7crj51prgVLQaGQ82S48k=", + "connectionId": "myJMSCoID1", + "persistent": false, + "destination": { + "physicalname": "testQueue" + }, + "timestamp": 1598827811958, + "brokerInTime": 1598827811958, + "brokerOutTime": 1598827811959 + } + ] +} diff --git a/tests/events/rabbitMQEvent.json b/tests/events/rabbitMQEvent.json new file mode 100644 index 00000000000..e4259555a8b --- /dev/null +++ b/tests/events/rabbitMQEvent.json @@ -0,0 +1,51 @@ +{ + "eventSource": "aws:rmq", + "eventSourceArn": "arn:aws:mq:us-west-2:112556298976:broker:pizzaBroker:b-9bcfa592-423a-4942-879d-eb284b418fc8", + "rmqMessagesByQueue": { + "pizzaQueue::/": [ + { + "basicProperties": { + "contentType": "text/plain", + "contentEncoding": null, + "headers": { + "header1": { + "bytes": [ + 118, + 97, + 108, + 117, + 101, + 49 + ] + }, + "header2": { + "bytes": [ + 118, + 97, + 108, + 117, + 101, + 50 + ] + }, + "numberInHeader": 10 + }, + "deliveryMode": 1, + "priority": 34, + "correlationId": null, + "replyTo": null, + "expiration": "60000", + "messageId": null, + "timestamp": "Jan 1, 1970, 12:33:41 AM", + "type": null, + "userId": "AIDACKCEVSQ6C2EXAMPLE", + "appId": null, + "clusterId": null, + "bodySize": 80 + }, + "redelivered": false, + "data": "eyJ0aW1lb3V0IjowLCJkYXRhIjoiQ1pybWYwR3c4T3Y0YnFMUXhENEUifQ==" + } + ] + } +} diff --git a/tests/functional/data_classes/test_amazon_mq.py b/tests/functional/data_classes/test_amazon_mq.py new file mode 100644 index 00000000000..0f4f5079565 --- /dev/null +++ b/tests/functional/data_classes/test_amazon_mq.py @@ -0,0 +1,69 @@ +from typing import Dict + +from aws_lambda_powertools.utilities.data_classes.active_mq_event import ActiveMQEvent, ActiveMQMessage +from aws_lambda_powertools.utilities.data_classes.rabbit_mq_event import BasicProperties, RabbitMessage, RabbitMQEvent +from tests.functional.utils import load_event + + +def test_active_mq_event(): + event = ActiveMQEvent(load_event("activeMQEvent.json")) + + assert event.event_source == "aws:amq" + assert event.event_source_arn is not None + assert len(list(event.messages)) == 3 + + message = event.message + assert isinstance(message, ActiveMQMessage) + assert message.message_id is not None + assert message.message_type is not None + assert message.data is not None + assert message.decoded_data is not None + assert message.connection_id is not None + assert message.redelivered is False + assert message.timestamp is not None + assert message.broker_in_time is not None + assert message.broker_out_time is not None + assert message.destination_physicalname is not None + assert message.delivery_mode is None + assert message.correlation_id is None + assert message.reply_to is None + assert message.get_type is None + assert message.expiration is None + assert message.priority is None + + messages = list(event.messages) + message = messages[1] + assert message.json_data["timeout"] == 0 + + +def test_rabbit_mq_event(): + event = RabbitMQEvent(load_event("rabbitMQEvent.json")) + + assert event.event_source == "aws:rmq" + assert event.event_source_arn is not None + + message = event.rmq_messages_by_queue["pizzaQueue::/"][0] + assert message.redelivered is False + assert message.data is not None + assert message.decoded_data is not None + assert message.json_data["timeout"] == 0 + + assert isinstance(message, RabbitMessage) + properties = message.basic_properties + assert isinstance(properties, BasicProperties) + assert properties.content_type == "text/plain" + assert properties.content_encoding is None + assert isinstance(properties.headers, Dict) + assert properties.headers["header1"] is not None + assert properties.delivery_mode == 1 + assert properties.priority == 34 + assert properties.correlation_id is None + assert properties.reply_to is None + assert properties.expiration == "60000" + assert properties.message_id is None + assert properties.timestamp is not None + assert properties.get_type is None + assert properties.user_id is not None + assert properties.app_id is None + assert properties.cluster_id is None + assert properties.body_size == 80