From d34b9dabad675f2434ef3107e48b51ab2676b29f Mon Sep 17 00:00:00 2001 From: Giovanni Grano Date: Mon, 11 Aug 2025 17:08:58 +0200 Subject: [PATCH 1/3] Added SDK to the test dependencies --- .pre-commit-config.yaml | 4 +-- pyproject.toml | 1 + requirements-base-runtime.txt | 8 ++--- requirements-basic.txt | 6 ++-- requirements-dev.txt | 41 ++++++++++++++--------- requirements-runtime.txt | 14 ++++---- requirements-test.txt | 33 +++++++++++------- requirements-typehint.txt | 63 ++++++++++++++++++++--------------- 8 files changed, 99 insertions(+), 71 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 801efd84b6ad8..5ee7cc392573d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -3,7 +3,7 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit # Ruff version. - rev: v0.12.7 + rev: v0.12.8 hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] @@ -18,7 +18,7 @@ repos: additional_dependencies: ['botocore-stubs', 'rolo'] - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v5.0.0 + rev: v6.0.0 hooks: - id: end-of-file-fixer - id: trailing-whitespace diff --git a/pyproject.toml b/pyproject.toml index 26ec717a45c1e..dec408f1368ed 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -116,6 +116,7 @@ test = [ "aws-cdk-lib>=2.88.0", "websocket-client>=1.7.0", "localstack-snapshot>=0.1.1", + "localstack-sdk-python" ] # for developing localstack diff --git a/requirements-base-runtime.txt b/requirements-base-runtime.txt index 71b6aac02103e..047f6a4291482 100644 --- a/requirements-base-runtime.txt +++ b/requirements-base-runtime.txt @@ -28,13 +28,13 @@ certifi==2025.8.3 # via requests cffi==1.17.1 # via cryptography -charset-normalizer==3.4.2 +charset-normalizer==3.4.3 # via requests click==8.2.1 # via localstack-core (pyproject.toml) constantly==23.10.4 # via localstack-twisted -cryptography==45.0.5 +cryptography==45.0.6 # via # localstack-core (pyproject.toml) # pyopenssl @@ -98,7 +98,7 @@ lazy-object-proxy==1.11.0 # via openapi-spec-validator localstack-twisted==24.3.0 # via localstack-core (pyproject.toml) -markdown-it-py==3.0.0 +markdown-it-py==4.0.0 # via rich markupsafe==3.0.2 # via werkzeug @@ -168,7 +168,7 @@ rich==14.1.0 # via localstack-core (pyproject.toml) rolo==0.7.6 # via localstack-core (pyproject.toml) -rpds-py==0.26.0 +rpds-py==0.27.0 # via # jsonschema # referencing diff --git a/requirements-basic.txt b/requirements-basic.txt index 38325497d8329..6b76470fab394 100644 --- a/requirements-basic.txt +++ b/requirements-basic.txt @@ -12,11 +12,11 @@ certifi==2025.8.3 # via requests cffi==1.17.1 # via cryptography -charset-normalizer==3.4.2 +charset-normalizer==3.4.3 # via requests click==8.2.1 # via localstack-core (pyproject.toml) -cryptography==45.0.5 +cryptography==45.0.6 # via localstack-core (pyproject.toml) dill==0.3.6 # via localstack-core (pyproject.toml) @@ -28,7 +28,7 @@ idna==3.10 # via requests jsonpickle==4.1.1 # via localstack-core (pyproject.toml) -markdown-it-py==3.0.0 +markdown-it-py==4.0.0 # via rich mdurl==0.1.2 # via markdown-it-py diff --git a/requirements-dev.txt b/requirements-dev.txt index d5983d91b1135..f0b0fed153432 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -29,9 +29,9 @@ aws-cdk-asset-awscli-v1==2.2.242 # via aws-cdk-lib aws-cdk-asset-node-proxy-agent-v6==2.1.0 # via aws-cdk-lib -aws-cdk-cloud-assembly-schema==45.2.0 +aws-cdk-cloud-assembly-schema==48.3.0 # via aws-cdk-lib -aws-cdk-lib==2.208.0 +aws-cdk-lib==2.210.0 # via localstack-core aws-sam-translator==1.99.0 # via @@ -80,9 +80,9 @@ cffi==1.17.1 # via cryptography cfgv==3.4.0 # via pre-commit -cfn-lint==1.38.1 +cfn-lint==1.38.2 # via moto-ext -charset-normalizer==3.4.2 +charset-normalizer==3.4.3 # via requests click==8.2.1 # via @@ -94,7 +94,7 @@ constantly==23.10.4 # via localstack-twisted constructs==10.4.2 # via aws-cdk-lib -coverage==7.10.2 +coverage==7.10.3 # via # coveralls # localstack-core @@ -102,7 +102,7 @@ coveralls==4.0.1 # via localstack-core (pyproject.toml) crontab==1.0.5 # via localstack-core -cryptography==45.0.5 +cryptography==45.0.6 # via # joserfc # localstack-core @@ -113,7 +113,7 @@ cython==3.1.2 # via localstack-core (pyproject.toml) decorator==5.2.1 # via jsonpath-rw -deepdiff==8.5.0 +deepdiff==8.6.0 # via # localstack-core # localstack-snapshot @@ -168,7 +168,7 @@ hyperframe==6.1.0 # via h2 hyperlink==21.0.0 # via localstack-twisted -identify==2.6.12 +identify==2.6.13 # via pre-commit idna==3.10 # via @@ -240,11 +240,15 @@ kclpy-ext==3.0.5 # via localstack-core lazy-object-proxy==1.11.0 # via openapi-spec-validator +localstack-sdk-generated==4.7.0 + # via localstack-sdk-python +localstack-sdk-python==4.7.0 + # via localstack-core localstack-snapshot==0.3.0 # via localstack-core localstack-twisted==24.3.0 # via localstack-core -markdown-it-py==3.0.0 +markdown-it-py==4.0.0 # via rich markupsafe==3.0.2 # via @@ -317,7 +321,7 @@ ply==3.11 # jsonpath-ng # jsonpath-rw # pandoc -pre-commit==4.2.0 +pre-commit==4.3.0 # via localstack-core (pyproject.toml) priority==1.3.0 # via @@ -342,14 +346,16 @@ pyasn1==0.6.1 pycparser==2.22 # via cffi pydantic==2.11.7 - # via aws-sam-translator + # via + # aws-sam-translator + # localstack-sdk-generated pydantic-core==2.33.2 # via pydantic pygments==2.19.2 # via # pytest # rich -pymongo==4.13.2 +pymongo==4.14.0 # via localstack-core pyopenssl==25.1.0 # via @@ -379,6 +385,7 @@ python-dateutil==2.9.0.post0 # via # botocore # jsii + # localstack-sdk-generated # moto-ext # opensearch-py python-dotenv==1.1.1 @@ -419,7 +426,7 @@ requests==2.32.4 # rolo requests-aws4auth==1.3.1 # via localstack-core -responses==0.25.7 +responses==0.25.8 # via moto-ext rfc3339-validator==0.1.4 # via openapi-schema-validator @@ -429,7 +436,7 @@ rich==14.1.0 # localstack-core (pyproject.toml) rolo==0.7.6 # via localstack-core -rpds-py==0.26.0 +rpds-py==0.27.0 # via # jsonschema # referencing @@ -437,7 +444,7 @@ rsa==4.7.2 # via awscli rstr==3.2.2 # via localstack-core (pyproject.toml) -ruff==0.12.7 +ruff==0.12.8 # via localstack-core (pyproject.toml) s3transfer==0.13.1 # via @@ -476,6 +483,7 @@ typing-extensions==4.14.1 # cattrs # cfn-lint # jsii + # localstack-sdk-generated # localstack-twisted # mypy # pydantic @@ -491,10 +499,11 @@ urllib3==2.5.0 # botocore # docker # localstack-core + # localstack-sdk-generated # opensearch-py # requests # responses -virtualenv==20.33.0 +virtualenv==20.33.1 # via pre-commit websocket-client==1.8.0 # via localstack-core diff --git a/requirements-runtime.txt b/requirements-runtime.txt index f20f18d53e970..81448cefd6b89 100644 --- a/requirements-runtime.txt +++ b/requirements-runtime.txt @@ -62,9 +62,9 @@ certifi==2025.8.3 # requests cffi==1.17.1 # via cryptography -cfn-lint==1.38.1 +cfn-lint==1.38.2 # via moto-ext -charset-normalizer==3.4.2 +charset-normalizer==3.4.3 # via requests click==8.2.1 # via @@ -76,7 +76,7 @@ constantly==23.10.4 # via localstack-twisted crontab==1.0.5 # via localstack-core (pyproject.toml) -cryptography==45.0.5 +cryptography==45.0.6 # via # joserfc # localstack-core @@ -182,7 +182,7 @@ lazy-object-proxy==1.11.0 # via openapi-spec-validator localstack-twisted==24.3.0 # via localstack-core -markdown-it-py==3.0.0 +markdown-it-py==4.0.0 # via rich markupsafe==3.0.2 # via @@ -249,7 +249,7 @@ pydantic-core==2.33.2 # via pydantic pygments==2.19.2 # via rich -pymongo==4.13.2 +pymongo==4.14.0 # via localstack-core (pyproject.toml) pyopenssl==25.1.0 # via @@ -300,7 +300,7 @@ requests==2.32.4 # rolo requests-aws4auth==1.3.1 # via localstack-core -responses==0.25.7 +responses==0.25.8 # via moto-ext rfc3339-validator==0.1.4 # via openapi-schema-validator @@ -310,7 +310,7 @@ rich==14.1.0 # localstack-core (pyproject.toml) rolo==0.7.6 # via localstack-core -rpds-py==0.26.0 +rpds-py==0.27.0 # via # jsonschema # referencing diff --git a/requirements-test.txt b/requirements-test.txt index 5366d4ec8d41e..ca986c4b4da2b 100644 --- a/requirements-test.txt +++ b/requirements-test.txt @@ -29,9 +29,9 @@ aws-cdk-asset-awscli-v1==2.2.242 # via aws-cdk-lib aws-cdk-asset-node-proxy-agent-v6==2.1.0 # via aws-cdk-lib -aws-cdk-cloud-assembly-schema==45.2.0 +aws-cdk-cloud-assembly-schema==48.3.0 # via aws-cdk-lib -aws-cdk-lib==2.208.0 +aws-cdk-lib==2.210.0 # via localstack-core (pyproject.toml) aws-sam-translator==1.99.0 # via @@ -78,9 +78,9 @@ certifi==2025.8.3 # requests cffi==1.17.1 # via cryptography -cfn-lint==1.38.1 +cfn-lint==1.38.2 # via moto-ext -charset-normalizer==3.4.2 +charset-normalizer==3.4.3 # via requests click==8.2.1 # via @@ -92,11 +92,11 @@ constantly==23.10.4 # via localstack-twisted constructs==10.4.2 # via aws-cdk-lib -coverage==7.10.2 +coverage==7.10.3 # via localstack-core (pyproject.toml) crontab==1.0.5 # via localstack-core -cryptography==45.0.5 +cryptography==45.0.6 # via # joserfc # localstack-core @@ -105,7 +105,7 @@ cryptography==45.0.5 # pyopenssl decorator==5.2.1 # via jsonpath-rw -deepdiff==8.5.0 +deepdiff==8.6.0 # via # localstack-core (pyproject.toml) # localstack-snapshot @@ -224,11 +224,15 @@ kclpy-ext==3.0.5 # via localstack-core lazy-object-proxy==1.11.0 # via openapi-spec-validator +localstack-sdk-generated==4.7.0 + # via localstack-sdk-python +localstack-sdk-python==4.7.0 + # via localstack-core (pyproject.toml) localstack-snapshot==0.3.0 # via localstack-core (pyproject.toml) localstack-twisted==24.3.0 # via localstack-core -markdown-it-py==3.0.0 +markdown-it-py==4.0.0 # via rich markupsafe==3.0.2 # via @@ -306,14 +310,16 @@ pyasn1==0.6.1 pycparser==2.22 # via cffi pydantic==2.11.7 - # via aws-sam-translator + # via + # aws-sam-translator + # localstack-sdk-generated pydantic-core==2.33.2 # via pydantic pygments==2.19.2 # via # pytest # rich -pymongo==4.13.2 +pymongo==4.14.0 # via localstack-core pyopenssl==25.1.0 # via @@ -341,6 +347,7 @@ python-dateutil==2.9.0.post0 # via # botocore # jsii + # localstack-sdk-generated # moto-ext # opensearch-py python-dotenv==1.1.1 @@ -379,7 +386,7 @@ requests==2.32.4 # rolo requests-aws4auth==1.3.1 # via localstack-core -responses==0.25.7 +responses==0.25.8 # via moto-ext rfc3339-validator==0.1.4 # via openapi-schema-validator @@ -389,7 +396,7 @@ rich==14.1.0 # localstack-core (pyproject.toml) rolo==0.7.6 # via localstack-core -rpds-py==0.26.0 +rpds-py==0.27.0 # via # jsonschema # referencing @@ -432,6 +439,7 @@ typing-extensions==4.14.1 # cattrs # cfn-lint # jsii + # localstack-sdk-generated # localstack-twisted # pydantic # pydantic-core @@ -446,6 +454,7 @@ urllib3==2.5.0 # botocore # docker # localstack-core + # localstack-sdk-generated # opensearch-py # requests # responses diff --git a/requirements-typehint.txt b/requirements-typehint.txt index ddf1d507af29a..f2ef4d032947e 100644 --- a/requirements-typehint.txt +++ b/requirements-typehint.txt @@ -29,9 +29,9 @@ aws-cdk-asset-awscli-v1==2.2.242 # via aws-cdk-lib aws-cdk-asset-node-proxy-agent-v6==2.1.0 # via aws-cdk-lib -aws-cdk-cloud-assembly-schema==45.2.0 +aws-cdk-cloud-assembly-schema==48.3.0 # via aws-cdk-lib -aws-cdk-lib==2.208.0 +aws-cdk-lib==2.210.0 # via localstack-core aws-sam-translator==1.99.0 # via @@ -49,7 +49,7 @@ boto3==1.40.1 # kclpy-ext # localstack-core # moto-ext -boto3-stubs==1.40.2 +boto3-stubs==1.40.6 # via localstack-core (pyproject.toml) botocore==1.40.1 # via @@ -84,9 +84,9 @@ cffi==1.17.1 # via cryptography cfgv==3.4.0 # via pre-commit -cfn-lint==1.38.1 +cfn-lint==1.38.2 # via moto-ext -charset-normalizer==3.4.2 +charset-normalizer==3.4.3 # via requests click==8.2.1 # via @@ -98,7 +98,7 @@ constantly==23.10.4 # via localstack-twisted constructs==10.4.2 # via aws-cdk-lib -coverage==7.10.2 +coverage==7.10.3 # via # coveralls # localstack-core @@ -106,7 +106,7 @@ coveralls==4.0.1 # via localstack-core crontab==1.0.5 # via localstack-core -cryptography==45.0.5 +cryptography==45.0.6 # via # joserfc # localstack-core @@ -117,7 +117,7 @@ cython==3.1.2 # via localstack-core decorator==5.2.1 # via jsonpath-rw -deepdiff==8.5.0 +deepdiff==8.6.0 # via # localstack-core # localstack-snapshot @@ -172,7 +172,7 @@ hyperframe==6.1.0 # via h2 hyperlink==21.0.0 # via localstack-twisted -identify==2.6.12 +identify==2.6.13 # via pre-commit idna==3.10 # via @@ -244,11 +244,15 @@ kclpy-ext==3.0.5 # via localstack-core lazy-object-proxy==1.11.0 # via openapi-spec-validator +localstack-sdk-generated==4.7.0 + # via localstack-sdk-python +localstack-sdk-python==4.7.0 + # via localstack-core localstack-snapshot==0.3.0 # via localstack-core localstack-twisted==24.3.0 # via localstack-core -markdown-it-py==3.0.0 +markdown-it-py==4.0.0 # via rich markupsafe==3.0.2 # via @@ -290,7 +294,7 @@ mypy-boto3-autoscaling==1.40.0 # via boto3-stubs mypy-boto3-backup==1.40.0 # via boto3-stubs -mypy-boto3-batch==1.40.0 +mypy-boto3-batch==1.40.5 # via boto3-stubs mypy-boto3-ce==1.40.0 # via boto3-stubs @@ -298,13 +302,13 @@ mypy-boto3-cloudcontrol==1.40.0 # via boto3-stubs mypy-boto3-cloudformation==1.40.0 # via boto3-stubs -mypy-boto3-cloudfront==1.40.0 +mypy-boto3-cloudfront==1.40.5 # via boto3-stubs mypy-boto3-cloudtrail==1.40.0 # via boto3-stubs mypy-boto3-cloudwatch==1.40.0 # via boto3-stubs -mypy-boto3-codebuild==1.40.0 +mypy-boto3-codebuild==1.40.5 # via boto3-stubs mypy-boto3-codecommit==1.40.0 # via boto3-stubs @@ -328,7 +332,7 @@ mypy-boto3-dynamodb==1.40.0 # via boto3-stubs mypy-boto3-dynamodbstreams==1.40.0 # via boto3-stubs -mypy-boto3-ec2==1.40.0 +mypy-boto3-ec2==1.40.4 # via boto3-stubs mypy-boto3-ecr==1.40.0 # via boto3-stubs @@ -336,7 +340,7 @@ mypy-boto3-ecs==1.40.0 # via boto3-stubs mypy-boto3-efs==1.40.0 # via boto3-stubs -mypy-boto3-eks==1.40.0 +mypy-boto3-eks==1.40.3 # via boto3-stubs mypy-boto3-elasticache==1.40.0 # via boto3-stubs @@ -358,7 +362,7 @@ mypy-boto3-fis==1.40.0 # via boto3-stubs mypy-boto3-glacier==1.40.0 # via boto3-stubs -mypy-boto3-glue==1.40.0 +mypy-boto3-glue==1.40.5 # via boto3-stubs mypy-boto3-iam==1.40.0 # via boto3-stubs @@ -366,7 +370,7 @@ mypy-boto3-identitystore==1.40.0 # via boto3-stubs mypy-boto3-iot==1.40.0 # via boto3-stubs -mypy-boto3-iot-data==1.40.0 +mypy-boto3-iot-data==1.40.6 # via boto3-stubs mypy-boto3-iotanalytics==1.40.0 # via boto3-stubs @@ -414,7 +418,7 @@ mypy-boto3-qldb==1.40.0 # via boto3-stubs mypy-boto3-qldb-session==1.40.0 # via boto3-stubs -mypy-boto3-rds==1.40.0 +mypy-boto3-rds==1.40.3 # via boto3-stubs mypy-boto3-rds-data==1.40.0 # via boto3-stubs @@ -434,7 +438,7 @@ mypy-boto3-s3==1.40.0 # via boto3-stubs mypy-boto3-s3control==1.40.0 # via boto3-stubs -mypy-boto3-sagemaker==1.40.2 +mypy-boto3-sagemaker==1.40.6 # via boto3-stubs mypy-boto3-sagemaker-runtime==1.40.0 # via boto3-stubs @@ -464,7 +468,7 @@ mypy-boto3-timestream-query==1.40.0 # via boto3-stubs mypy-boto3-timestream-write==1.40.0 # via boto3-stubs -mypy-boto3-transcribe==1.40.0 +mypy-boto3-transcribe==1.40.6 # via boto3-stubs mypy-boto3-verifiedpermissions==1.40.0 # via boto3-stubs @@ -527,7 +531,7 @@ ply==3.11 # jsonpath-ng # jsonpath-rw # pandoc -pre-commit==4.2.0 +pre-commit==4.3.0 # via localstack-core priority==1.3.0 # via @@ -552,14 +556,16 @@ pyasn1==0.6.1 pycparser==2.22 # via cffi pydantic==2.11.7 - # via aws-sam-translator + # via + # aws-sam-translator + # localstack-sdk-generated pydantic-core==2.33.2 # via pydantic pygments==2.19.2 # via # pytest # rich -pymongo==4.13.2 +pymongo==4.14.0 # via localstack-core pyopenssl==25.1.0 # via @@ -589,6 +595,7 @@ python-dateutil==2.9.0.post0 # via # botocore # jsii + # localstack-sdk-generated # moto-ext # opensearch-py python-dotenv==1.1.1 @@ -629,7 +636,7 @@ requests==2.32.4 # rolo requests-aws4auth==1.3.1 # via localstack-core -responses==0.25.7 +responses==0.25.8 # via moto-ext rfc3339-validator==0.1.4 # via openapi-schema-validator @@ -639,7 +646,7 @@ rich==14.1.0 # localstack-core (pyproject.toml) rolo==0.7.6 # via localstack-core -rpds-py==0.26.0 +rpds-py==0.27.0 # via # jsonschema # referencing @@ -647,7 +654,7 @@ rsa==4.7.2 # via awscli rstr==3.2.2 # via localstack-core -ruff==0.12.7 +ruff==0.12.8 # via localstack-core s3transfer==0.13.1 # via @@ -691,6 +698,7 @@ typing-extensions==4.14.1 # cattrs # cfn-lint # jsii + # localstack-sdk-generated # localstack-twisted # mypy # mypy-boto3-acm @@ -809,10 +817,11 @@ urllib3==2.5.0 # botocore # docker # localstack-core + # localstack-sdk-generated # opensearch-py # requests # responses -virtualenv==20.33.0 +virtualenv==20.33.1 # via pre-commit websocket-client==1.8.0 # via localstack-core From 94207254de774164133fb6efea7e858a64458717 Mon Sep 17 00:00:00 2001 From: Giovanni Grano Date: Mon, 11 Aug 2025 17:09:14 +0200 Subject: [PATCH 2/3] add sdk fixture --- .../localstack/testing/pytest/fixtures.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/localstack-core/localstack/testing/pytest/fixtures.py b/localstack-core/localstack/testing/pytest/fixtures.py index c75f8a1293998..ce737cc826ab1 100644 --- a/localstack-core/localstack/testing/pytest/fixtures.py +++ b/localstack-core/localstack/testing/pytest/fixtures.py @@ -2753,3 +2753,17 @@ def _delete_log_group(): def patch_default_encoder(request, monkeypatch): backend = request.param monkeypatch.setattr(config, "STATE_SERIALIZATION_BACKEND", backend) + + +@pytest.fixture(scope="session") +def localstack_sdk_aws_client(): + """ + Returns a client that is used to interact with the LocalStack's internal endpoints. + """ + from localstack.sdk.aws.client import AWSClient + + def _wrapper(host: str | None = None, **kwargs) -> AWSClient: + host = host or config.internal_service_url() + return AWSClient(host=host, **kwargs) + + return _wrapper From 30cee153c5ee9aa14c96e28c3b8eea34cf32bda4 Mon Sep 17 00:00:00 2001 From: Giovanni Grano Date: Mon, 11 Aug 2025 17:09:26 +0200 Subject: [PATCH 3/3] use sdk in the test --- tests/aws/services/ses/test_ses.py | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/tests/aws/services/ses/test_ses.py b/tests/aws/services/ses/test_ses.py index 6220480f77715..1c1c2a7607b63 100644 --- a/tests/aws/services/ses/test_ses.py +++ b/tests/aws/services/ses/test_ses.py @@ -8,6 +8,7 @@ from botocore.exceptions import ClientError import localstack.config as config +from localstack.sdk.models import SesSentEmail from localstack.services.ses.provider import EMAILS, EMAILS_ENDPOINT from localstack.testing.aws.util import is_aws_cloud from localstack.testing.pytest import markers @@ -928,18 +929,18 @@ def test_ses_sns_topic_integration_send_email_ses_destination( ses_configuration_set_sns_event_destination, setup_email_addresses, aws_client, + localstack_sdk_aws_client, ): """ Validates that configure Event Destinations and sending an email does not trigger an infinite loop of sending SNS notifications that sends an email that would trigger SNS. """ + sdk_client = localstack_sdk_aws_client() sender_email_address, recipient_email_address = setup_email_addresses() config_set_name = f"config-set-{short_uid()}" - emails_url = config.internal_service_url() + EMAILS_ENDPOINT - response = requests.delete(emails_url) - assert response.status_code == 204 + sdk_client.discard_ses_messages() # create subscription to get notified about SES events topic_arn = sns_topic["Attributes"]["TopicArn"] @@ -973,29 +974,25 @@ def test_ses_sns_topic_integration_send_email_ses_destination( ], ) - def _get_emails(): - _resp = requests.get(emails_url) - return _resp.json()["messages"] - - poll_condition(lambda: len(_get_emails()) >= 4, timeout=3) - requests.delete(emails_url, params={"id": send_email["MessageId"]}) + poll_condition(lambda: len(sdk_client.get_ses_messages()) >= 4, timeout=3) + sdk_client.discard_ses_messages(id_filter=send_email["MessageId"]) - emails = _get_emails() + emails: list[SesSentEmail] = sdk_client.get_ses_messages() # we assert that we only received 3 emails assert len(emails) == 3 - emails = sorted(emails, key=lambda x: x["Body"]["text_part"]) + emails = sorted(emails, key=lambda x: x.body.text_part) # the first email is the validation of SNS confirming the SES subscription ses_delivery_notification = emails[1] ses_send_notification = emails[2] - assert ses_delivery_notification["Subject"] == "SNS-Subscriber-Endpoint" - delivery_payload = json.loads(ses_delivery_notification["Body"]["text_part"]) + assert ses_delivery_notification.subject == "SNS-Subscriber-Endpoint" + delivery_payload = json.loads(ses_delivery_notification.body.text_part) assert delivery_payload["eventType"] == "Delivery" assert delivery_payload["mail"]["source"] == sender_email_address - assert ses_send_notification["Subject"] == "SNS-Subscriber-Endpoint" - send_payload = json.loads(ses_send_notification["Body"]["text_part"]) + assert ses_send_notification.subject == "SNS-Subscriber-Endpoint" + send_payload = json.loads(ses_send_notification.body.text_part) assert send_payload["eventType"] == "Send" assert send_payload["mail"]["source"] == sender_email_address