diff --git a/.github/actions/download-artifact/action.yml b/.github/actions/download-artifact/action.yml
index ef938ddb684..1f1347e4220 100644
--- a/.github/actions/download-artifact/action.yml
+++ b/.github/actions/download-artifact/action.yml
@@ -38,7 +38,7 @@ runs:
using: composite
steps:
- name: Download artifacts
- uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2
+ uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7
with:
name: ${{ inputs.name }}
path: ${{ inputs.path }}
diff --git a/.github/actions/seal-restore/action.yml b/.github/actions/seal-restore/action.yml
index beadad90cbc..1107414b640 100644
--- a/.github/actions/seal-restore/action.yml
+++ b/.github/actions/seal-restore/action.yml
@@ -43,7 +43,7 @@ runs:
shell: bash
- name: Download artifacts
- uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2
+ uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7
with:
name: ${{ inputs.artifact_name }}
path: .
diff --git a/.github/actions/seal/action.yml b/.github/actions/seal/action.yml
index 3438056c872..c3e75a13e92 100644
--- a/.github/actions/seal/action.yml
+++ b/.github/actions/seal/action.yml
@@ -79,7 +79,7 @@ runs:
shell: bash
- name: Upload artifacts
- uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
+ uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
with:
if-no-files-found: error
name: ${{ steps.export_artifact_name.outputs.artifact_name }}
diff --git a/.github/actions/upload-artifact/action.yml b/.github/actions/upload-artifact/action.yml
index ffa18cc0723..f88ea2475b9 100644
--- a/.github/actions/upload-artifact/action.yml
+++ b/.github/actions/upload-artifact/action.yml
@@ -68,7 +68,7 @@ runs:
shell: bash
- name: Upload artifacts
- uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
+ uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
with:
if-no-files-found: ${{ inputs.if-no-files-found }}
name: ${{ inputs.name }}
diff --git a/.github/actions/upload-release-provenance/action.yml b/.github/actions/upload-release-provenance/action.yml
index e4c1e52c0d2..d0829efd4f4 100644
--- a/.github/actions/upload-release-provenance/action.yml
+++ b/.github/actions/upload-release-provenance/action.yml
@@ -42,7 +42,7 @@ runs:
- id: download-provenance
name: Download newly generated provenance
- uses: actions/download-artifact@9782bd6a9848b53b110e712e20e42d89988822b7 # v3.0.1
+ uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7
with:
name: ${{ inputs.provenance_name }}
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
index 9e7272b032e..2d51f3032f1 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -28,7 +28,7 @@ jobs:
steps:
- name: Checkout repository
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+ uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml
index 511af32d4cd..62daccd7f96 100644
--- a/.github/workflows/dependency-review.yml
+++ b/.github/workflows/dependency-review.yml
@@ -17,6 +17,6 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: 'Checkout Repository'
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+ uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
- name: 'Dependency Review'
- uses: actions/dependency-review-action@5bbc3ba658137598168acb2ab73b21c432dd411b # v4.2.5
+ uses: actions/dependency-review-action@0c155c5e8556a497adf53f2c18edabf945ed8e70 # v4.3.2
diff --git a/.github/workflows/label_pr_on_title.yml b/.github/workflows/label_pr_on_title.yml
index c5c57e6bee2..78432a4a53a 100644
--- a/.github/workflows/label_pr_on_title.yml
+++ b/.github/workflows/label_pr_on_title.yml
@@ -50,7 +50,7 @@ jobs:
pull-requests: write # label respective PR
steps:
- name: Checkout repository
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+ uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
- name: "Label PR based on title"
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
env:
diff --git a/.github/workflows/on_label_added.yml b/.github/workflows/on_label_added.yml
index c8d7007b1d4..d5ead643063 100644
--- a/.github/workflows/on_label_added.yml
+++ b/.github/workflows/on_label_added.yml
@@ -47,7 +47,7 @@ jobs:
permissions:
pull-requests: write # comment on PR
steps:
- - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+ - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
# Maintenance: Persist state per PR as an artifact to avoid spam on label add
- name: "Suggest split large Pull Request"
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
diff --git a/.github/workflows/on_merged_pr.yml b/.github/workflows/on_merged_pr.yml
index 9745f4ee0f3..b1d389f0eb8 100644
--- a/.github/workflows/on_merged_pr.yml
+++ b/.github/workflows/on_merged_pr.yml
@@ -49,7 +49,7 @@ jobs:
issues: write # label issue with pending-release
if: needs.get_pr_details.outputs.prIsMerged == 'true'
steps:
- - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+ - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
- name: "Label PR related issue for release"
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
env:
diff --git a/.github/workflows/on_opened_pr.yml b/.github/workflows/on_opened_pr.yml
index 065d9a6baed..c7f1965bd45 100644
--- a/.github/workflows/on_opened_pr.yml
+++ b/.github/workflows/on_opened_pr.yml
@@ -47,7 +47,7 @@ jobs:
needs: get_pr_details
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+ - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
- name: "Ensure related issue is present"
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
env:
@@ -66,7 +66,7 @@ jobs:
permissions:
pull-requests: write # label and comment on PR if missing acknowledge section (requirement)
steps:
- - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+ - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
- name: "Ensure acknowledgement section is present"
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
env:
diff --git a/.github/workflows/on_schedule_monthly_roadmap_reminder.yml b/.github/workflows/on_schedule_monthly_roadmap_reminder.yml
index 6a47fedd34d..a274e2dea08 100644
--- a/.github/workflows/on_schedule_monthly_roadmap_reminder.yml
+++ b/.github/workflows/on_schedule_monthly_roadmap_reminder.yml
@@ -2,17 +2,21 @@ name: Monthly roadmap reminder
on:
workflow_dispatch: {}
-# schedule:
-# - cron: '0 0 1 * *'
+ schedule:
+ - cron: '0 0 1 * *' # runs first day of the month
permissions:
contents: read
- pull-requests: read
- issues: read
jobs:
call-workflow-passing-data:
- uses: aws-powertools/actions/.github/workflows/monthly_roadmap_reminder.yml@fd4575466e5c2ac10703ac16f5aa9fb8890f532a
- with:
- token: ${{ github.token }}
+ permissions:
+ contents: read
+ pull-requests: read
+ issues: write # create monthly roadmap report
+
+ # setting to `@main` until we have releases and governance installed
+ uses: aws-powertools/actions/.github/workflows/monthly_roadmap_reminder.yml@main
+ secrets:
+ token: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/ossf_scorecard.yml b/.github/workflows/ossf_scorecard.yml
index c94e0fd38b4..7baaef518ad 100644
--- a/.github/workflows/ossf_scorecard.yml
+++ b/.github/workflows/ossf_scorecard.yml
@@ -22,12 +22,12 @@ jobs:
steps:
- name: "Checkout code"
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+ uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
with:
persist-credentials: false
- name: "Run analysis"
- uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # v2.3.1
+ uses: ossf/scorecard-action@dc50aa9510b46c811795eb24b2f1ba02a914e534 # v2.3.3
with:
results_file: results.sarif
results_format: sarif
diff --git a/.github/workflows/publish_v2_layer.yml b/.github/workflows/publish_v2_layer.yml
index acde1fa840f..38c02983103 100644
--- a/.github/workflows/publish_v2_layer.yml
+++ b/.github/workflows/publish_v2_layer.yml
@@ -88,7 +88,7 @@ jobs:
working-directory: ./layer
steps:
- name: checkout
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+ uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
with:
ref: ${{ env.RELEASE_COMMIT }}
@@ -247,7 +247,7 @@ jobs:
pages: none
steps:
- name: Checkout repository # reusable workflows start clean, so we need to checkout again
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+ uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
with:
ref: ${{ env.RELEASE_COMMIT }}
diff --git a/.github/workflows/quality_check.yml b/.github/workflows/quality_check.yml
index 84e9c3720c0..bdac2576bcc 100644
--- a/.github/workflows/quality_check.yml
+++ b/.github/workflows/quality_check.yml
@@ -52,7 +52,7 @@ jobs:
permissions:
contents: read # checkout code only
steps:
- - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+ - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
- name: Install poetry
run: pipx install poetry
- name: Set up Python ${{ matrix.python-version }}
@@ -73,7 +73,7 @@ jobs:
- name: Complexity baseline
run: make complexity-baseline
- name: Upload coverage to Codecov
- uses: codecov/codecov-action@84508663e988701840491b86de86b666e8a86bed # 4.3.0
+ uses: codecov/codecov-action@125fc84a9a348dbcf27191600683ec096ec9021c # 4.4.1
with:
file: ./coverage.xml
env_vars: PYTHON
diff --git a/.github/workflows/quality_check_pydanticv2.yml b/.github/workflows/quality_check_pydanticv2.yml
index 8b4fd72dda6..0022de58bbc 100644
--- a/.github/workflows/quality_check_pydanticv2.yml
+++ b/.github/workflows/quality_check_pydanticv2.yml
@@ -49,7 +49,7 @@ jobs:
permissions:
contents: read # checkout code only
steps:
- - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+ - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
- name: Install poetry
run: pipx install poetry
- name: Set up Python ${{ matrix.python-version }}
diff --git a/.github/workflows/record_pr.yml b/.github/workflows/record_pr.yml
index 038c51e9733..386ddf666c9 100644
--- a/.github/workflows/record_pr.yml
+++ b/.github/workflows/record_pr.yml
@@ -46,7 +46,7 @@ jobs:
permissions:
contents: read # NOTE: treat as untrusted location
steps:
- - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+ - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
- name: "Extract PR details"
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index d457186ced5..e2e9d2b7bbd 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -80,7 +80,7 @@ jobs:
RELEASE_VERSION="${RELEASE_TAG_VERSION:1}"
echo "RELEASE_VERSION=${RELEASE_VERSION}" >> "$GITHUB_OUTPUT"
- - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+ - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
with:
ref: ${{ env.RELEASE_COMMIT }}
@@ -115,7 +115,7 @@ jobs:
contents: read
steps:
# NOTE: we need actions/checkout to configure git first (pre-commit hooks in make dev)
- - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+ - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
with:
ref: ${{ env.RELEASE_COMMIT }}
@@ -156,7 +156,7 @@ jobs:
attestation_hashes: ${{ steps.encoded_hash.outputs.attestation_hashes }}
steps:
# NOTE: we need actions/checkout to configure git first (pre-commit hooks in make dev)
- - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+ - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
with:
ref: ${{ env.RELEASE_COMMIT }}
@@ -206,7 +206,7 @@ jobs:
# NOTE: provenance fails if we use action pinning... it's a Github limitation
# because SLSA needs to trace & attest it came from a given branch; pinning doesn't expose that information
# https://github.com/slsa-framework/slsa-github-generator/blob/main/internal/builders/generic/README.md#referencing-the-slsa-generator
- uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v1.10.0
+ uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.0.0
with:
base64-subjects: ${{ needs.build.outputs.attestation_hashes }}
upload-assets: false # we upload its attestation in create_tag job, otherwise it creates a new release
@@ -225,7 +225,7 @@ jobs:
RELEASE_VERSION: ${{ needs.seal.outputs.RELEASE_VERSION }}
steps:
# NOTE: we need actions/checkout in order to use our local actions (e.g., ./.github/actions)
- - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+ - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
with:
ref: ${{ env.RELEASE_COMMIT }}
@@ -259,7 +259,7 @@ jobs:
contents: write
steps:
# NOTE: we need actions/checkout to authenticate and configure git first
- - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+ - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
with:
ref: ${{ env.RELEASE_COMMIT }}
@@ -303,7 +303,7 @@ jobs:
runs-on: ubuntu-latest
steps:
# NOTE: we need actions/checkout to authenticate and configure git first
- - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+ - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
with:
ref: ${{ env.RELEASE_COMMIT }}
@@ -357,7 +357,7 @@ jobs:
env:
RELEASE_VERSION: ${{ needs.seal.outputs.RELEASE_VERSION }}
steps:
- - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+ - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
with:
ref: ${{ env.RELEASE_COMMIT }}
diff --git a/.github/workflows/reusable_deploy_v2_layer_stack.yml b/.github/workflows/reusable_deploy_v2_layer_stack.yml
index 686ae608e70..d097214ff00 100644
--- a/.github/workflows/reusable_deploy_v2_layer_stack.yml
+++ b/.github/workflows/reusable_deploy_v2_layer_stack.yml
@@ -140,7 +140,7 @@ jobs:
has_arm64_support: "true"
steps:
- name: checkout
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+ uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
with:
ref: ${{ env.RELEASE_COMMIT }}
diff --git a/.github/workflows/reusable_deploy_v2_sar.yml b/.github/workflows/reusable_deploy_v2_sar.yml
index 519148abcc2..bb36afed5b8 100644
--- a/.github/workflows/reusable_deploy_v2_sar.yml
+++ b/.github/workflows/reusable_deploy_v2_sar.yml
@@ -79,7 +79,7 @@ jobs:
architecture: ["x86_64", "arm64"]
steps:
- name: checkout
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+ uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
with:
ref: ${{ env.RELEASE_COMMIT }}
diff --git a/.github/workflows/reusable_export_pr_details.yml b/.github/workflows/reusable_export_pr_details.yml
index 220f081593d..a7fc6c94f93 100644
--- a/.github/workflows/reusable_export_pr_details.yml
+++ b/.github/workflows/reusable_export_pr_details.yml
@@ -76,7 +76,7 @@ jobs:
prLabels: ${{ steps.prLabels.outputs.prLabels }}
steps:
- name: Checkout repository # in case caller workflow doesn't checkout thus failing with file not found
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+ uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
- name: "Download previously saved PR"
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
env:
diff --git a/.github/workflows/reusable_publish_changelog.yml b/.github/workflows/reusable_publish_changelog.yml
index 422afd158fe..20108fbf9ee 100644
--- a/.github/workflows/reusable_publish_changelog.yml
+++ b/.github/workflows/reusable_publish_changelog.yml
@@ -26,7 +26,7 @@ jobs:
pull-requests: write # create PR
steps:
- name: Checkout repository # reusable workflows start clean, so we need to checkout again
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+ uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
with:
fetch-depth: 0
- name: "Generate latest changelog"
diff --git a/.github/workflows/reusable_publish_docs.yml b/.github/workflows/reusable_publish_docs.yml
index e61ff2bfffd..93ec97aa795 100644
--- a/.github/workflows/reusable_publish_docs.yml
+++ b/.github/workflows/reusable_publish_docs.yml
@@ -44,7 +44,7 @@ jobs:
id-token: write # trade JWT token for AWS credentials in AWS Docs account
pages: write # uncomment if mike fails as we migrated to S3 hosting
steps:
- - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+ - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
with:
fetch-depth: 0
ref: ${{ inputs.git_ref }}
diff --git a/.github/workflows/run-e2e-tests.yml b/.github/workflows/run-e2e-tests.yml
index 64308ba17db..26df50e50bf 100644
--- a/.github/workflows/run-e2e-tests.yml
+++ b/.github/workflows/run-e2e-tests.yml
@@ -52,7 +52,7 @@ jobs:
if: ${{ github.actor != 'dependabot[bot]' && github.repository == 'aws-powertools/powertools-lambda-python' }}
steps:
- name: "Checkout"
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+ uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
- name: Install poetry
run: pipx install poetry
- name: "Use Python"
diff --git a/.github/workflows/secure_workflows.yml b/.github/workflows/secure_workflows.yml
index 296452b49fe..ca7e0c2c982 100644
--- a/.github/workflows/secure_workflows.yml
+++ b/.github/workflows/secure_workflows.yml
@@ -30,8 +30,10 @@ jobs:
contents: read # checkout code and subsequently GitHub action workflows
steps:
- name: Checkout code
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+ uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
- name: Ensure 3rd party workflows have SHA pinned
- uses: zgosalvez/github-actions-ensure-sha-pinned-actions@19ebcb0babbd282ae1822a0b9c28f3f1f25cea45 # v3.0.4
+ uses: zgosalvez/github-actions-ensure-sha-pinned-actions@40e45e738b3cad2729f599d8afc6ed02184e1dbd # v3.0.5
with:
- allowlist: slsa-framework/slsa-github-generator
+ allowlist: |
+ slsa-framework/slsa-github-generator
+ aws-powertools/actions
diff --git a/.gitignore b/.gitignore
index 2a814459161..990f6517fe9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -314,4 +314,4 @@ examples/**/sam/.aws-sam
cdk.out
# NOTE: different accounts will be used for E2E thus creating unnecessary git clutter
-cdk.context.json
+cdk.context.json
\ No newline at end of file
diff --git a/.markdownlint.yaml b/.markdownlint.yaml
index 4d571206e07..4529480ad19 100644
--- a/.markdownlint.yaml
+++ b/.markdownlint.yaml
@@ -73,8 +73,6 @@ MD013:
tables: false
# Include headings
headings: true
- # Include headings
- headers: true
# Strict length checking
strict: false
# Stern length checking
@@ -107,8 +105,6 @@ MD023: true
# MD024/no-duplicate-heading/no-duplicate-header - Multiple headings with the same content
MD024:
- # Only check sibling headings
- allow_different_nesting: false
# Only check sibling headings
siblings_only: false
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 319afbad0b4..1fbd55f3197 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -34,6 +34,7 @@ repos:
entry: poetry run cfn-lint
language: system
types: [yaml]
+ exclude: examples/homepage/install/.*?/serverless\.yml$
files: examples/.*
- repo: https://github.com/rhysd/actionlint
rev: "fd7ba3c382e13dcc0248e425b4cbc3f1185fa3ee" # v1.6.24
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a462304ab2c..9a15b444d27 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,50 +4,165 @@
# Unreleased
+## Maintenance
+
+* **deps:** bump aws-xray-sdk from 2.13.0 to 2.13.1 ([#4379](https://github.com/aws-powertools/powertools-lambda-python/issues/4379))
+* **deps:** bump requests from 2.31.0 to 2.32.0 ([#4383](https://github.com/aws-powertools/powertools-lambda-python/issues/4383))
+* **deps:** bump the layer-balancer group in /layer/scripts/layer-balancer with 3 updates ([#4369](https://github.com/aws-powertools/powertools-lambda-python/issues/4369))
+* **deps:** bump squidfunk/mkdocs-material from `48d1914` to `5358893` in /docs ([#4377](https://github.com/aws-powertools/powertools-lambda-python/issues/4377))
+* **deps:** bump codecov/codecov-action from 4.4.0 to 4.4.1 ([#4376](https://github.com/aws-powertools/powertools-lambda-python/issues/4376))
+* **deps-dev:** bump pytest from 8.2.0 to 8.2.1 ([#4381](https://github.com/aws-powertools/powertools-lambda-python/issues/4381))
+* **deps-dev:** bump aws-cdk from 2.142.0 to 2.142.1 ([#4366](https://github.com/aws-powertools/powertools-lambda-python/issues/4366))
+* **deps-dev:** bump cdklabs-generative-ai-cdk-constructs from 0.1.150 to 0.1.152 ([#4368](https://github.com/aws-powertools/powertools-lambda-python/issues/4368))
+* **deps-dev:** bump mkdocs-material from 9.5.23 to 9.5.24 ([#4380](https://github.com/aws-powertools/powertools-lambda-python/issues/4380))
+* **deps-dev:** bump cfn-lint from 0.87.2 to 0.87.3 ([#4370](https://github.com/aws-powertools/powertools-lambda-python/issues/4370))
+* **deps-dev:** bump mypy-boto3-secretsmanager from 1.34.107 to 1.34.109 in the boto-typing group ([#4378](https://github.com/aws-powertools/powertools-lambda-python/issues/4378))
+* **deps-dev:** bump aws-cdk-aws-lambda-python-alpha from 2.141.0a0 to 2.142.1a0 ([#4367](https://github.com/aws-powertools/powertools-lambda-python/issues/4367))
+
+
+
+## [v2.38.1] - 2024-05-17
+## Bug Fixes
+
+* **logger:** reverting logger child modification ([#4363](https://github.com/aws-powertools/powertools-lambda-python/issues/4363))
+
+## Maintenance
+
+* version bump
+
+
+
+## [v2.38.0] - 2024-05-17
+## Bug Fixes
+
+* **ci:** apply lessons learned to monthly roadmap reminder cross-repo ([#4078](https://github.com/aws-powertools/powertools-lambda-python/issues/4078))
+* **event-sources:** sane defaults for authorizer v1 and v2 ([#4298](https://github.com/aws-powertools/powertools-lambda-python/issues/4298))
+* **logger:** correctly pick powertools or custom handler in custom environments ([#4295](https://github.com/aws-powertools/powertools-lambda-python/issues/4295))
+* **parser:** make etag optional field on S3 notification events ([#4173](https://github.com/aws-powertools/powertools-lambda-python/issues/4173))
+* **typing:** resolved_headers_field is not Optional ([#4148](https://github.com/aws-powertools/powertools-lambda-python/issues/4148))
+
## Code Refactoring
+* **data-masking:** remove Non-GA comments ([#4334](https://github.com/aws-powertools/powertools-lambda-python/issues/4334))
* **parser:** only infer type hints when necessary ([#4183](https://github.com/aws-powertools/powertools-lambda-python/issues/4183))
## Documentation
+* **general:** update documentation to add info about v3 ([#4234](https://github.com/aws-powertools/powertools-lambda-python/issues/4234))
+* **homepage:** add link to new and official workshop ([#4292](https://github.com/aws-powertools/powertools-lambda-python/issues/4292))
* **idempotency:** fix highlight and import path ([#4154](https://github.com/aws-powertools/powertools-lambda-python/issues/4154))
* **roadmap:** april updates ([#4181](https://github.com/aws-powertools/powertools-lambda-python/issues/4181))
+## Features
+
+* **event_handler:** add support for persisting authorization session in OpenAPI ([#4312](https://github.com/aws-powertools/powertools-lambda-python/issues/4312))
+* **event_handler:** add decorator for HTTP HEAD verb ([#4275](https://github.com/aws-powertools/powertools-lambda-python/issues/4275))
+* **logger-utils:** preserve log level for discovered third-party top-level loggers ([#4299](https://github.com/aws-powertools/powertools-lambda-python/issues/4299))
+
## Maintenance
+* version bump
+* **ci:** bump upload artifact action to v4 ([#4355](https://github.com/aws-powertools/powertools-lambda-python/issues/4355))
+* **ci:** add branch v3 to quality check and e2e actions ([#4232](https://github.com/aws-powertools/powertools-lambda-python/issues/4232))
+* **ci:** bump download artifact action to v4 ([#4358](https://github.com/aws-powertools/powertools-lambda-python/issues/4358))
+* **deps:** bump actions/download-artifact from 4.1.4 to 4.1.5 ([#4161](https://github.com/aws-powertools/powertools-lambda-python/issues/4161))
+* **deps:** bump actions/checkout from 4.1.3 to 4.1.4 ([#4206](https://github.com/aws-powertools/powertools-lambda-python/issues/4206))
+* **deps:** bump ossf/scorecard-action from 2.3.1 to 2.3.3 ([#4315](https://github.com/aws-powertools/powertools-lambda-python/issues/4315))
+* **deps:** bump github.com/aws/aws-sdk-go-v2/config from 1.27.12 to 1.27.13 in /layer/scripts/layer-balancer in the layer-balancer group ([#4319](https://github.com/aws-powertools/powertools-lambda-python/issues/4319))
* **deps:** bump actions/download-artifact from 4.1.6 to 4.1.7 ([#4205](https://github.com/aws-powertools/powertools-lambda-python/issues/4205))
-* **deps:** bump actions/checkout from 4.1.2 to 4.1.3 ([#4168](https://github.com/aws-powertools/powertools-lambda-python/issues/4168))
* **deps:** bump squidfunk/mkdocs-material from `521644b` to `e309089` in /docs ([#4216](https://github.com/aws-powertools/powertools-lambda-python/issues/4216))
-* **deps:** bump actions/upload-artifact from 4.3.2 to 4.3.3 ([#4177](https://github.com/aws-powertools/powertools-lambda-python/issues/4177))
-* **deps:** bump actions/download-artifact from 4.1.5 to 4.1.6 ([#4178](https://github.com/aws-powertools/powertools-lambda-python/issues/4178))
+* **deps:** bump squidfunk/mkdocs-material from `11d7ec0` to `8ef47d7` in /docs ([#4323](https://github.com/aws-powertools/powertools-lambda-python/issues/4323))
* **deps:** bump datadog-lambda from 5.92.0 to 5.93.0 ([#4211](https://github.com/aws-powertools/powertools-lambda-python/issues/4211))
-* **deps:** bump actions/checkout from 4.1.3 to 4.1.4 ([#4206](https://github.com/aws-powertools/powertools-lambda-python/issues/4206))
-* **deps:** bump actions/download-artifact from 4.1.4 to 4.1.5 ([#4161](https://github.com/aws-powertools/powertools-lambda-python/issues/4161))
-* **deps:** bump actions/upload-artifact from 4.3.1 to 4.3.2 ([#4162](https://github.com/aws-powertools/powertools-lambda-python/issues/4162))
* **deps:** bump redis from 5.0.3 to 5.0.4 ([#4187](https://github.com/aws-powertools/powertools-lambda-python/issues/4187))
+* **deps:** bump actions/upload-artifact from 4.3.2 to 4.3.3 ([#4177](https://github.com/aws-powertools/powertools-lambda-python/issues/4177))
+* **deps:** bump the layer-balancer group in /layer/scripts/layer-balancer with 2 updates ([#4302](https://github.com/aws-powertools/powertools-lambda-python/issues/4302))
+* **deps:** bump squidfunk/mkdocs-material from `8ef47d7` to `48d1914` in /docs ([#4336](https://github.com/aws-powertools/powertools-lambda-python/issues/4336))
+* **deps:** bump the layer-balancer group in /layer/scripts/layer-balancer with 3 updates ([#4337](https://github.com/aws-powertools/powertools-lambda-python/issues/4337))
+* **deps:** bump squidfunk/mkdocs-material from `e309089` to `98c9809` in /docs ([#4236](https://github.com/aws-powertools/powertools-lambda-python/issues/4236))
+* **deps:** bump actions/dependency-review-action from 4.3.1 to 4.3.2 ([#4244](https://github.com/aws-powertools/powertools-lambda-python/issues/4244))
+* **deps:** bump zgosalvez/github-actions-ensure-sha-pinned-actions from 3.0.4 to 3.0.5 ([#4281](https://github.com/aws-powertools/powertools-lambda-python/issues/4281))
+* **deps:** bump actions/checkout from 4.1.4 to 4.1.5 ([#4282](https://github.com/aws-powertools/powertools-lambda-python/issues/4282))
+* **deps:** bump jinja2 from 3.1.3 to 3.1.4 in /docs ([#4284](https://github.com/aws-powertools/powertools-lambda-python/issues/4284))
+* **deps:** bump codecov/codecov-action from 4.3.0 to 4.3.1 ([#4252](https://github.com/aws-powertools/powertools-lambda-python/issues/4252))
+* **deps:** bump datadog-lambda from 5.93.0 to 5.94.0 ([#4253](https://github.com/aws-powertools/powertools-lambda-python/issues/4253))
+* **deps:** bump actions/checkout from 4.1.2 to 4.1.3 ([#4168](https://github.com/aws-powertools/powertools-lambda-python/issues/4168))
+* **deps:** bump actions/dependency-review-action from 4.2.5 to 4.3.1 ([#4240](https://github.com/aws-powertools/powertools-lambda-python/issues/4240))
+* **deps:** bump actions/checkout from 4.1.5 to 4.1.6 ([#4344](https://github.com/aws-powertools/powertools-lambda-python/issues/4344))
+* **deps:** bump squidfunk/mkdocs-material from `98c9809` to `11d7ec0` in /docs ([#4269](https://github.com/aws-powertools/powertools-lambda-python/issues/4269))
+* **deps:** bump actions/upload-artifact from 4.3.1 to 4.3.2 ([#4162](https://github.com/aws-powertools/powertools-lambda-python/issues/4162))
+* **deps:** bump codecov/codecov-action from 4.3.1 to 4.4.0 ([#4328](https://github.com/aws-powertools/powertools-lambda-python/issues/4328))
+* **deps:** bump slsa-framework/slsa-github-generator from 1.10.0 to 2.0.0 ([#4179](https://github.com/aws-powertools/powertools-lambda-python/issues/4179))
+* **deps:** bump actions/download-artifact from 4.1.5 to 4.1.6 ([#4178](https://github.com/aws-powertools/powertools-lambda-python/issues/4178))
+* **deps-dev:** bump mkdocs-material from 9.5.20 to 9.5.21 ([#4271](https://github.com/aws-powertools/powertools-lambda-python/issues/4271))
+* **deps-dev:** bump mike from 2.1.0 to 2.1.1 ([#4268](https://github.com/aws-powertools/powertools-lambda-python/issues/4268))
+* **deps-dev:** bump cfn-lint from 0.87.0 to 0.87.1 ([#4272](https://github.com/aws-powertools/powertools-lambda-python/issues/4272))
+* **deps-dev:** bump mike from 1.1.2 to 2.1.0 ([#4258](https://github.com/aws-powertools/powertools-lambda-python/issues/4258))
+* **deps-dev:** bump aws-cdk-lib from 2.139.1 to 2.140.0 ([#4259](https://github.com/aws-powertools/powertools-lambda-python/issues/4259))
+* **deps-dev:** bump aws-cdk-aws-lambda-python-alpha from 2.139.1a0 to 2.140.0a0 ([#4270](https://github.com/aws-powertools/powertools-lambda-python/issues/4270))
+* **deps-dev:** bump aws-cdk-aws-lambda-python-alpha from 2.139.0a0 to 2.139.1a0 ([#4261](https://github.com/aws-powertools/powertools-lambda-python/issues/4261))
+* **deps-dev:** bump cdklabs-generative-ai-cdk-constructs from 0.1.133 to 0.1.134 ([#4260](https://github.com/aws-powertools/powertools-lambda-python/issues/4260))
+* **deps-dev:** bump cdklabs-generative-ai-cdk-constructs from 0.1.134 to 0.1.135 ([#4273](https://github.com/aws-powertools/powertools-lambda-python/issues/4273))
+* **deps-dev:** bump mypy-boto3-dynamodb from 1.34.91 to 1.34.97 in the boto-typing group ([#4257](https://github.com/aws-powertools/powertools-lambda-python/issues/4257))
+* **deps-dev:** bump sentry-sdk from 2.0.1 to 2.1.1 ([#4287](https://github.com/aws-powertools/powertools-lambda-python/issues/4287))
+* **deps-dev:** bump aws-cdk-lib from 2.139.0 to 2.139.1 ([#4248](https://github.com/aws-powertools/powertools-lambda-python/issues/4248))
+* **deps-dev:** bump cfn-lint from 0.86.4 to 0.87.0 ([#4249](https://github.com/aws-powertools/powertools-lambda-python/issues/4249))
+* **deps-dev:** bump pytest-xdist from 3.5.0 to 3.6.1 ([#4247](https://github.com/aws-powertools/powertools-lambda-python/issues/4247))
+* **deps-dev:** bump ruff from 0.4.2 to 0.4.3 ([#4286](https://github.com/aws-powertools/powertools-lambda-python/issues/4286))
+* **deps-dev:** bump cdklabs-generative-ai-cdk-constructs from 0.1.132 to 0.1.133 ([#4246](https://github.com/aws-powertools/powertools-lambda-python/issues/4246))
+* **deps-dev:** bump jinja2 from 3.1.3 to 3.1.4 ([#4283](https://github.com/aws-powertools/powertools-lambda-python/issues/4283))
+* **deps-dev:** bump aws-cdk from 2.139.0 to 2.139.1 ([#4245](https://github.com/aws-powertools/powertools-lambda-python/issues/4245))
+* **deps-dev:** bump cdklabs-generative-ai-cdk-constructs from 0.1.135 to 0.1.136 ([#4285](https://github.com/aws-powertools/powertools-lambda-python/issues/4285))
+* **deps-dev:** bump filelock from 3.13.4 to 3.14.0 ([#4241](https://github.com/aws-powertools/powertools-lambda-python/issues/4241))
+* **deps-dev:** bump hvac from 2.1.0 to 2.2.0 ([#4238](https://github.com/aws-powertools/powertools-lambda-python/issues/4238))
+* **deps-dev:** bump cdklabs-generative-ai-cdk-constructs from 0.1.131 to 0.1.132 ([#4239](https://github.com/aws-powertools/powertools-lambda-python/issues/4239))
+* **deps-dev:** bump mkdocs-material from 9.5.19 to 9.5.20 ([#4242](https://github.com/aws-powertools/powertools-lambda-python/issues/4242))
+* **deps-dev:** bump aws-cdk from 2.139.1 to 2.140.0 ([#4256](https://github.com/aws-powertools/powertools-lambda-python/issues/4256))
+* **deps-dev:** bump pytest from 8.1.1 to 8.2.0 ([#4237](https://github.com/aws-powertools/powertools-lambda-python/issues/4237))
+* **deps-dev:** bump cdklabs-generative-ai-cdk-constructs from 0.1.136 to 0.1.139 ([#4293](https://github.com/aws-powertools/powertools-lambda-python/issues/4293))
+* **deps-dev:** bump aws-cdk-lib from 2.141.0 to 2.142.1 ([#4352](https://github.com/aws-powertools/powertools-lambda-python/issues/4352))
+* **deps-dev:** bump cdklabs-generative-ai-cdk-constructs from 0.1.139 to 0.1.140 ([#4301](https://github.com/aws-powertools/powertools-lambda-python/issues/4301))
+* **deps-dev:** bump sentry-sdk from 1.45.0 to 2.0.1 ([#4223](https://github.com/aws-powertools/powertools-lambda-python/issues/4223))
+* **deps-dev:** bump mkdocs-material from 9.5.18 to 9.5.19 ([#4224](https://github.com/aws-powertools/powertools-lambda-python/issues/4224))
+* **deps-dev:** bump black from 24.4.1 to 24.4.2 ([#4222](https://github.com/aws-powertools/powertools-lambda-python/issues/4222))
+* **deps-dev:** bump aws-cdk-aws-lambda-python-alpha from 2.138.0a0 to 2.139.0a0 ([#4225](https://github.com/aws-powertools/powertools-lambda-python/issues/4225))
+* **deps-dev:** bump cdklabs-generative-ai-cdk-constructs from 0.1.130 to 0.1.131 ([#4221](https://github.com/aws-powertools/powertools-lambda-python/issues/4221))
+* **deps-dev:** bump cdklabs-generative-ai-cdk-constructs from 0.1.140 to 0.1.142 ([#4307](https://github.com/aws-powertools/powertools-lambda-python/issues/4307))
* **deps-dev:** bump ruff from 0.4.1 to 0.4.2 ([#4212](https://github.com/aws-powertools/powertools-lambda-python/issues/4212))
-* **deps-dev:** bump cdklabs-generative-ai-cdk-constructs from 0.1.123 to 0.1.126 ([#4188](https://github.com/aws-powertools/powertools-lambda-python/issues/4188))
+* **deps-dev:** bump aws-cdk-lib from 2.138.0 to 2.139.0 ([#4213](https://github.com/aws-powertools/powertools-lambda-python/issues/4213))
+* **deps-dev:** bump aws-cdk from 2.138.0 to 2.139.0 ([#4215](https://github.com/aws-powertools/powertools-lambda-python/issues/4215))
+* **deps-dev:** bump aws-cdk from 2.140.0 to 2.141.0 ([#4306](https://github.com/aws-powertools/powertools-lambda-python/issues/4306))
+* **deps-dev:** bump types-redis from 4.6.0.20240423 to 4.6.0.20240425 ([#4214](https://github.com/aws-powertools/powertools-lambda-python/issues/4214))
+* **deps-dev:** bump aws-cdk-lib from 2.140.0 to 2.141.0 ([#4308](https://github.com/aws-powertools/powertools-lambda-python/issues/4308))
+* **deps-dev:** bump the boto-typing group with 2 updates ([#4210](https://github.com/aws-powertools/powertools-lambda-python/issues/4210))
+* **deps-dev:** bump cdklabs-generative-ai-cdk-constructs from 0.1.126 to 0.1.130 ([#4209](https://github.com/aws-powertools/powertools-lambda-python/issues/4209))
+* **deps-dev:** bump ruff from 0.4.3 to 0.4.4 ([#4309](https://github.com/aws-powertools/powertools-lambda-python/issues/4309))
+* **deps-dev:** bump aws-cdk-aws-lambda-python-alpha from 2.140.0a0 to 2.141.0a0 ([#4318](https://github.com/aws-powertools/powertools-lambda-python/issues/4318))
+* **deps-dev:** bump cdklabs-generative-ai-cdk-constructs from 0.1.142 to 0.1.144 ([#4316](https://github.com/aws-powertools/powertools-lambda-python/issues/4316))
+* **deps-dev:** bump black from 24.4.0 to 24.4.1 ([#4203](https://github.com/aws-powertools/powertools-lambda-python/issues/4203))
+* **deps-dev:** bump mypy from 1.9.0 to 1.10.0 ([#4202](https://github.com/aws-powertools/powertools-lambda-python/issues/4202))
* **deps-dev:** bump mypy-boto3-ssm from 1.34.61 to 1.34.91 in the boto-typing group ([#4201](https://github.com/aws-powertools/powertools-lambda-python/issues/4201))
+* **deps-dev:** bump cdklabs-generative-ai-cdk-constructs from 0.1.123 to 0.1.126 ([#4188](https://github.com/aws-powertools/powertools-lambda-python/issues/4188))
+* **deps-dev:** bump cfn-lint from 0.87.1 to 0.87.2 ([#4317](https://github.com/aws-powertools/powertools-lambda-python/issues/4317))
* **deps-dev:** bump coverage from 7.4.4 to 7.5.0 ([#4186](https://github.com/aws-powertools/powertools-lambda-python/issues/4186))
-* **deps-dev:** bump mypy from 1.9.0 to 1.10.0 ([#4202](https://github.com/aws-powertools/powertools-lambda-python/issues/4202))
+* **deps-dev:** bump cdklabs-generative-ai-cdk-constructs from 0.1.144 to 0.1.145 ([#4325](https://github.com/aws-powertools/powertools-lambda-python/issues/4325))
* **deps-dev:** bump types-redis from 4.6.0.20240417 to 4.6.0.20240423 ([#4185](https://github.com/aws-powertools/powertools-lambda-python/issues/4185))
-* **deps-dev:** bump black from 24.4.0 to 24.4.1 ([#4203](https://github.com/aws-powertools/powertools-lambda-python/issues/4203))
-* **deps-dev:** bump cdklabs-generative-ai-cdk-constructs from 0.1.126 to 0.1.130 ([#4209](https://github.com/aws-powertools/powertools-lambda-python/issues/4209))
-* **deps-dev:** bump the boto-typing group with 2 updates ([#4210](https://github.com/aws-powertools/powertools-lambda-python/issues/4210))
+* **deps-dev:** bump mkdocs-material from 9.5.21 to 9.5.22 ([#4324](https://github.com/aws-powertools/powertools-lambda-python/issues/4324))
+* **deps-dev:** bump mypy-boto3-s3 from 1.34.91 to 1.34.105 in the boto-typing group ([#4329](https://github.com/aws-powertools/powertools-lambda-python/issues/4329))
+* **deps-dev:** bump cdklabs-generative-ai-cdk-constructs from 0.1.145 to 0.1.146 ([#4330](https://github.com/aws-powertools/powertools-lambda-python/issues/4330))
* **deps-dev:** bump cfn-lint from 0.86.3 to 0.86.4 ([#4180](https://github.com/aws-powertools/powertools-lambda-python/issues/4180))
* **deps-dev:** bump cdklabs-generative-ai-cdk-constructs from 0.1.121 to 0.1.123 ([#4176](https://github.com/aws-powertools/powertools-lambda-python/issues/4176))
-* **deps-dev:** bump mkdocs-material from 9.5.18 to 9.5.19 ([#4224](https://github.com/aws-powertools/powertools-lambda-python/issues/4224))
+* **deps-dev:** bump mkdocs-material from 9.5.22 to 9.5.23 ([#4338](https://github.com/aws-powertools/powertools-lambda-python/issues/4338))
* **deps-dev:** bump aws-cdk-aws-lambda-python-alpha from 2.137.0a0 to 2.138.0a0 ([#4169](https://github.com/aws-powertools/powertools-lambda-python/issues/4169))
-* **deps-dev:** bump types-redis from 4.6.0.20240423 to 4.6.0.20240425 ([#4214](https://github.com/aws-powertools/powertools-lambda-python/issues/4214))
+* **deps-dev:** bump aws-cdk from 2.141.0 to 2.142.0 ([#4343](https://github.com/aws-powertools/powertools-lambda-python/issues/4343))
* **deps-dev:** bump cdklabs-generative-ai-cdk-constructs from 0.1.119 to 0.1.121 ([#4167](https://github.com/aws-powertools/powertools-lambda-python/issues/4167))
* **deps-dev:** bump ruff from 0.3.7 to 0.4.1 ([#4166](https://github.com/aws-powertools/powertools-lambda-python/issues/4166))
-* **deps-dev:** bump aws-cdk from 2.138.0 to 2.139.0 ([#4215](https://github.com/aws-powertools/powertools-lambda-python/issues/4215))
-* **deps-dev:** bump aws-cdk-lib from 2.138.0 to 2.139.0 ([#4213](https://github.com/aws-powertools/powertools-lambda-python/issues/4213))
-* **deps-dev:** bump aws-cdk-lib from 2.137.0 to 2.138.0 ([#4160](https://github.com/aws-powertools/powertools-lambda-python/issues/4160))
-* **deps-dev:** bump cdklabs-generative-ai-cdk-constructs from 0.1.130 to 0.1.131 ([#4221](https://github.com/aws-powertools/powertools-lambda-python/issues/4221))
-* **deps-dev:** bump aws-cdk-aws-lambda-python-alpha from 2.138.0a0 to 2.139.0a0 ([#4225](https://github.com/aws-powertools/powertools-lambda-python/issues/4225))
-* **deps-dev:** bump black from 24.4.1 to 24.4.2 ([#4222](https://github.com/aws-powertools/powertools-lambda-python/issues/4222))
+* **deps-dev:** bump mypy-boto3-secretsmanager from 1.34.72 to 1.34.107 in the boto-typing group ([#4345](https://github.com/aws-powertools/powertools-lambda-python/issues/4345))
* **deps-dev:** bump aws-cdk from 2.137.0 to 2.138.0 ([#4157](https://github.com/aws-powertools/powertools-lambda-python/issues/4157))
+* **deps-dev:** bump aws-cdk-lib from 2.137.0 to 2.138.0 ([#4160](https://github.com/aws-powertools/powertools-lambda-python/issues/4160))
+* **deps-dev:** bump sentry-sdk from 2.1.1 to 2.2.0 ([#4348](https://github.com/aws-powertools/powertools-lambda-python/issues/4348))
+* **deps-dev:** bump cdklabs-generative-ai-cdk-constructs from 0.1.146 to 0.1.150 ([#4346](https://github.com/aws-powertools/powertools-lambda-python/issues/4346))
+* **deps-dev:** bump coverage from 7.5.0 to 7.5.1 ([#4288](https://github.com/aws-powertools/powertools-lambda-python/issues/4288))
+* **governance:** add FastAPI third party license attribution ([#4297](https://github.com/aws-powertools/powertools-lambda-python/issues/4297))
@@ -4748,7 +4863,9 @@
* Merge pull request [#5](https://github.com/aws-powertools/powertools-lambda-python/issues/5) from jfuss/feat/python38
-[Unreleased]: https://github.com/aws-powertools/powertools-lambda-python/compare/v2.37.0...HEAD
+[Unreleased]: https://github.com/aws-powertools/powertools-lambda-python/compare/v2.38.1...HEAD
+[v2.38.1]: https://github.com/aws-powertools/powertools-lambda-python/compare/v2.38.0...v2.38.1
+[v2.38.0]: https://github.com/aws-powertools/powertools-lambda-python/compare/v2.37.0...v2.38.0
[v2.37.0]: https://github.com/aws-powertools/powertools-lambda-python/compare/v2.36.0...v2.37.0
[v2.36.0]: https://github.com/aws-powertools/powertools-lambda-python/compare/v2.35.1...v2.36.0
[v2.35.1]: https://github.com/aws-powertools/powertools-lambda-python/compare/v2.35.0...v2.35.1
diff --git a/THIRD-PARTY-LICENSES b/THIRD-PARTY-LICENSES
index 3712eac88cf..f6d647c54a7 100644
--- a/THIRD-PARTY-LICENSES
+++ b/THIRD-PARTY-LICENSES
@@ -1,3 +1,27 @@
+** FastAPI - https://github.com/tiangolo/fastapi/ - Used in the OpenAPI feature
+
+ The MIT License (MIT)
+
+ Copyright (c) 2018 Sebastián Ramírez
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+
** Tensorflow - https://github.com/tensorflow/tensorflow/
Apache License
diff --git a/aws_lambda_powertools/event_handler/api_gateway.py b/aws_lambda_powertools/event_handler/api_gateway.py
index 87433b020d5..26da85679bc 100644
--- a/aws_lambda_powertools/event_handler/api_gateway.py
+++ b/aws_lambda_powertools/event_handler/api_gateway.py
@@ -1222,6 +1222,63 @@ def lambda_handler(event, context):
middlewares,
)
+ def head(
+ self,
+ rule: str,
+ cors: Optional[bool] = None,
+ compress: bool = False,
+ cache_control: Optional[str] = None,
+ summary: Optional[str] = None,
+ description: Optional[str] = None,
+ responses: Optional[Dict[int, OpenAPIResponse]] = None,
+ response_description: str = _DEFAULT_OPENAPI_RESPONSE_DESCRIPTION,
+ tags: Optional[List[str]] = None,
+ operation_id: Optional[str] = None,
+ include_in_schema: bool = True,
+ security: Optional[List[Dict[str, List[str]]]] = None,
+ middlewares: Optional[List[Callable]] = None,
+ ):
+ """Head route decorator with HEAD `method`
+
+ Examples
+ --------
+ Simple example with a custom lambda handler using the Tracer capture_lambda_handler decorator
+
+ ```python
+ from aws_lambda_powertools import Tracer
+ from aws_lambda_powertools.event_handler import APIGatewayRestResolver, Response, content_types
+
+ tracer = Tracer()
+ app = APIGatewayRestResolver()
+
+ @app.head("/head-call")
+ def simple_head():
+ return Response(status_code=200,
+ content_type=content_types.APPLICATION_JSON,
+ headers={"Content-Length": "123"})
+
+ @tracer.capture_lambda_handler
+ def lambda_handler(event, context):
+ return app.resolve(event, context)
+ ```
+ """
+ return self.route(
+ rule,
+ "HEAD",
+ cors,
+ compress,
+ cache_control,
+ summary,
+ description,
+ responses,
+ response_description,
+ tags,
+ operation_id,
+ include_in_schema,
+ security,
+ middlewares,
+ )
+
def _push_processed_stack_frame(self, frame: str):
"""
Add Current Middleware to the Middleware Stack Frames
@@ -1589,13 +1646,13 @@ def _determine_openapi_version(openapi_version):
from aws_lambda_powertools.event_handler.openapi.pydantic_loader import PYDANTIC_V2
# Pydantic V2 has no support for OpenAPI schema 3.0
- if PYDANTIC_V2 and not openapi_version.startswith("3.1"):
+ if PYDANTIC_V2 and not openapi_version.startswith("3.1"): # pragma: no cover
warnings.warn(
"You are using Pydantic v2, which is incompatible with OpenAPI schema 3.0. Forcing OpenAPI 3.1",
stacklevel=2,
)
openapi_version = "3.1.0"
- elif not PYDANTIC_V2 and not openapi_version.startswith("3.0"):
+ elif not PYDANTIC_V2 and not openapi_version.startswith("3.0"): # pragma: no cover
warnings.warn(
"You are using Pydantic v1, which is incompatible with OpenAPI schema 3.1. Forcing OpenAPI 3.0",
stacklevel=2,
@@ -1696,6 +1753,7 @@ def enable_swagger(
security_schemes: Optional[Dict[str, "SecurityScheme"]] = None,
security: Optional[List[Dict[str, List[str]]]] = None,
oauth2_config: Optional["OAuth2Config"] = None,
+ persist_authorization: bool = False,
):
"""
Returns the OpenAPI schema as a JSON serializable dict
@@ -1736,6 +1794,8 @@ def enable_swagger(
A declaration of which security mechanisms are applied globally across the API.
oauth2_config: OAuth2Config, optional
The OAuth2 configuration for the Swagger UI.
+ persist_authorization: bool, optional
+ Whether to persist authorization data on browser close/refresh.
"""
from aws_lambda_powertools.event_handler.openapi.compat import model_json
from aws_lambda_powertools.event_handler.openapi.models import Server
@@ -1814,6 +1874,7 @@ def swagger_handler():
swagger_css,
swagger_base_url,
oauth2_config,
+ persist_authorization,
)
return Response(
@@ -2135,7 +2196,7 @@ def not_found(self, func: Optional[Callable] = None):
def exception_handler(self, exc_class: Union[Type[Exception], List[Type[Exception]]]):
def register_exception_handler(func: Callable):
- if isinstance(exc_class, list):
+ if isinstance(exc_class, list): # pragma: no cover
for exp in exc_class:
self._exception_handlers[exp] = func
else:
diff --git a/aws_lambda_powertools/event_handler/middlewares/openapi_validation.py b/aws_lambda_powertools/event_handler/middlewares/openapi_validation.py
index a57560a3ad1..2eafb0d67bb 100644
--- a/aws_lambda_powertools/event_handler/middlewares/openapi_validation.py
+++ b/aws_lambda_powertools/event_handler/middlewares/openapi_validation.py
@@ -410,7 +410,7 @@ def _normalize_multi_query_string_with_param(
return resolved_query_string
-def _normalize_multi_header_values_with_param(headers: Optional[Dict[str, str]], params: Sequence[ModelField]):
+def _normalize_multi_header_values_with_param(headers: Dict[str, Any], params: Sequence[ModelField]):
"""
Extract and normalize resolved_headers_field
diff --git a/aws_lambda_powertools/event_handler/openapi/compat.py b/aws_lambda_powertools/event_handler/openapi/compat.py
index bd102aa7b93..060886605ec 100644
--- a/aws_lambda_powertools/event_handler/openapi/compat.py
+++ b/aws_lambda_powertools/event_handler/openapi/compat.py
@@ -40,7 +40,7 @@
RequestErrorModel: Type[BaseModel] = create_model("Request")
-if PYDANTIC_V2:
+if PYDANTIC_V2: # pragma: no cover # false positive; dropping in v3
from pydantic import TypeAdapter, ValidationError
from pydantic._internal._typing_extra import eval_type_lenient
from pydantic.fields import FieldInfo
diff --git a/aws_lambda_powertools/event_handler/openapi/pydantic_loader.py b/aws_lambda_powertools/event_handler/openapi/pydantic_loader.py
index 12f06dad899..225f7e88096 100644
--- a/aws_lambda_powertools/event_handler/openapi/pydantic_loader.py
+++ b/aws_lambda_powertools/event_handler/openapi/pydantic_loader.py
@@ -3,4 +3,4 @@
PYDANTIC_V2 = PYDANTIC_VERSION.startswith("2.")
except ImportError:
- PYDANTIC_V2 = False
+ PYDANTIC_V2 = False # pragma: no cover # false positive; dropping in v3
diff --git a/aws_lambda_powertools/event_handler/openapi/swagger_ui/html.py b/aws_lambda_powertools/event_handler/openapi/swagger_ui/html.py
index 8b748d9338a..85e041f2f56 100644
--- a/aws_lambda_powertools/event_handler/openapi/swagger_ui/html.py
+++ b/aws_lambda_powertools/event_handler/openapi/swagger_ui/html.py
@@ -10,6 +10,7 @@ def generate_swagger_html(
swagger_css: str,
swagger_base_url: str,
oauth2_config: Optional[OAuth2Config],
+ persist_authorization: bool = False,
) -> str:
"""
Generate Swagger UI HTML page
@@ -28,6 +29,8 @@ def generate_swagger_html(
The base URL for Swagger UI
oauth2_config: OAuth2Config, optional
The OAuth2 configuration.
+ persist_authorization: bool, optional
+ Whether to persist authorization data on browser close/refresh.
"""
# If Swagger base URL is present, generate HTML content with linked CSS and JavaScript files
@@ -86,6 +89,7 @@ def generate_swagger_html(
SwaggerUIBundle.plugins.DownloadUrl
],
withCredentials: true,
+ persistAuthorization: {str(persist_authorization).lower()},
oauth2RedirectUrl: baseUrl + "?format=oauth2-redirect",
}}
diff --git a/aws_lambda_powertools/logging/constants.py b/aws_lambda_powertools/logging/constants.py
new file mode 100644
index 00000000000..c98204f9bb1
--- /dev/null
+++ b/aws_lambda_powertools/logging/constants.py
@@ -0,0 +1,5 @@
+# logger.powertools_handler is set with Powertools Logger handler; useful when there are many handlers
+LOGGER_ATTRIBUTE_POWERTOOLS_HANDLER = "powertools_handler"
+# logger.init attribute is set when Logger has been configured
+LOGGER_ATTRIBUTE_PRECONFIGURED = "init"
+LOGGER_ATTRIBUTE_HANDLER = "logger_handler"
diff --git a/aws_lambda_powertools/logging/logger.py b/aws_lambda_powertools/logging/logger.py
index dc03e1af8eb..77845c9e8ae 100644
--- a/aws_lambda_powertools/logging/logger.py
+++ b/aws_lambda_powertools/logging/logger.py
@@ -22,6 +22,9 @@
overload,
)
+from aws_lambda_powertools.logging.constants import (
+ LOGGER_ATTRIBUTE_PRECONFIGURED,
+)
from aws_lambda_powertools.shared import constants
from aws_lambda_powertools.shared.functions import (
extract_event_from_common_models,
@@ -264,7 +267,7 @@ def __init__(
# Prevent __getattr__ from shielding unknown attribute errors in type checkers
# https://github.com/aws-powertools/powertools-lambda-python/issues/1660
- if not TYPE_CHECKING:
+ if not TYPE_CHECKING: # pragma: no cover
def __getattr__(self, name):
# Proxy attributes not found to actual logger to support backward compatibility
@@ -292,7 +295,7 @@ def _init_logger(
# a) multiple handlers being attached
# b) different sampling mechanisms
# c) multiple messages from being logged as handlers can be duplicated
- is_logger_preconfigured = getattr(self._logger, "init", False)
+ is_logger_preconfigured = getattr(self._logger, LOGGER_ATTRIBUTE_PRECONFIGURED, False)
if self.child or is_logger_preconfigured:
return
@@ -613,7 +616,7 @@ def structure_logs(self, append: bool = False, formatter_options: Optional[Dict]
# Mode 1
log_keys = {**self._default_log_keys, **keys}
- is_logger_preconfigured = getattr(self._logger, "init", False)
+ is_logger_preconfigured = getattr(self._logger, LOGGER_ATTRIBUTE_PRECONFIGURED, False)
if not is_logger_preconfigured:
formatter = self.logger_formatter or LambdaPowertoolsFormatter(**formatter_options, **log_keys)
self.registered_handler.setFormatter(formatter)
diff --git a/aws_lambda_powertools/logging/utils.py b/aws_lambda_powertools/logging/utils.py
index eb299c888a2..3e1c3c69aed 100644
--- a/aws_lambda_powertools/logging/utils.py
+++ b/aws_lambda_powertools/logging/utils.py
@@ -9,6 +9,7 @@
def copy_config_to_registered_loggers(
source_logger: Logger,
log_level: Optional[Union[int, str]] = None,
+ ignore_log_level=False,
exclude: Optional[Set[str]] = None,
include: Optional[Set[str]] = None,
) -> None:
@@ -16,10 +17,13 @@ def copy_config_to_registered_loggers(
Parameters
----------
+ ignore_log_level
source_logger : Logger
Powertools for AWS Lambda (Python) Logger to copy configuration from
log_level : Union[int, str], optional
Logging level to set to registered loggers, by default uses source_logger logging level
+ ignore_log_level: bool
+ Whether to not touch log levels for discovered loggers. log_level param is disregarded when this is set.
include : Optional[Set[str]], optional
List of logger names to include, by default all registered loggers are included
exclude : Optional[Set[str]], optional
@@ -54,7 +58,7 @@ def copy_config_to_registered_loggers(
registered_loggers = _find_registered_loggers(source_logger, loggers, filter_func)
for logger in registered_loggers:
- _configure_logger(source_logger, logger, level)
+ _configure_logger(source_logger=source_logger, logger=logger, level=level, ignore_log_level=ignore_log_level)
def _include_registered_loggers_filter(loggers: Set[str]):
@@ -78,13 +82,21 @@ def _find_registered_loggers(
return root_loggers
-def _configure_logger(source_logger: Logger, logger: logging.Logger, level: Union[int, str]) -> None:
+def _configure_logger(
+ source_logger: Logger,
+ logger: logging.Logger,
+ level: Union[int, str],
+ ignore_log_level: bool = False,
+) -> None:
+ # customers may not want to copy the same log level from Logger to discovered loggers
+ if not ignore_log_level:
+ logger.setLevel(level)
+ source_logger.debug(f"Logger {logger} reconfigured to use logging level {level}")
+
logger.handlers = []
- logger.setLevel(level)
logger.propagate = False # ensure we don't propagate logs to existing loggers, #1073
source_logger.append_keys(name="%(name)s") # include logger name, see #1267
- source_logger.debug(f"Logger {logger} reconfigured to use logging level {level}")
for source_handler in source_logger.handlers:
logger.addHandler(source_handler)
source_logger.debug(f"Logger {logger} reconfigured to use {source_handler}")
diff --git a/aws_lambda_powertools/shared/constants.py b/aws_lambda_powertools/shared/constants.py
index bb8164d1d37..9652e09a0b2 100644
--- a/aws_lambda_powertools/shared/constants.py
+++ b/aws_lambda_powertools/shared/constants.py
@@ -9,6 +9,7 @@
INVALID_XRAY_NAME_CHARACTERS = r"[?;*()!$~^<>]"
# Logger constants
+# maintenance: future major version should start having localized `constants.py` to ease future modularization
LOGGER_LOG_SAMPLING_RATE: str = "POWERTOOLS_LOGGER_SAMPLE_RATE"
LOGGER_LOG_EVENT_ENV: str = "POWERTOOLS_LOGGER_LOG_EVENT"
LOGGER_LOG_DEDUPLICATION_ENV: str = "POWERTOOLS_LOG_DEDUPLICATION_DISABLED"
@@ -61,7 +62,7 @@
# JSON constants
PRETTY_INDENT: int = 4
-COMPACT_INDENT = None
+COMPACT_INDENT: None = None
# Idempotency constants
IDEMPOTENCY_DISABLED_ENV: str = "POWERTOOLS_IDEMPOTENCY_DISABLED"
diff --git a/aws_lambda_powertools/shared/version.py b/aws_lambda_powertools/shared/version.py
index 351af8fac73..2f1383fecf2 100644
--- a/aws_lambda_powertools/shared/version.py
+++ b/aws_lambda_powertools/shared/version.py
@@ -1,3 +1,3 @@
"""Exposes version constant to avoid circular dependencies."""
-VERSION = "2.37.0"
+VERSION = "2.38.1"
diff --git a/aws_lambda_powertools/utilities/batch/types.py b/aws_lambda_powertools/utilities/batch/types.py
index 40083537e04..d48f768a6b8 100644
--- a/aws_lambda_powertools/utilities/batch/types.py
+++ b/aws_lambda_powertools/utilities/batch/types.py
@@ -7,7 +7,7 @@
# For IntelliSense and Mypy to work, we need to account for possible SQS subclasses
# We need them as subclasses as we must access their message ID or sequence number metadata via dot notation
-if has_pydantic:
+if has_pydantic: # pragma: no cover
from aws_lambda_powertools.utilities.parser.models import DynamoDBStreamRecordModel, SqsRecordModel
from aws_lambda_powertools.utilities.parser.models import (
KinesisDataStreamRecord as KinesisDataStreamRecordModel,
@@ -17,7 +17,7 @@
Union[Type[SqsRecordModel], Type[DynamoDBStreamRecordModel], Type[KinesisDataStreamRecordModel]]
]
BatchSqsTypeModel = Optional[Type[SqsRecordModel]]
-else:
+else: # pragma: no cover
BatchTypeModels = "BatchTypeModels" # type: ignore
BatchSqsTypeModel = "BatchSqsTypeModel" # type: ignore
diff --git a/aws_lambda_powertools/utilities/data_classes/alb_event.py b/aws_lambda_powertools/utilities/data_classes/alb_event.py
index a1ee3424a94..a3fbb24f270 100644
--- a/aws_lambda_powertools/utilities/data_classes/alb_event.py
+++ b/aws_lambda_powertools/utilities/data_classes/alb_event.py
@@ -43,7 +43,7 @@ def resolved_query_string_parameters(self) -> Dict[str, List[str]]:
return super().resolved_query_string_parameters
@property
- def resolved_headers_field(self) -> Optional[Dict[str, Any]]:
+ def resolved_headers_field(self) -> Dict[str, Any]:
headers: Dict[str, Any] = {}
if self.multi_value_headers:
diff --git a/aws_lambda_powertools/utilities/data_classes/api_gateway_proxy_event.py b/aws_lambda_powertools/utilities/data_classes/api_gateway_proxy_event.py
index b8ef9c08045..48d3c96c84c 100644
--- a/aws_lambda_powertools/utilities/data_classes/api_gateway_proxy_event.py
+++ b/aws_lambda_powertools/utilities/data_classes/api_gateway_proxy_event.py
@@ -15,18 +15,18 @@
class APIGatewayEventAuthorizer(DictWrapper):
@property
- def claims(self) -> Optional[Dict[str, Any]]:
- return self.get("claims")
+ def claims(self) -> Dict[str, Any]:
+ return self.get("claims") or {} # key might exist but can be `null`
@property
- def scopes(self) -> Optional[List[str]]:
- return self.get("scopes")
+ def scopes(self) -> List[str]:
+ return self.get("scopes") or [] # key might exist but can be `null`
@property
- def principal_id(self) -> Optional[str]:
+ def principal_id(self) -> str:
"""The principal user identification associated with the token sent by the client and returned from an
API Gateway Lambda authorizer (formerly known as a custom authorizer)"""
- return self.get("principalId")
+ return self.get("principalId") or "" # key might exist but can be `null`
@property
def integration_latency(self) -> Optional[int]:
@@ -91,7 +91,8 @@ def route_key(self) -> Optional[str]:
@property
def authorizer(self) -> APIGatewayEventAuthorizer:
- return APIGatewayEventAuthorizer(self._data["requestContext"]["authorizer"])
+ authz_data = self._data.get("requestContext", {}).get("authorizer", {})
+ return APIGatewayEventAuthorizer(authz_data)
class APIGatewayProxyEvent(BaseProxyEvent):
@@ -112,11 +113,11 @@ def resource(self) -> str:
@property
def multi_value_headers(self) -> Dict[str, List[str]]:
- return self.get("multiValueHeaders") or {}
+ return self.get("multiValueHeaders") or {} # key might exist but can be `null`
@property
def multi_value_query_string_parameters(self) -> Dict[str, List[str]]:
- return self.get("multiValueQueryStringParameters") or {}
+ return self.get("multiValueQueryStringParameters") or {} # key might exist but can be `null`
@property
def resolved_query_string_parameters(self) -> Dict[str, List[str]]:
@@ -126,7 +127,7 @@ def resolved_query_string_parameters(self) -> Dict[str, List[str]]:
return super().resolved_query_string_parameters
@property
- def resolved_headers_field(self) -> Optional[Dict[str, Any]]:
+ def resolved_headers_field(self) -> Dict[str, Any]:
headers: Dict[str, Any] = {}
if self.multi_value_headers:
@@ -154,72 +155,72 @@ def header_serializer(self) -> BaseHeadersSerializer:
class RequestContextV2AuthorizerIam(DictWrapper):
@property
- def access_key(self) -> Optional[str]:
+ def access_key(self) -> str:
"""The IAM user access key associated with the request."""
- return self.get("accessKey")
+ return self.get("accessKey") or "" # key might exist but can be `null`
@property
- def account_id(self) -> Optional[str]:
+ def account_id(self) -> str:
"""The AWS account ID associated with the request."""
- return self.get("accountId")
+ return self.get("accountId") or "" # key might exist but can be `null`
@property
- def caller_id(self) -> Optional[str]:
+ def caller_id(self) -> str:
"""The principal identifier of the caller making the request."""
- return self.get("callerId")
+ return self.get("callerId") or "" # key might exist but can be `null`
def _cognito_identity(self) -> Dict:
- return self.get("cognitoIdentity", {}) or {} # not available in FunctionURL
+ return self.get("cognitoIdentity") or {} # not available in FunctionURL; key might exist but can be `null`
@property
- def cognito_amr(self) -> Optional[List[str]]:
+ def cognito_amr(self) -> List[str]:
"""This represents how the user was authenticated.
AMR stands for Authentication Methods References as per the openid spec"""
- return self._cognito_identity().get("amr")
+ return self._cognito_identity().get("amr", [])
@property
- def cognito_identity_id(self) -> Optional[str]:
+ def cognito_identity_id(self) -> str:
"""The Amazon Cognito identity ID of the caller making the request.
Available only if the request was signed with Amazon Cognito credentials."""
- return self._cognito_identity().get("identityId")
+ return self._cognito_identity().get("identityId", "")
@property
- def cognito_identity_pool_id(self) -> Optional[str]:
+ def cognito_identity_pool_id(self) -> str:
"""The Amazon Cognito identity pool ID of the caller making the request.
Available only if the request was signed with Amazon Cognito credentials."""
- return self._cognito_identity().get("identityPoolId")
+ return self._cognito_identity().get("identityPoolId") or "" # key might exist but can be `null`
@property
- def principal_org_id(self) -> Optional[str]:
+ def principal_org_id(self) -> str:
"""The AWS organization ID."""
- return self.get("principalOrgId")
+ return self.get("principalOrgId") or "" # key might exist but can be `null`
@property
- def user_arn(self) -> Optional[str]:
+ def user_arn(self) -> str:
"""The Amazon Resource Name (ARN) of the effective user identified after authentication."""
- return self.get("userArn")
+ return self.get("userArn") or "" # key might exist but can be `null`
@property
- def user_id(self) -> Optional[str]:
+ def user_id(self) -> str:
"""The IAM user ID of the effective user identified after authentication."""
- return self.get("userId")
+ return self.get("userId") or "" # key might exist but can be `null`
class RequestContextV2Authorizer(DictWrapper):
@property
- def jwt_claim(self) -> Optional[Dict[str, Any]]:
- jwt = self.get("jwt") or {} # not available in FunctionURL
- return jwt.get("claims")
+ def jwt_claim(self) -> Dict[str, Any]:
+ jwt = self.get("jwt") or {} # not available in FunctionURL; key might exist but can be `null`
+ return jwt.get("claims") or {} # key might exist but can be `null`
@property
- def jwt_scopes(self) -> Optional[List[str]]:
- jwt = self.get("jwt") or {} # not available in FunctionURL
- return jwt.get("scopes")
+ def jwt_scopes(self) -> List[str]:
+ jwt = self.get("jwt") or {} # not available in FunctionURL; key might exist but can be `null`
+ return jwt.get("scopes", [])
@property
- def get_lambda(self) -> Optional[Dict[str, Any]]:
+ def get_lambda(self) -> Dict[str, Any]:
"""Lambda authorization context details"""
- return self.get("lambda")
+ return self.get("lambda") or {} # key might exist but can be `null`
def get_context(self) -> Dict[str, Any]:
"""Retrieve the authorization context details injected by a Lambda Authorizer.
@@ -238,20 +239,20 @@ def get_context(self) -> Dict[str, Any]:
Dict[str, Any]
A dictionary containing Lambda authorization context details.
"""
- return self.get("lambda", {}) or {}
+ return self.get_lambda
@property
- def iam(self) -> Optional[RequestContextV2AuthorizerIam]:
+ def iam(self) -> RequestContextV2AuthorizerIam:
"""IAM authorization details used for making the request."""
- iam = self.get("iam")
- return None if iam is None else RequestContextV2AuthorizerIam(iam)
+ iam = self.get("iam") or {} # key might exist but can be `null`
+ return RequestContextV2AuthorizerIam(iam)
class RequestContextV2(BaseRequestContextV2):
@property
- def authorizer(self) -> Optional[RequestContextV2Authorizer]:
- authorizer = self["requestContext"].get("authorizer")
- return None if authorizer is None else RequestContextV2Authorizer(authorizer)
+ def authorizer(self) -> RequestContextV2Authorizer:
+ ctx = self.get("requestContext") or {} # key might exist but can be `null`
+ return RequestContextV2Authorizer(ctx.get("authorizer", {}))
class APIGatewayProxyEventV2(BaseProxyEvent):
@@ -319,7 +320,7 @@ def header_serializer(self):
return HttpApiHeadersSerializer()
@property
- def resolved_headers_field(self) -> Optional[Dict[str, Any]]:
+ def resolved_headers_field(self) -> Dict[str, Any]:
if self.headers is not None:
headers = {key.lower(): value.split(",") if "," in value else value for key, value in self.headers.items()}
return headers
diff --git a/aws_lambda_powertools/utilities/data_classes/bedrock_agent_event.py b/aws_lambda_powertools/utilities/data_classes/bedrock_agent_event.py
index 45f3cd81f1f..4c404c73111 100644
--- a/aws_lambda_powertools/utilities/data_classes/bedrock_agent_event.py
+++ b/aws_lambda_powertools/utilities/data_classes/bedrock_agent_event.py
@@ -111,7 +111,7 @@ def query_string_parameters(self) -> Optional[Dict[str, str]]:
return {x["name"]: x["value"] for x in self["parameters"]} if self.get("parameters") else None
@property
- def resolved_headers_field(self) -> Optional[Dict[str, Any]]:
+ def resolved_headers_field(self) -> Dict[str, Any]:
return {}
@cached_property
diff --git a/aws_lambda_powertools/utilities/data_classes/common.py b/aws_lambda_powertools/utilities/data_classes/common.py
index b78a6e4939c..76726ca5129 100644
--- a/aws_lambda_powertools/utilities/data_classes/common.py
+++ b/aws_lambda_powertools/utilities/data_classes/common.py
@@ -124,7 +124,7 @@ def resolved_query_string_parameters(self) -> Dict[str, List[str]]:
return {}
@property
- def resolved_headers_field(self) -> Optional[Dict[str, Any]]:
+ def resolved_headers_field(self) -> Dict[str, Any]:
"""
This property determines the appropriate header to be used
as a trusted source for validating OpenAPI.
diff --git a/aws_lambda_powertools/utilities/data_classes/s3_event.py b/aws_lambda_powertools/utilities/data_classes/s3_event.py
index 802f1663edb..1a6f9c541a3 100644
--- a/aws_lambda_powertools/utilities/data_classes/s3_event.py
+++ b/aws_lambda_powertools/utilities/data_classes/s3_event.py
@@ -32,14 +32,14 @@ def key(self) -> str:
return unquote_plus(self["key"])
@property
- def size(self) -> str:
- """Object size"""
- return self["size"]
+ def size(self) -> Optional[int]:
+ """Object size. Object deletion event doesn't contain size."""
+ return self.get("size")
@property
def etag(self) -> str:
- """Object etag"""
- return self["etag"]
+ """Object etag. Object deletion event doesn't contain etag; we default to empty string"""
+ return self.get("etag", "") # type: ignore[return-value] # false positive
@property
def version_id(self) -> str:
@@ -178,8 +178,8 @@ def size(self) -> int:
@property
def etag(self) -> str:
- """object eTag"""
- return self["s3"]["object"]["eTag"]
+ """Object eTag. Object deletion event doesn't contain eTag; we default to empty string"""
+ return self["s3"]["object"].get("eTag", "")
@property
def version_id(self) -> Optional[str]:
diff --git a/aws_lambda_powertools/utilities/data_classes/vpc_lattice.py b/aws_lambda_powertools/utilities/data_classes/vpc_lattice.py
index 3fe9762fcd7..c28977c56ba 100644
--- a/aws_lambda_powertools/utilities/data_classes/vpc_lattice.py
+++ b/aws_lambda_powertools/utilities/data_classes/vpc_lattice.py
@@ -145,7 +145,7 @@ def query_string_parameters(self) -> Dict[str, str]:
return self["query_string_parameters"]
@property
- def resolved_headers_field(self) -> Optional[Dict[str, Any]]:
+ def resolved_headers_field(self) -> Dict[str, Any]:
if self.headers is not None:
headers = {key.lower(): value.split(",") if "," in value else value for key, value in self.headers.items()}
return headers
@@ -272,7 +272,7 @@ def query_string_parameters(self) -> Optional[Dict[str, str]]:
return None
@property
- def resolved_headers_field(self) -> Optional[Dict[str, str]]:
+ def resolved_headers_field(self) -> Dict[str, str]:
if self.headers is not None:
return {key.lower(): value for key, value in self.headers.items()}
diff --git a/aws_lambda_powertools/utilities/data_masking/__init__.py b/aws_lambda_powertools/utilities/data_masking/__init__.py
index 4d767e83ce1..428cea6635d 100644
--- a/aws_lambda_powertools/utilities/data_masking/__init__.py
+++ b/aws_lambda_powertools/utilities/data_masking/__init__.py
@@ -1,9 +1,3 @@
-"""
- Note: This utility is currently in a Non-General Availability (Non-GA) phase and may have limitations.
- Please DON'T USE THIS utility in production environments.
- Keep in mind that when we transition to General Availability (GA), there might be breaking changes introduced.
-"""
-
from aws_lambda_powertools.utilities.data_masking.base import DataMasking
__all__ = [
diff --git a/aws_lambda_powertools/utilities/data_masking/base.py b/aws_lambda_powertools/utilities/data_masking/base.py
index 5274aac3b8a..bf5842a70fb 100644
--- a/aws_lambda_powertools/utilities/data_masking/base.py
+++ b/aws_lambda_powertools/utilities/data_masking/base.py
@@ -19,10 +19,6 @@
class DataMasking:
"""
- Note: This utility is currently in a Non-General Availability (Non-GA) phase and may have limitations.
- Please DON'T USE THIS utility in production environments.
- Keep in mind that when we transition to General Availability (GA), there might be breaking changes introduced.
-
The DataMasking class orchestrates erasing, encrypting, and decrypting
for the base provider.
diff --git a/aws_lambda_powertools/utilities/parser/compat.py b/aws_lambda_powertools/utilities/parser/compat.py
index c73098421b1..c76bc6546a5 100644
--- a/aws_lambda_powertools/utilities/parser/compat.py
+++ b/aws_lambda_powertools/utilities/parser/compat.py
@@ -22,7 +22,7 @@ def disable_pydantic_v2_warning():
version = __version__.split(".")
- if int(version[0]) == 2:
+ if int(version[0]) == 2: # pragma: no cover # dropping in v3
import warnings
from pydantic import PydanticDeprecatedSince20, PydanticDeprecationWarning
@@ -30,5 +30,5 @@ def disable_pydantic_v2_warning():
warnings.filterwarnings("ignore", category=PydanticDeprecationWarning)
warnings.filterwarnings("ignore", category=PydanticDeprecatedSince20)
- except ImportError:
+ except ImportError: # pragma: no cover # false positive; dropping in v3
pass
diff --git a/aws_lambda_powertools/utilities/parser/models/s3.py b/aws_lambda_powertools/utilities/parser/models/s3.py
index db6c41d30f3..cb5df44e193 100644
--- a/aws_lambda_powertools/utilities/parser/models/s3.py
+++ b/aws_lambda_powertools/utilities/parser/models/s3.py
@@ -61,7 +61,7 @@ class S3Message(BaseModel):
class S3EventNotificationObjectModel(BaseModel):
key: str
size: Optional[NonNegativeFloat] = None
- etag: str
+ etag: str = Field(default="")
version_id: str = Field(None, alias="version-id")
sequencer: Optional[str] = None
diff --git a/docs/Dockerfile b/docs/Dockerfile
index 3ad824e399b..045e92a898c 100644
--- a/docs/Dockerfile
+++ b/docs/Dockerfile
@@ -1,5 +1,5 @@
# v9.1.18
-FROM squidfunk/mkdocs-material@sha256:e3090898189e428f51f46faa2a59c90765abf8304fe4d2d2c401199d170cd991
+FROM squidfunk/mkdocs-material@sha256:5358893a04dc6ed0e267ef1c0c06abc5d6b00d13dd0fee703c978ef98d56fd53
# pip-compile --generate-hashes --output-file=requirements.txt requirements.in
COPY requirements.txt /tmp/
RUN pip install --require-hashes -r /tmp/requirements.txt
diff --git a/docs/core/event_handler/api_gateway.md b/docs/core/event_handler/api_gateway.md
index aaf9352ebc0..aa667f5f169 100644
--- a/docs/core/event_handler/api_gateway.md
+++ b/docs/core/event_handler/api_gateway.md
@@ -221,7 +221,7 @@ You can use named decorators to specify the HTTP method that should be handled i
--8<-- "examples/event_handler_rest/src/http_methods.json"
```
-If you need to accept multiple HTTP methods in a single function, you can use the `route` method and pass a list of HTTP methods.
+If you need to accept multiple HTTP methods in a single function, or support a HTTP method for which no decorator exists (e.g. [TRACE](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/TRACE)), you can use the `route` method and pass a list of HTTP methods.
```python hl_lines="15" title="Handling multiple HTTP Methods"
--8<-- "examples/event_handler_rest/src/http_methods_multiple.py"
@@ -524,12 +524,13 @@ Behind the scenes, the [data validation](#data-validation) feature auto-generate
There are some important **caveats** that you should know before enabling it:
-| Caveat | Description |
-| ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| Swagger UI is **publicly accessible by default** | When using `enable_swagger` method, you can [protect sensitive API endpoints by implementing a custom middleware](#customizing-swagger-ui) using your preferred authorization mechanism. |
-| **No micro-functions support** yet | Swagger UI is enabled on a per resolver instance which will limit its accuracy here. |
-| You need to expose a **new route** | You'll need to expose the following path to Lambda: `/swagger`; ignore if you're routing this path already. |
-| JS and CSS files are **embedded within Swagger HTML** | If you are not using an external CDN to serve Swagger UI assets, we embed JS and CSS directly into the HTML. To enhance performance, please consider enabling the `compress` option to minimize the size of HTTP requests. |
+| Caveat | Description |
+| ------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| Swagger UI is **publicly accessible by default** | When using `enable_swagger` method, you can [protect sensitive API endpoints by implementing a custom middleware](#customizing-swagger-ui) using your preferred authorization mechanism. |
+| **No micro-functions support** yet | Swagger UI is enabled on a per resolver instance which will limit its accuracy here. |
+| You need to expose a **new route** | You'll need to expose the following path to Lambda: `/swagger`; ignore if you're routing this path already. |
+| JS and CSS files are **embedded within Swagger HTML** | If you are not using an external CDN to serve Swagger UI assets, we embed JS and CSS directly into the HTML. To enhance performance, please consider enabling the `compress` option to minimize the size of HTTP requests. |
+| Authorization data is **lost** on browser close/refresh | Use `enable_swagger(persist_authorization=True)` to persist authorization data, like OAuath 2.0 access tokens. |
```python hl_lines="12-13" title="enabling_swagger.py"
--8<-- "examples/event_handler_rest/src/enabling_swagger.py"
@@ -835,8 +836,8 @@ As a practical example, let's refactor our correlation ID middleware so it accep
These are native middlewares that may become native features depending on customer demand.
-| Middleware | Purpose |
-| ------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
+| Middleware | Purpose |
+| ------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| [SchemaValidationMiddleware](/lambda/python/latest/api/event_handler/middlewares/schema_validation.html){target="_blank"} | Validates API request body and response against JSON Schema, using [Validation utility](../../utilities/validation.md){target="_blank"} |
#### Being a good citizen
@@ -1053,7 +1054,7 @@ When you're describing your API, declare security schemes at the top level, and
OpenAPI 3 lets you describe APIs protected using the following security schemes:
| Security Scheme | Type | Description |
-|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [HTTP auth](https://www.iana.org/assignments/http-authschemes/http-authschemes.xhtml){target="_blank"} | `HTTPBase` | HTTP authentication schemes using the Authorization header (e.g: [Basic auth](https://swagger.io/docs/specification/authentication/basic-authentication/){target="_blank"}, [Bearer](https://swagger.io/docs/specification/authentication/bearer-authentication/){target="_blank"}) |
| [API keys](https://swagger.io/docs/specification/authentication/api-keys/https://swagger.io/docs/specification/authentication/api-keys/){target="_blank"} (e.g: query strings, cookies) | `APIKey` | API keys in headers, query strings or [cookies](https://swagger.io/docs/specification/authentication/cookie-authentication/){target="_blank"}. |
| [OAuth 2](https://swagger.io/docs/specification/authentication/oauth2/){target="_blank"} | `OAuth2` | Authorization protocol that gives an API client limited access to user data on a web server. |
diff --git a/docs/core/logger.md b/docs/core/logger.md
index bf600e285ca..b48adb7034b 100644
--- a/docs/core/logger.md
+++ b/docs/core/logger.md
@@ -475,9 +475,9 @@ You can use any of the following built-in JMESPath expressions as part of [injec
### Reusing Logger across your code
-Similar to [Tracer](./tracer.md#reusing-tracer-across-your-code){target="_blank"}, a new instance that uses the same `service` name - env var or explicit parameter - will reuse a previous Logger instance. Just like `logging.getLogger("logger_name")` would in the standard library if called with the same logger name.
+Similar to [Tracer](./tracer.md#reusing-tracer-across-your-code){target="_blank"}, a new instance that uses the same `service` name will reuse a previous Logger instance.
-Notice in the CloudWatch Logs output how `payment_id` appeared as expected when logging in `collect.py`.
+Notice in the CloudWatch Logs output how `payment_id` appears as expected when logging in `collect.py`.
=== "logger_reuse.py"
@@ -496,7 +496,6 @@ Notice in the CloudWatch Logs output how `payment_id` appeared as expected when
```json hl_lines="12"
--8<-- "examples/logger/src/logger_reuse_output.json"
```
-
???+ note "Note: About Child Loggers"
Coming from standard library, you might be used to use `logging.getLogger(__name__)`. This will create a new instance of a Logger with a different name.
@@ -595,7 +594,6 @@ For Logger, the `service` is the logging key customers can use to search log ope
??? tip "Tip: Prefer [Logger Reuse feature](#reusing-logger-across-your-code) over inheritance unless strictly necessary, [see caveats.](#reusing-logger-across-your-code)"
> Python Logging hierarchy happens via the dot notation: `service`, `service.child`, `service.child_2`
-
For inheritance, Logger uses a `child=True` parameter along with `service` being the same value across Loggers.
For child Loggers, we introspect the name of your module where `Logger(child=True, service="name")` is called, and we name your Logger as **{service}.{filename}**.
@@ -610,7 +608,6 @@ For child Loggers, we introspect the name of your module where `Logger(child=Tru
```
=== "logging_inheritance_module.py"
-
```python hl_lines="1 9"
--8<-- "examples/logger/src/logging_inheritance_module.py"
```
@@ -816,10 +813,11 @@ for the given name and level to the logging module. By default, this logs all bo
You can copy the Logger setup to all or sub-sets of registered external loggers. Use the `copy_config_to_registered_logger` method to do this.
-???+ tip
- To help differentiate between loggers, we include the standard logger `name` attribute for all loggers we copied configuration to.
+!!! tip "We include the logger `name` attribute for all loggers we copied configuration to help you differentiate them."
+
+By default all registered loggers will be modified. You can change this behavior by providing `include` and `exclude` attributes.
-By default all registered loggers will be modified. You can change this behavior by providing `include` and `exclude` attributes. You can also provide optional `log_level` attribute external loggers will be configured with.
+You can also provide optional `log_level` attribute external top-level loggers will be configured with, by default it'll use the source logger log level. You can opt-out by using `ignore_log_level=True` parameter.
```python hl_lines="10" title="Cloning Logger config to all other registered standard loggers"
---8<-- "examples/logger/src/cloning_logger_config.py"
diff --git a/docs/index.md b/docs/index.md
index 88367b3c4ec..660bbe71c3f 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -67,8 +67,8 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc
For the latter, make sure to replace `{region}` with your AWS region, e.g., `eu-west-1`.
- * x86 architecture: __arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:69__{: .copyMe}:clipboard:
- * ARM architecture: __arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:69__{: .copyMe}:clipboard:
+ * x86 architecture: __arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:71__{: .copyMe}:clipboard:
+ * ARM architecture: __arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:71__{: .copyMe}:clipboard:
???+ note "Code snippets for popular infrastructure as code frameworks"
@@ -76,310 +76,76 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc
=== "SAM"
- ```yaml hl_lines="5"
- MyLambdaFunction:
- Type: AWS::Serverless::Function
- Properties:
- Layers:
- - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:69
+ ```yaml hl_lines="11"
+ --8<-- "examples/homepage/install/x86_64/sam.yaml"
```
=== "Serverless framework"
- ```yaml hl_lines="5"
- functions:
- hello:
- handler: lambda_function.lambda_handler
- layers:
- - arn:aws:lambda:${aws:region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:69
+ ```yaml hl_lines="13"
+ --8<-- "examples/homepage/install/x86_64/serverless.yml"
```
=== "CDK"
- ```python hl_lines="11 16"
- from aws_cdk import core, aws_lambda
-
- class SampleApp(core.Construct):
-
- def __init__(self, scope: core.Construct, id_: str, env: core.Environment) -> None:
- super().__init__(scope, id_)
-
- powertools_layer = aws_lambda.LayerVersion.from_layer_version_arn(
- self,
- id="lambda-powertools",
- layer_version_arn=f"arn:aws:lambda:{env.region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:69"
- )
- aws_lambda.Function(self,
- 'sample-app-lambda',
- runtime=aws_lambda.Runtime.PYTHON_3_9,
- layers=[powertools_layer]
- # other props...
- )
+ ```python hl_lines="13 19"
+ --8<-- "examples/homepage/install/x86_64/cdk.py"
```
=== "Terraform"
- ```terraform hl_lines="9 38"
- terraform {
- required_version = "~> 1.0.5"
- required_providers {
- aws = "~> 3.50.0"
- }
- }
-
- provider "aws" {
- region = "{region}"
- }
-
- resource "aws_iam_role" "iam_for_lambda" {
- name = "iam_for_lambda"
-
- assume_role_policy = <
- ? Choose the runtime that you want to use: Python
- ? Do you want to configure advanced settings? Yes
- ...
- ? Do you want to enable Lambda layers for this function? Yes
- ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:69
- ❯ amplify push -y
-
-
- # Updating an existing function and add the layer
- ❯ amplify update function
- ? Select the Lambda function you want to update test2
- General information
- - Name:
- ? Which setting do you want to update? Lambda layers configuration
- ? Do you want to enable Lambda layers for this function? Yes
- ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:69
- ? Do you want to edit the local lambda function now? No
+ ```zsh hl_lines="9"
+ --8<-- "examples/homepage/install/x86_64/amplify.txt"
```
=== "arm64"
=== "SAM"
- ```yaml hl_lines="6"
- MyLambdaFunction:
- Type: AWS::Serverless::Function
- Properties:
- Architectures: [arm64]
- Layers:
- - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:69
+ ```yaml hl_lines="12"
+ --8<-- "examples/homepage/install/arm64/sam.yaml"
```
=== "Serverless framework"
- ```yaml hl_lines="6"
- functions:
- hello:
- handler: lambda_function.lambda_handler
- architecture: arm64
- layers:
- - arn:aws:lambda:${aws:region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:69
+ ```yaml hl_lines="13"
+ --8<-- "examples/homepage/install/arm64/serverless.yml"
```
=== "CDK"
- ```python hl_lines="11 17"
- from aws_cdk import core, aws_lambda
-
- class SampleApp(core.Construct):
-
- def __init__(self, scope: core.Construct, id_: str, env: core.Environment) -> None:
- super().__init__(scope, id_)
-
- powertools_layer = aws_lambda.LayerVersion.from_layer_version_arn(
- self,
- id="lambda-powertools",
- layer_version_arn=f"arn:aws:lambda:{env.region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:69"
- )
- aws_lambda.Function(self,
- 'sample-app-lambda',
- runtime=aws_lambda.Runtime.PYTHON_3_9,
- architecture=aws_lambda.Architecture.ARM_64,
- layers=[powertools_layer]
- # other props...
- )
+ ```python hl_lines="13 19"
+ --8<-- "examples/homepage/install/arm64/cdk.py"
```
=== "Terraform"
```terraform hl_lines="9 37"
- terraform {
- required_version = "~> 1.0.5"
- required_providers {
- aws = "~> 3.50.0"
- }
- }
-
- provider "aws" {
- region = "{region}"
- }
-
- resource "aws_iam_role" "iam_for_lambda" {
- name = "iam_for_lambda"
-
- assume_role_policy = <
- ? Choose the runtime that you want to use: Python
- ? Do you want to configure advanced settings? Yes
- ...
- ? Do you want to enable Lambda layers for this function? Yes
- ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:69
- ❯ amplify push -y
-
-
- # Updating an existing function and add the layer
- ❯ amplify update function
- ? Select the Lambda function you want to update test2
- General information
- - Name:
- ? Which setting do you want to update? Lambda layers configuration
- ? Do you want to enable Lambda layers for this function? Yes
- ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:69
- ? Do you want to edit the local lambda function now? No
+ ```zsh hl_lines="9"
+ --8<-- "examples/homepage/install/arm64/amplify.txt"
```
### Local development
@@ -409,74 +175,74 @@ In this context, `[aws-sdk]` is an alias to the `boto3` package. Due to dependen
| Region | Layer ARN |
| -------------------- | --------------------------------------------------------------------------------------------------------- |
- | **`af-south-1`** | **arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:69**{: .copyMe}:clipboard: |
- | **`ap-east-1`** | **arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:69**{: .copyMe}:clipboard: |
- | **`ap-northeast-1`** | **arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:69**{: .copyMe}:clipboard: |
- | **`ap-northeast-2`** | **arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:69**{: .copyMe}:clipboard: |
- | **`ap-northeast-3`** | **arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:69**{: .copyMe}:clipboard: |
- | **`ap-south-1`** | **arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:69**{: .copyMe}:clipboard: |
- | **`ap-south-2`** | **arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:69**{: .copyMe}:clipboard: |
- | **`ap-southeast-1`** | **arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:69**{: .copyMe}:clipboard: |
- | **`ap-southeast-2`** | **arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:69**{: .copyMe}:clipboard: |
- | **`ap-southeast-3`** | **arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:69**{: .copyMe}:clipboard: |
- | **`ap-southeast-4`** | **arn:aws:lambda:ap-southeast-4:017000801446:layer:AWSLambdaPowertoolsPythonV2:69**{: .copyMe}:clipboard: |
- | **`ca-central-1`** | **arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:69**{: .copyMe}:clipboard: |
- | **`ca-west-1`** | **arn:aws:lambda:ca-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:69**{: .copyMe}:clipboard: |
- | **`eu-central-1`** | **arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:69**{: .copyMe}:clipboard: |
- | **`eu-central-2`** | **arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:69**{: .copyMe}:clipboard: |
- | **`eu-north-1`** | **arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:69**{: .copyMe}:clipboard: |
- | **`eu-south-1`** | **arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:69**{: .copyMe}:clipboard: |
- | **`eu-south-2`** | **arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:69**{: .copyMe}:clipboard: |
- | **`eu-west-1`** | **arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:69**{: .copyMe}:clipboard: |
- | **`eu-west-2`** | **arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:69**{: .copyMe}:clipboard: |
- | **`eu-west-3`** | **arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:69**{: .copyMe}:clipboard: |
- | **`il-central-1`** | **arn:aws:lambda:il-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:69**{: .copyMe}:clipboard: |
- | **`me-central-1`** | **arn:aws:lambda:me-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:69**{: .copyMe}:clipboard: |
- | **`me-south-1`** | **arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:69**{: .copyMe}:clipboard: |
- | **`sa-east-1`** | **arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:69**{: .copyMe}:clipboard: |
- | **`us-east-1`** | **arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:69**{: .copyMe}:clipboard: |
- | **`us-east-2`** | **arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:69**{: .copyMe}:clipboard: |
- | **`us-west-1`** | **arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:69**{: .copyMe}:clipboard: |
- | **`us-west-2`** | **arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:69**{: .copyMe}:clipboard: |
+ | **`af-south-1`** | **arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:71**{: .copyMe}:clipboard: |
+ | **`ap-east-1`** | **arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:71**{: .copyMe}:clipboard: |
+ | **`ap-northeast-1`** | **arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:71**{: .copyMe}:clipboard: |
+ | **`ap-northeast-2`** | **arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:71**{: .copyMe}:clipboard: |
+ | **`ap-northeast-3`** | **arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:71**{: .copyMe}:clipboard: |
+ | **`ap-south-1`** | **arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:71**{: .copyMe}:clipboard: |
+ | **`ap-south-2`** | **arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:71**{: .copyMe}:clipboard: |
+ | **`ap-southeast-1`** | **arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:71**{: .copyMe}:clipboard: |
+ | **`ap-southeast-2`** | **arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:71**{: .copyMe}:clipboard: |
+ | **`ap-southeast-3`** | **arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:71**{: .copyMe}:clipboard: |
+ | **`ap-southeast-4`** | **arn:aws:lambda:ap-southeast-4:017000801446:layer:AWSLambdaPowertoolsPythonV2:71**{: .copyMe}:clipboard: |
+ | **`ca-central-1`** | **arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:71**{: .copyMe}:clipboard: |
+ | **`ca-west-1`** | **arn:aws:lambda:ca-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:71**{: .copyMe}:clipboard: |
+ | **`eu-central-1`** | **arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:71**{: .copyMe}:clipboard: |
+ | **`eu-central-2`** | **arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:71**{: .copyMe}:clipboard: |
+ | **`eu-north-1`** | **arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:71**{: .copyMe}:clipboard: |
+ | **`eu-south-1`** | **arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:71**{: .copyMe}:clipboard: |
+ | **`eu-south-2`** | **arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:71**{: .copyMe}:clipboard: |
+ | **`eu-west-1`** | **arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:71**{: .copyMe}:clipboard: |
+ | **`eu-west-2`** | **arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:71**{: .copyMe}:clipboard: |
+ | **`eu-west-3`** | **arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:71**{: .copyMe}:clipboard: |
+ | **`il-central-1`** | **arn:aws:lambda:il-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:71**{: .copyMe}:clipboard: |
+ | **`me-central-1`** | **arn:aws:lambda:me-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:71**{: .copyMe}:clipboard: |
+ | **`me-south-1`** | **arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:71**{: .copyMe}:clipboard: |
+ | **`sa-east-1`** | **arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:71**{: .copyMe}:clipboard: |
+ | **`us-east-1`** | **arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:71**{: .copyMe}:clipboard: |
+ | **`us-east-2`** | **arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:71**{: .copyMe}:clipboard: |
+ | **`us-west-1`** | **arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:71**{: .copyMe}:clipboard: |
+ | **`us-west-2`** | **arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:71**{: .copyMe}:clipboard: |
=== "arm64"
| Region | Layer ARN |
| -------------------- | --------------------------------------------------------------------------------------------------------------- |
- | **`af-south-1`** | **arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:69**{: .copyMe}:clipboard: |
- | **`ap-east-1`** | **arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:69**{: .copyMe}:clipboard: |
- | **`ap-northeast-1`** | **arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:69**{: .copyMe}:clipboard: |
- | **`ap-northeast-2`** | **arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:69**{: .copyMe}:clipboard: |
- | **`ap-northeast-3`** | **arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:69**{: .copyMe}:clipboard: |
- | **`ap-south-1`** | **arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:69**{: .copyMe}:clipboard: |
- | **`ap-south-2`** | **arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:69**{: .copyMe}:clipboard: |
- | **`ap-southeast-1`** | **arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:69**{: .copyMe}:clipboard: |
- | **`ap-southeast-2`** | **arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:69**{: .copyMe}:clipboard: |
- | **`ap-southeast-3`** | **arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:69**{: .copyMe}:clipboard: |
- | **`ca-central-1`** | **arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:69**{: .copyMe}:clipboard: |
- | **`eu-central-1`** | **arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:69**{: .copyMe}:clipboard: |
- | **`eu-central-2`** | **arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:69**{: .copyMe}:clipboard: |
- | **`eu-north-1`** | **arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:69**{: .copyMe}:clipboard: |
- | **`eu-south-1`** | **arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:69**{: .copyMe}:clipboard: |
- | **`eu-south-2`** | **arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:69**{: .copyMe}:clipboard: |
- | **`eu-west-1`** | **arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:69**{: .copyMe}:clipboard: |
- | **`eu-west-2`** | **arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:69**{: .copyMe}:clipboard: |
- | **`eu-west-3`** | **arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:69**{: .copyMe}:clipboard: |
- | **`il-central-1`** | **arn:aws:lambda:il-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:69**{: .copyMe}:clipboard: |
- | **`me-central-1`** | **arn:aws:lambda:me-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:69**{: .copyMe}:clipboard: |
- | **`me-south-1`** | **arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:69**{: .copyMe}:clipboard: |
- | **`sa-east-1`** | **arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:69**{: .copyMe}:clipboard: |
- | **`us-east-1`** | **arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:69**{: .copyMe}:clipboard: |
- | **`us-east-2`** | **arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:69**{: .copyMe}:clipboard: |
- | **`us-west-1`** | **arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:69**{: .copyMe}:clipboard: |
- | **`us-west-2`** | **arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:69**{: .copyMe}:clipboard: |
+ | **`af-south-1`** | **arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:71**{: .copyMe}:clipboard: |
+ | **`ap-east-1`** | **arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:71**{: .copyMe}:clipboard: |
+ | **`ap-northeast-1`** | **arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:71**{: .copyMe}:clipboard: |
+ | **`ap-northeast-2`** | **arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:71**{: .copyMe}:clipboard: |
+ | **`ap-northeast-3`** | **arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:71**{: .copyMe}:clipboard: |
+ | **`ap-south-1`** | **arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:71**{: .copyMe}:clipboard: |
+ | **`ap-south-2`** | **arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:71**{: .copyMe}:clipboard: |
+ | **`ap-southeast-1`** | **arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:71**{: .copyMe}:clipboard: |
+ | **`ap-southeast-2`** | **arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:71**{: .copyMe}:clipboard: |
+ | **`ap-southeast-3`** | **arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:71**{: .copyMe}:clipboard: |
+ | **`ca-central-1`** | **arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:71**{: .copyMe}:clipboard: |
+ | **`eu-central-1`** | **arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:71**{: .copyMe}:clipboard: |
+ | **`eu-central-2`** | **arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:71**{: .copyMe}:clipboard: |
+ | **`eu-north-1`** | **arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:71**{: .copyMe}:clipboard: |
+ | **`eu-south-1`** | **arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:71**{: .copyMe}:clipboard: |
+ | **`eu-south-2`** | **arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:71**{: .copyMe}:clipboard: |
+ | **`eu-west-1`** | **arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:71**{: .copyMe}:clipboard: |
+ | **`eu-west-2`** | **arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:71**{: .copyMe}:clipboard: |
+ | **`eu-west-3`** | **arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:71**{: .copyMe}:clipboard: |
+ | **`il-central-1`** | **arn:aws:lambda:il-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:71**{: .copyMe}:clipboard: |
+ | **`me-central-1`** | **arn:aws:lambda:me-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:71**{: .copyMe}:clipboard: |
+ | **`me-south-1`** | **arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:71**{: .copyMe}:clipboard: |
+ | **`sa-east-1`** | **arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:71**{: .copyMe}:clipboard: |
+ | **`us-east-1`** | **arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:71**{: .copyMe}:clipboard: |
+ | **`us-east-2`** | **arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:71**{: .copyMe}:clipboard: |
+ | **`us-west-1`** | **arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:71**{: .copyMe}:clipboard: |
+ | **`us-west-2`** | **arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:71**{: .copyMe}:clipboard: |
**Want to inspect the contents of the Layer?**
The pre-signed URL to download this Lambda Layer will be within `Location` key in the CLI output. The CLI output will also contain the Powertools for AWS Lambda version it contains.
```bash title="AWS CLI command to download Lambda Layer content"
-aws lambda get-layer-version-by-arn --arn arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:69 --region eu-west-1
+aws lambda get-layer-version-by-arn --arn arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:71 --region eu-west-1
```
#### SAR
@@ -496,78 +262,20 @@ Compared with the [public Layer ARN](#lambda-layer) option, SAR allows you to ch
=== "SAM"
- ```yaml hl_lines="5-6 12-13"
- AwsLambdaPowertoolsPythonLayer:
- Type: AWS::Serverless::Application
- Properties:
- Location:
- ApplicationId: arn:aws:serverlessrepo:eu-west-1:057560766410:applications/aws-lambda-powertools-python-layer
- SemanticVersion: 2.0.0 # 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
+ ```yaml hl_lines="6 9 10 17-19"
+ --8<-- "examples/homepage/install/sar/sam.yaml"
```
=== "Serverless framework"
- ```yaml hl_lines="5 8 10-11"
- functions:
- main:
- handler: lambda_function.lambda_handler
- layers:
- - !GetAtt AwsLambdaPowertoolsPythonLayer.Outputs.LayerVersionArn
-
- resources:
- Transform: AWS::Serverless-2016-10-31
- Resources:****
- 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/aws-powertools/powertools-lambda-python/releases
- SemanticVersion: 2.0.0
+ ```yaml hl_lines="11 12 19 20"
+ --8<-- "examples/homepage/install/sar/serverless.yml"
```
=== "CDK"
- ```python hl_lines="14 22-23 31"
- from aws_cdk import core, aws_sam as sam, aws_lambda
-
- POWERTOOLS_BASE_NAME = 'AWSLambdaPowertools'
- # Find latest from github.com/aws-powertools/powertools-lambda-python/releases
- POWERTOOLS_VER = '2.0.0'
- POWERTOOLS_ARN = 'arn:aws:serverlessrepo:eu-west-1:057560766410:applications/aws-lambda-powertools-python-layer'
-
- class SampleApp(core.Construct):
-
- def __init__(self, scope: core.Construct, id_: str) -> None:
- super().__init__(scope, id_)
-
- # Launches SAR App as CloudFormation nested stack and return Lambda Layer
- powertools_app = sam.CfnApplication(self,
- f'{POWERTOOLS_BASE_NAME}Application',
- location={
- 'applicationId': POWERTOOLS_ARN,
- 'semanticVersion': POWERTOOLS_VER
- },
- )
-
- powertools_layer_arn = powertools_app.get_att("Outputs.LayerVersionArn").to_string()
- powertools_layer_version = aws_lambda.LayerVersion.from_layer_version_arn(self, f'{POWERTOOLS_BASE_NAME}', powertools_layer_arn)
-
- aws_lambda.Function(self,
- 'sample-app-lambda',
- runtime=aws_lambda.Runtime.PYTHON_3_8,
- function_name='sample-lambda',
- code=aws_lambda.Code.asset('./src'),
- handler='app.handler',
- layers: [powertools_layer_version]
- )
+ ```python hl_lines="7 16-20 23-27"
+ --8<-- "examples/homepage/install/sar/cdk.py"
```
=== "Terraform"
@@ -575,106 +283,13 @@ Compared with the [public Layer ARN](#lambda-layer) option, SAR allows you to ch
> Credits to [Dani Comnea](https://github.com/DanyC97){target="_blank" rel="nofollow"} for providing the Terraform equivalent.
```terraform hl_lines="12-13 15-20 23-25 40"
- terraform {
- required_version = "~> 0.13"
- required_providers {
- aws = "~> 3.50.0"
- }
- }
-
- provider "aws" {
- region = "us-east-1"
- }
-
- resource "aws_serverlessapplicationrepository_cloudformation_stack" "deploy_sar_stack" {
- name = "aws-lambda-powertools-python-layer"
-
- application_id = data.aws_serverlessapplicationrepository_application.sar_app.application_id
- semantic_version = data.aws_serverlessapplicationrepository_application.sar_app.semantic_version
- capabilities = [
- "CAPABILITY_IAM",
- "CAPABILITY_NAMED_IAM"
- ]
- }
-
- data "aws_serverlessapplicationrepository_application" "sar_app" {
- application_id = "arn:aws:serverlessrepo:eu-west-1:057560766410:applications/aws-lambda-powertools-python-layer"
- semantic_version = var.aws_powertools_version
- }
-
- variable "aws_powertools_version" {
- type = string
- default = "2.0.0"
- description = "The Powertools for AWS Lambda (Python) release version"
- }
-
- output "deployed_powertools_sar_version" {
- value = data.aws_serverlessapplicationrepository_application.sar_app.semantic_version
- }
-
- # Fetch Powertools for AWS Lambda (Python) Layer ARN from deployed SAR App
- output "aws_lambda_powertools_layer_arn" {
- value = aws_serverlessapplicationrepository_cloudformation_stack.deploy_sar_stack.outputs.LayerVersionArn
- }
+ --8<-- "examples/homepage/install/sar/terraform.tf"
```
Credits to [mwarkentin](https://github.com/mwarkentin){target="_blank" rel="nofollow"} for providing the scoped down IAM permissions below.
```yaml hl_lines="21-52" title="Least-privileged IAM permissions SAM example"
- AWSTemplateFormatVersion: "2010-09-09"
- Resources:
- PowertoolsLayerIamRole:
- Type: "AWS::IAM::Role"
- Properties:
- AssumeRolePolicyDocument:
- Version: "2012-10-17"
- Statement:
- - Effect: "Allow"
- Principal:
- Service:
- - "cloudformation.amazonaws.com"
- Action:
- - "sts:AssumeRole"
- Path: "/"
- PowertoolsLayerIamPolicy:
- Type: "AWS::IAM::Policy"
- Properties:
- PolicyName: PowertoolsLambdaLayerPolicy
- PolicyDocument:
- Version: "2012-10-17"
- Statement:
- - Sid: CloudFormationTransform
- Effect: Allow
- Action: cloudformation:CreateChangeSet
- Resource:
- - arn:aws:cloudformation:us-east-1:aws:transform/Serverless-2016-10-31
- - Sid: GetCfnTemplate
- Effect: Allow
- Action:
- - serverlessrepo:CreateCloudFormationTemplate
- - serverlessrepo:GetCloudFormationTemplate
- Resource:
- # this is arn of the Powertools for AWS Lambda (Python) SAR app
- - arn:aws:serverlessrepo:eu-west-1:057560766410:applications/aws-lambda-powertools-python-layer
- - Sid: S3AccessLayer
- Effect: Allow
- Action:
- - s3:GetObject
- Resource:
- # AWS publishes to an external S3 bucket locked down to your account ID
- # The below example is us publishing Powertools for AWS Lambda (Python)
- # Bucket: awsserverlessrepo-changesets-plntc6bfnfj
- # Key: *****/arn:aws:serverlessrepo:eu-west-1:057560766410:applications-aws-lambda-powertools-python-layer-versions-1.10.2/aeeccf50-****-****-****-*********
- - arn:aws:s3:::awsserverlessrepo-changesets-*/*
- - Sid: GetLayerVersion
- Effect: Allow
- Action:
- - lambda:PublishLayerVersion
- - lambda:GetLayerVersion
- Resource:
- - !Sub arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:layer:aws-lambda-powertools-python-layer*
- Roles:
- - Ref: "PowertoolsLayerIamRole"
+ --8<-- "examples/homepage/install/sar/scoped_down_iam.yaml"
```
## Quick getting started
diff --git a/docs/requirements.txt b/docs/requirements.txt
index 9de8e7ee71f..e60fd35b041 100644
--- a/docs/requirements.txt
+++ b/docs/requirements.txt
@@ -26,9 +26,9 @@ importlib-metadata==7.0.1 \
# via
# markdown
# mkdocs
-jinja2==3.1.3 \
- --hash=sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa \
- --hash=sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90
+jinja2==3.1.4 \
+ --hash=sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369 \
+ --hash=sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d
# via
# mkdocs
# mkdocs-git-revision-date-plugin
diff --git a/examples/event_handler_bedrock_agents/cdk/bedrock_agent_stack.py b/examples/event_handler_bedrock_agents/cdk/bedrock_agent_stack.py
index ef220209d6d..9f7efd07c85 100644
--- a/examples/event_handler_bedrock_agents/cdk/bedrock_agent_stack.py
+++ b/examples/event_handler_bedrock_agents/cdk/bedrock_agent_stack.py
@@ -3,11 +3,7 @@
)
from aws_cdk.aws_lambda import Runtime
from aws_cdk.aws_lambda_python_alpha import PythonFunction
-from cdklabs.generative_ai_cdk_constructs.bedrock import (
- Agent,
- ApiSchema,
- BedrockFoundationModel,
-)
+from cdklabs.generative_ai_cdk_constructs.bedrock import Agent, AgentActionGroup, ApiSchema, BedrockFoundationModel
from constructs import Construct
@@ -31,10 +27,14 @@ def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
foundation_model=BedrockFoundationModel.ANTHROPIC_CLAUDE_INSTANT_V1_2,
instruction="You are a helpful and friendly agent that answers questions about insurance claims.",
)
- agent.add_action_group(
+
+ action_group = AgentActionGroup(
+ self,
+ "ActionGroup",
action_group_name="InsureClaimsSupport",
description="Use these functions for insurance claims support",
action_group_executor=action_group_function,
action_group_state="ENABLED",
api_schema=ApiSchema.from_asset("./lambda/openapi.json"), # (2)!
)
+ agent.add_action_group(action_group)
diff --git a/examples/homepage/install/arm64/amplify.txt b/examples/homepage/install/arm64/amplify.txt
new file mode 100644
index 00000000000..58f26c59c4c
--- /dev/null
+++ b/examples/homepage/install/arm64/amplify.txt
@@ -0,0 +1,21 @@
+# Create a new one with the layer
+❯ amplify add function
+? Select which capability you want to add: Lambda function (serverless function)
+? Provide an AWS Lambda function name:
+? Choose the runtime that you want to use: Python
+? Do you want to configure advanced settings? Yes
+...
+? Do you want to enable Lambda layers for this function? Yes
+? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:69
+❯ amplify push -y
+
+
+# Updating an existing function and add the layer
+❯ amplify update function
+? Select the Lambda function you want to update test2
+General information
+- Name:
+? Which setting do you want to update? Lambda layers configuration
+? Do you want to enable Lambda layers for this function? Yes
+? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:69
+? Do you want to edit the local lambda function now? No
\ No newline at end of file
diff --git a/examples/homepage/install/arm64/cdk.py b/examples/homepage/install/arm64/cdk.py
new file mode 100644
index 00000000000..97e857d955c
--- /dev/null
+++ b/examples/homepage/install/arm64/cdk.py
@@ -0,0 +1,23 @@
+from aws_cdk import Aws, Stack, aws_lambda
+from constructs import Construct
+
+
+class SampleApp(Stack):
+
+ def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
+ super().__init__(scope, construct_id, **kwargs)
+
+ powertools_layer = aws_lambda.LayerVersion.from_layer_version_arn(
+ self,
+ id="lambda-powertools",
+ layer_version_arn=f"arn:aws:lambda:{Aws.REGION}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:69",
+ )
+ aws_lambda.Function(
+ self,
+ "sample-app-lambda",
+ runtime=aws_lambda.Runtime.PYTHON_3_12,
+ layers=[powertools_layer],
+ architecture=aws_lambda.Architecture.ARM_64,
+ code=aws_lambda.Code.from_asset("lambda"),
+ handler="hello.handler",
+ )
diff --git a/examples/homepage/install/arm64/pulumi.py b/examples/homepage/install/arm64/pulumi.py
new file mode 100644
index 00000000000..e32b7c1636c
--- /dev/null
+++ b/examples/homepage/install/arm64/pulumi.py
@@ -0,0 +1,34 @@
+import json
+
+import pulumi
+import pulumi_aws as aws
+
+role = aws.iam.Role(
+ "role",
+ assume_role_policy=json.dumps(
+ {
+ "Version": "2012-10-17",
+ "Statement": [
+ {"Action": "sts:AssumeRole", "Principal": {"Service": "lambda.amazonaws.com"}, "Effect": "Allow"},
+ ],
+ },
+ ),
+ managed_policy_arns=[aws.iam.ManagedPolicy.AWS_LAMBDA_BASIC_EXECUTION_ROLE],
+)
+
+lambda_function = aws.lambda_.Function(
+ "function",
+ layers=[
+ pulumi.Output.concat(
+ "arn:aws:lambda:",
+ aws.get_region_output().name,
+ ":017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:69",
+ ),
+ ],
+ tracing_config={"mode": "Active"},
+ runtime=aws.lambda_.Runtime.PYTHON3D9,
+ handler="index.handler",
+ role=role.arn,
+ architectures=["arm64"],
+ code=pulumi.FileArchive("lambda_function_payload.zip"),
+)
diff --git a/examples/homepage/install/arm64/sam.yaml b/examples/homepage/install/arm64/sam.yaml
new file mode 100644
index 00000000000..390a97edf13
--- /dev/null
+++ b/examples/homepage/install/arm64/sam.yaml
@@ -0,0 +1,12 @@
+AWSTemplateFormatVersion: '2010-09-09'
+Transform: AWS::Serverless-2016-10-31
+
+Resources:
+ MyLambdaFunction:
+ Type: AWS::Serverless::Function
+ Properties:
+ Architectures: [arm64]
+ Runtime: python3.12
+ Handler: app.lambda_handler
+ Layers:
+ - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:69
diff --git a/examples/homepage/install/arm64/serverless.yml b/examples/homepage/install/arm64/serverless.yml
new file mode 100644
index 00000000000..b1db844a985
--- /dev/null
+++ b/examples/homepage/install/arm64/serverless.yml
@@ -0,0 +1,13 @@
+service: powertools-lambda
+
+provider:
+ name: aws
+ runtime: python3.12
+ region: us-east-1
+
+functions:
+ powertools:
+ handler: lambda_function.lambda_handler
+ architecture: arm64
+ layers:
+ - arn:aws:lambda:${aws:region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:69
\ No newline at end of file
diff --git a/examples/homepage/install/arm64/terraform.tf b/examples/homepage/install/arm64/terraform.tf
new file mode 100644
index 00000000000..1cbb4a1e415
--- /dev/null
+++ b/examples/homepage/install/arm64/terraform.tf
@@ -0,0 +1,41 @@
+terraform {
+ required_version = "~> 1.0.5"
+ required_providers {
+ aws = "~> 3.50.0"
+ }
+}
+
+provider "aws" {
+ region = "{region}"
+}
+
+resource "aws_iam_role" "iam_for_lambda" {
+ name = "iam_for_lambda"
+
+ assume_role_policy = < None:
+ super().__init__(scope, id_)
+
+ # Launches SAR App as CloudFormation nested stack and return Lambda Layer
+ powertools_app = aws_sam.CfnApplication(
+ self,
+ f"{POWERTOOLS_BASE_NAME}Application",
+ location={"applicationId": POWERTOOLS_ARN, "semanticVersion": POWERTOOLS_VER},
+ )
+
+ powertools_layer_arn = powertools_app.get_att("Outputs.LayerVersionArn").to_string()
+ powertools_layer_version = aws_lambda.LayerVersion.from_layer_version_arn(
+ self,
+ f"{POWERTOOLS_BASE_NAME}",
+ powertools_layer_arn,
+ )
+
+ aws_lambda.Function(
+ self,
+ "sample-app-lambda",
+ runtime=aws_lambda.Runtime.PYTHON_3_12,
+ function_name="sample-lambda",
+ code=aws_lambda.Code.from_asset("lambda"),
+ handler="hello.handler",
+ layers=[powertools_layer_version],
+ )
diff --git a/examples/homepage/install/sar/sam.yaml b/examples/homepage/install/sar/sam.yaml
new file mode 100644
index 00000000000..0b2c759315d
--- /dev/null
+++ b/examples/homepage/install/sar/sam.yaml
@@ -0,0 +1,19 @@
+AWSTemplateFormatVersion: '2010-09-09'
+Transform: AWS::Serverless-2016-10-31
+
+Resources:
+ AwsLambdaPowertoolsPythonLayer:
+ Type: AWS::Serverless::Application
+ Properties:
+ Location:
+ ApplicationId: arn:aws:serverlessrepo:eu-west-1:057560766410:applications/aws-lambda-powertools-python-layer
+ SemanticVersion: 2.0.0 # change to latest semantic version available in SAR
+
+ MyLambdaFunction:
+ Type: AWS::Serverless::Function
+ Properties:
+ Runtime: python3.12
+ Handler: app.lambda_handler
+ Layers:
+ # fetch Layer ARN from SAR App stack output
+ - !GetAtt AwsLambdaPowertoolsPythonLayer.Outputs.LayerVersionArn
\ No newline at end of file
diff --git a/examples/homepage/install/sar/scoped_down_iam.yaml b/examples/homepage/install/sar/scoped_down_iam.yaml
new file mode 100644
index 00000000000..faf7c1237c3
--- /dev/null
+++ b/examples/homepage/install/sar/scoped_down_iam.yaml
@@ -0,0 +1,55 @@
+ AWSTemplateFormatVersion: "2010-09-09"
+ Resources:
+ PowertoolsLayerIamRole:
+ Type: "AWS::IAM::Role"
+ Properties:
+ AssumeRolePolicyDocument:
+ Version: "2012-10-17"
+ Statement:
+ - Effect: "Allow"
+ Principal:
+ Service:
+ - "cloudformation.amazonaws.com"
+ Action:
+ - "sts:AssumeRole"
+ Path: "/"
+
+ PowertoolsLayerIamPolicy:
+ Type: "AWS::IAM::Policy"
+ Properties:
+ PolicyName: PowertoolsLambdaLayerPolicy
+ PolicyDocument:
+ Version: "2012-10-17"
+ Statement:
+ - Sid: CloudFormationTransform
+ Effect: Allow
+ Action: cloudformation:CreateChangeSet
+ Resource:
+ - arn:aws:cloudformation:us-east-1:aws:transform/Serverless-2016-10-31
+ - Sid: GetCfnTemplate
+ Effect: Allow
+ Action:
+ - serverlessrepo:CreateCloudFormationTemplate
+ - serverlessrepo:GetCloudFormationTemplate
+ Resource:
+ # this is arn of the Powertools for AWS Lambda (Python) SAR app
+ - arn:aws:serverlessrepo:eu-west-1:057560766410:applications/aws-lambda-powertools-python-layer
+ - Sid: S3AccessLayer
+ Effect: Allow
+ Action:
+ - s3:GetObject
+ Resource:
+ # AWS publishes to an external S3 bucket locked down to your account ID
+ # The below example is us publishing Powertools for AWS Lambda (Python)
+ # Bucket: awsserverlessrepo-changesets-plntc6bfnfj
+ # Key: *****/arn:aws:serverlessrepo:eu-west-1:057560766410:applications-aws-lambda-powertools-python-layer-versions-1.10.2/aeeccf50-****-****-****-*********
+ - arn:aws:s3:::awsserverlessrepo-changesets-*/*
+ - Sid: GetLayerVersion
+ Effect: Allow
+ Action:
+ - lambda:PublishLayerVersion
+ - lambda:GetLayerVersion
+ Resource:
+ - !Sub arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:layer:aws-lambda-powertools-python-layer*
+ Roles:
+ - Ref: "PowertoolsLayerIamRole"
\ No newline at end of file
diff --git a/examples/homepage/install/sar/serverless.yml b/examples/homepage/install/sar/serverless.yml
new file mode 100644
index 00000000000..590079d6cd3
--- /dev/null
+++ b/examples/homepage/install/sar/serverless.yml
@@ -0,0 +1,20 @@
+service: powertools-lambda
+
+provider:
+ name: aws
+ runtime: python3.12
+ region: us-east-1
+
+functions:
+ powertools:
+ handler: lambda_function.lambda_handler
+ layers:
+ - !GetAtt AwsLambdaPowertoolsPythonLayer.Outputs.LayerVersionArn
+
+resources:
+ - AwsLambdaPowertoolsPythonLayer:
+ Type: AWS::Serverless::Application
+ Properties:
+ Location:
+ ApplicationId: arn:aws:serverlessrepo:eu-west-1:057560766410:applications/aws-lambda-powertools-python-layer
+ SemanticVersion: 2.0.0
\ No newline at end of file
diff --git a/examples/homepage/install/sar/terraform.tf b/examples/homepage/install/sar/terraform.tf
new file mode 100644
index 00000000000..a044d57bb44
--- /dev/null
+++ b/examples/homepage/install/sar/terraform.tf
@@ -0,0 +1,41 @@
+terraform {
+ required_version = "~> 0.13"
+ required_providers {
+ aws = "~> 3.50.0"
+ }
+}
+
+provider "aws" {
+ region = "us-east-1"
+}
+
+resource "aws_serverlessapplicationrepository_cloudformation_stack" "deploy_sar_stack" {
+ name = "aws-lambda-powertools-python-layer"
+
+ application_id = data.aws_serverlessapplicationrepository_application.sar_app.application_id
+ semantic_version = data.aws_serverlessapplicationrepository_application.sar_app.semantic_version
+ capabilities = [
+ "CAPABILITY_IAM",
+ "CAPABILITY_NAMED_IAM"
+ ]
+}
+
+data "aws_serverlessapplicationrepository_application" "sar_app" {
+ application_id = "arn:aws:serverlessrepo:eu-west-1:057560766410:applications/aws-lambda-powertools-python-layer"
+ semantic_version = var.aws_powertools_version
+}
+
+variable "aws_powertools_version" {
+ type = string
+ default = "2.0.0"
+ description = "The Powertools for AWS Lambda (Python) release version"
+}
+
+output "deployed_powertools_sar_version" {
+ value = data.aws_serverlessapplicationrepository_application.sar_app.semantic_version
+}
+
+# Fetch Powertools for AWS Lambda (Python) Layer ARN from deployed SAR App
+output "aws_lambda_powertools_layer_arn" {
+ value = aws_serverlessapplicationrepository_cloudformation_stack.deploy_sar_stack.outputs.LayerVersionArn
+}
\ No newline at end of file
diff --git a/examples/homepage/install/x86_64/amplify.txt b/examples/homepage/install/x86_64/amplify.txt
new file mode 100644
index 00000000000..b0bba434535
--- /dev/null
+++ b/examples/homepage/install/x86_64/amplify.txt
@@ -0,0 +1,21 @@
+# Create a new one with the layer
+❯ amplify add function
+? Select which capability you want to add: Lambda function (serverless function)
+? Provide an AWS Lambda function name:
+? Choose the runtime that you want to use: Python
+? Do you want to configure advanced settings? Yes
+...
+? Do you want to enable Lambda layers for this function? Yes
+? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:69
+❯ amplify push -y
+
+
+# Updating an existing function and add the layer
+❯ amplify update function
+? Select the Lambda function you want to update test2
+General information
+- Name:
+? Which setting do you want to update? Lambda layers configuration
+? Do you want to enable Lambda layers for this function? Yes
+? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:69
+? Do you want to edit the local lambda function now? No
\ No newline at end of file
diff --git a/examples/homepage/install/x86_64/cdk.py b/examples/homepage/install/x86_64/cdk.py
new file mode 100644
index 00000000000..ba2ec89a335
--- /dev/null
+++ b/examples/homepage/install/x86_64/cdk.py
@@ -0,0 +1,22 @@
+from aws_cdk import Aws, Stack, aws_lambda
+from constructs import Construct
+
+
+class SampleApp(Stack):
+
+ def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
+ super().__init__(scope, construct_id, **kwargs)
+
+ powertools_layer = aws_lambda.LayerVersion.from_layer_version_arn(
+ self,
+ id="lambda-powertools",
+ layer_version_arn=f"arn:aws:lambda:{Aws.REGION}:017000801446:layer:AWSLambdaPowertoolsPythonV2:69",
+ )
+ aws_lambda.Function(
+ self,
+ "sample-app-lambda",
+ runtime=aws_lambda.Runtime.PYTHON_3_12,
+ layers=[powertools_layer],
+ code=aws_lambda.Code.from_asset("lambda"),
+ handler="hello.handler",
+ )
diff --git a/examples/homepage/install/x86_64/pulumi.py b/examples/homepage/install/x86_64/pulumi.py
new file mode 100644
index 00000000000..4b8e9506708
--- /dev/null
+++ b/examples/homepage/install/x86_64/pulumi.py
@@ -0,0 +1,34 @@
+import json
+
+import pulumi
+import pulumi_aws as aws
+
+role = aws.iam.Role(
+ "role",
+ assume_role_policy=json.dumps(
+ {
+ "Version": "2012-10-17",
+ "Statement": [
+ {"Action": "sts:AssumeRole", "Principal": {"Service": "lambda.amazonaws.com"}, "Effect": "Allow"},
+ ],
+ },
+ ),
+ managed_policy_arns=[aws.iam.ManagedPolicy.AWS_LAMBDA_BASIC_EXECUTION_ROLE],
+)
+
+lambda_function = aws.lambda_.Function(
+ "function",
+ layers=[
+ pulumi.Output.concat(
+ "arn:aws:lambda:",
+ aws.get_region_output().name,
+ ":017000801446:layer:AWSLambdaPowertoolsPythonV2:69",
+ ),
+ ],
+ tracing_config={"mode": "Active"},
+ runtime=aws.lambda_.Runtime.PYTHON3D9,
+ handler="index.handler",
+ role=role.arn,
+ architectures=["x86_64"],
+ code=pulumi.FileArchive("lambda_function_payload.zip"),
+)
diff --git a/examples/homepage/install/x86_64/sam.yaml b/examples/homepage/install/x86_64/sam.yaml
new file mode 100644
index 00000000000..8029b4a3ed7
--- /dev/null
+++ b/examples/homepage/install/x86_64/sam.yaml
@@ -0,0 +1,11 @@
+AWSTemplateFormatVersion: '2010-09-09'
+Transform: AWS::Serverless-2016-10-31
+
+Resources:
+ MyLambdaFunction:
+ Type: AWS::Serverless::Function
+ Properties:
+ Runtime: python3.12
+ Handler: app.lambda_handler
+ Layers:
+ - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:69
\ No newline at end of file
diff --git a/examples/homepage/install/x86_64/serverless.yml b/examples/homepage/install/x86_64/serverless.yml
new file mode 100644
index 00000000000..92757005df5
--- /dev/null
+++ b/examples/homepage/install/x86_64/serverless.yml
@@ -0,0 +1,13 @@
+service: powertools-lambda
+
+provider:
+ name: aws
+ runtime: python3.12
+ region: us-east-1
+
+functions:
+ powertools:
+ handler: lambda_function.lambda_handler
+ architecture: arm64
+ layers:
+ - arn:aws:lambda:${aws:region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:69
\ No newline at end of file
diff --git a/examples/homepage/install/x86_64/terraform.tf b/examples/homepage/install/x86_64/terraform.tf
new file mode 100644
index 00000000000..63fe42b84a4
--- /dev/null
+++ b/examples/homepage/install/x86_64/terraform.tf
@@ -0,0 +1,40 @@
+terraform {
+ required_version = "~> 1.0.5"
+ required_providers {
+ aws = "~> 3.50.0"
+ }
+}
+
+provider "aws" {
+ region = "{region}"
+}
+
+resource "aws_iam_role" "iam_for_lambda" {
+ name = "iam_for_lambda"
+
+ assume_role_policy = <=2.139.0,<3.0.0"
+aws-cdk-lib = ">=2.142.1,<3.0.0"
constructs = ">=10.0.0,<11.0.0"
-jsii = ">=1.97.0,<2.0.0"
+jsii = ">=1.98.0,<2.0.0"
publication = ">=0.0.3"
typeguard = ">=2.13.3,<2.14.0"
[[package]]
name = "aws-cdk-lib"
-version = "2.139.0"
+version = "2.142.1"
description = "Version 2 of the AWS Cloud Development Kit library"
optional = false
python-versions = "~=3.8"
files = [
- {file = "aws-cdk-lib-2.139.0.tar.gz", hash = "sha256:49492be7b4afb2a050f5d5eaabd8f7f393134554343c07d62ca43290aaa9ecfe"},
- {file = "aws_cdk_lib-2.139.0-py3-none-any.whl", hash = "sha256:bc5590328fb0852055a09e36afb0eddf55691f413dc3775053671721d6ce9fab"},
+ {file = "aws-cdk-lib-2.142.1.tar.gz", hash = "sha256:d24482ed728c93c249badabad68cbf13cc8c26bd40d1e22ede552cc5d1b08b6d"},
+ {file = "aws_cdk_lib-2.142.1-py3-none-any.whl", hash = "sha256:b1148f7685e15584807a115f8ec949b2dd30cdcb53d76db39ef28b2093f1d2d9"},
]
[package.dependencies]
@@ -190,7 +190,7 @@ files = [
"aws-cdk.asset-kubectl-v20" = ">=2.1.2,<3.0.0"
"aws-cdk.asset-node-proxy-agent-v6" = ">=2.0.3,<3.0.0"
constructs = ">=10.0.0,<11.0.0"
-jsii = ">=1.97.0,<2.0.0"
+jsii = ">=1.98.0,<2.0.0"
publication = ">=0.0.3"
typeguard = ">=2.13.3,<2.14.0"
@@ -247,13 +247,13 @@ dev = ["black (==23.10.1)", "boto3 (>=1.23,<2)", "boto3-stubs[appconfig,serverle
[[package]]
name = "aws-xray-sdk"
-version = "2.13.0"
+version = "2.13.1"
description = "The AWS X-Ray SDK for Python (the SDK) enables Python developers to record and emit information from within their applications to the AWS X-Ray service."
optional = true
python-versions = ">=3.7"
files = [
- {file = "aws-xray-sdk-2.13.0.tar.gz", hash = "sha256:816186126917bc35ae4e6e2f304702a43d494ecef34a39e6330f5018bdecc9f5"},
- {file = "aws_xray_sdk-2.13.0-py2.py3-none-any.whl", hash = "sha256:d18604a8688b4bed03ce4a858cc9acd72b71400e085bf7512fc31cf657ca85f9"},
+ {file = "aws-xray-sdk-2.13.1.tar.gz", hash = "sha256:911d634c23e0693f585c4cab08d43ab5177f872de416fdc8dd0fe3b170b52835"},
+ {file = "aws_xray_sdk-2.13.1-py2.py3-none-any.whl", hash = "sha256:3da9d3b3d63c62f7745b987d80a157a30f4a0cd1db7e340b8f40f4d6aab30e12"},
]
[package.dependencies]
@@ -429,38 +429,38 @@ ujson = ["ujson (>=5.7.0)"]
[[package]]
name = "cdk-nag"
-version = "2.28.99"
+version = "2.28.119"
description = "Check CDK v2 applications for best practices using a combination on available rule packs."
optional = false
python-versions = "~=3.8"
files = [
- {file = "cdk-nag-2.28.99.tar.gz", hash = "sha256:079931ecb3bf834b09c0ae57bebffd96c50c179b7470b44ccba9d9d513b7fe14"},
- {file = "cdk_nag-2.28.99-py3-none-any.whl", hash = "sha256:6cd51a2c073ea9edc58aa1d2647ebb3392935d44ea42c916883e06278c22c4c9"},
+ {file = "cdk-nag-2.28.119.tar.gz", hash = "sha256:928c7b1e3398024dd66f1fb004920950a734f8a39695e8b85c5131f7328b93bc"},
+ {file = "cdk_nag-2.28.119-py3-none-any.whl", hash = "sha256:902e7f0fd361c61b0731e85492801f124e86243d6083fbbb60af200fab9c47c9"},
]
[package.dependencies]
aws-cdk-lib = ">=2.116.0,<3.0.0"
constructs = ">=10.0.5,<11.0.0"
-jsii = ">=1.97.0,<2.0.0"
+jsii = ">=1.98.0,<2.0.0"
publication = ">=0.0.3"
typeguard = ">=2.13.3,<2.14.0"
[[package]]
name = "cdklabs-generative-ai-cdk-constructs"
-version = "0.1.131"
+version = "0.1.154"
description = "AWS Generative AI CDK Constructs is a library for well-architected generative AI patterns."
optional = false
python-versions = "~=3.8"
files = [
- {file = "cdklabs.generative-ai-cdk-constructs-0.1.131.tar.gz", hash = "sha256:6267d38090955f72ff22ef4f0d1c6024ddd374554bb4db13f015aa81618bf38b"},
- {file = "cdklabs.generative_ai_cdk_constructs-0.1.131-py3-none-any.whl", hash = "sha256:69751a67d7e546c5ab221c92a7b365d2f78348c88afecddd8f4cd083b39ac553"},
+ {file = "cdklabs.generative-ai-cdk-constructs-0.1.154.tar.gz", hash = "sha256:7bc398b355197e7b816d3df1f6569f4e84ba2ca0f0b911414041ec4a37852a39"},
+ {file = "cdklabs.generative_ai_cdk_constructs-0.1.154-py3-none-any.whl", hash = "sha256:61b4571b7542b602250fdf5b7c84e1a01c9414a3eb3a30cfd7e75d5350e06ed0"},
]
[package.dependencies]
-aws-cdk-lib = ">=2.122.0,<3.0.0"
-cdk-nag = ">=2.28.99,<3.0.0"
+aws-cdk-lib = ">=2.141.0,<3.0.0"
+cdk-nag = ">=2.28.118,<3.0.0"
constructs = ">=10.3.0,<11.0.0"
-jsii = ">=1.97.0,<2.0.0"
+jsii = ">=1.98.0,<2.0.0"
publication = ">=0.0.3"
typeguard = ">=2.13.3,<2.14.0"
@@ -541,13 +541,13 @@ pycparser = "*"
[[package]]
name = "cfn-lint"
-version = "0.86.4"
+version = "0.87.3"
description = "Checks CloudFormation templates for practices and behaviour that could potentially be improved"
optional = false
python-versions = "!=4.0,<=4.0,>=3.8"
files = [
- {file = "cfn_lint-0.86.4-py3-none-any.whl", hash = "sha256:2e779afba0acd9878a4e2dc07a93679411495512241a4da9b9d52aca5254334f"},
- {file = "cfn_lint-0.86.4.tar.gz", hash = "sha256:9ee31451a18457f2b27cd064f5d99adbf79afd1402aaf4b614514d13d8bc0174"},
+ {file = "cfn_lint-0.87.3-py3-none-any.whl", hash = "sha256:6b96b4ea8ce8d2601491c238bc504d0a1f6e0e2709217e3a296214d48f182ca1"},
+ {file = "cfn_lint-0.87.3.tar.gz", hash = "sha256:4c4f1717cba9b9b579f95687ffa71a8d740b7e1712f6e315c723aac9bb0279d7"},
]
[package.dependencies]
@@ -715,63 +715,63 @@ typeguard = ">=2.13.3,<2.14.0"
[[package]]
name = "coverage"
-version = "7.5.0"
+version = "7.5.1"
description = "Code coverage measurement for Python"
optional = false
python-versions = ">=3.8"
files = [
- {file = "coverage-7.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:432949a32c3e3f820af808db1833d6d1631664d53dd3ce487aa25d574e18ad1c"},
- {file = "coverage-7.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2bd7065249703cbeb6d4ce679c734bef0ee69baa7bff9724361ada04a15b7e3b"},
- {file = "coverage-7.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bbfe6389c5522b99768a93d89aca52ef92310a96b99782973b9d11e80511f932"},
- {file = "coverage-7.5.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:39793731182c4be939b4be0cdecde074b833f6171313cf53481f869937129ed3"},
- {file = "coverage-7.5.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85a5dbe1ba1bf38d6c63b6d2c42132d45cbee6d9f0c51b52c59aa4afba057517"},
- {file = "coverage-7.5.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:357754dcdfd811462a725e7501a9b4556388e8ecf66e79df6f4b988fa3d0b39a"},
- {file = "coverage-7.5.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a81eb64feded34f40c8986869a2f764f0fe2db58c0530d3a4afbcde50f314880"},
- {file = "coverage-7.5.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:51431d0abbed3a868e967f8257c5faf283d41ec882f58413cf295a389bb22e58"},
- {file = "coverage-7.5.0-cp310-cp310-win32.whl", hash = "sha256:f609ebcb0242d84b7adeee2b06c11a2ddaec5464d21888b2c8255f5fd6a98ae4"},
- {file = "coverage-7.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:6782cd6216fab5a83216cc39f13ebe30adfac2fa72688c5a4d8d180cd52e8f6a"},
- {file = "coverage-7.5.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e768d870801f68c74c2b669fc909839660180c366501d4cc4b87efd6b0eee375"},
- {file = "coverage-7.5.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:84921b10aeb2dd453247fd10de22907984eaf80901b578a5cf0bb1e279a587cb"},
- {file = "coverage-7.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:710c62b6e35a9a766b99b15cdc56d5aeda0914edae8bb467e9c355f75d14ee95"},
- {file = "coverage-7.5.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c379cdd3efc0658e652a14112d51a7668f6bfca7445c5a10dee7eabecabba19d"},
- {file = "coverage-7.5.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fea9d3ca80bcf17edb2c08a4704259dadac196fe5e9274067e7a20511fad1743"},
- {file = "coverage-7.5.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:41327143c5b1d715f5f98a397608f90ab9ebba606ae4e6f3389c2145410c52b1"},
- {file = "coverage-7.5.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:565b2e82d0968c977e0b0f7cbf25fd06d78d4856289abc79694c8edcce6eb2de"},
- {file = "coverage-7.5.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cf3539007202ebfe03923128fedfdd245db5860a36810136ad95a564a2fdffff"},
- {file = "coverage-7.5.0-cp311-cp311-win32.whl", hash = "sha256:bf0b4b8d9caa8d64df838e0f8dcf68fb570c5733b726d1494b87f3da85db3a2d"},
- {file = "coverage-7.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:9c6384cc90e37cfb60435bbbe0488444e54b98700f727f16f64d8bfda0b84656"},
- {file = "coverage-7.5.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:fed7a72d54bd52f4aeb6c6e951f363903bd7d70bc1cad64dd1f087980d309ab9"},
- {file = "coverage-7.5.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:cbe6581fcff7c8e262eb574244f81f5faaea539e712a058e6707a9d272fe5b64"},
- {file = "coverage-7.5.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ad97ec0da94b378e593ef532b980c15e377df9b9608c7c6da3506953182398af"},
- {file = "coverage-7.5.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bd4bacd62aa2f1a1627352fe68885d6ee694bdaebb16038b6e680f2924a9b2cc"},
- {file = "coverage-7.5.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:adf032b6c105881f9d77fa17d9eebe0ad1f9bfb2ad25777811f97c5362aa07f2"},
- {file = "coverage-7.5.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:4ba01d9ba112b55bfa4b24808ec431197bb34f09f66f7cb4fd0258ff9d3711b1"},
- {file = "coverage-7.5.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:f0bfe42523893c188e9616d853c47685e1c575fe25f737adf473d0405dcfa7eb"},
- {file = "coverage-7.5.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a9a7ef30a1b02547c1b23fa9a5564f03c9982fc71eb2ecb7f98c96d7a0db5cf2"},
- {file = "coverage-7.5.0-cp312-cp312-win32.whl", hash = "sha256:3c2b77f295edb9fcdb6a250f83e6481c679335ca7e6e4a955e4290350f2d22a4"},
- {file = "coverage-7.5.0-cp312-cp312-win_amd64.whl", hash = "sha256:427e1e627b0963ac02d7c8730ca6d935df10280d230508c0ba059505e9233475"},
- {file = "coverage-7.5.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9dd88fce54abbdbf4c42fb1fea0e498973d07816f24c0e27a1ecaf91883ce69e"},
- {file = "coverage-7.5.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a898c11dca8f8c97b467138004a30133974aacd572818c383596f8d5b2eb04a9"},
- {file = "coverage-7.5.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:07dfdd492d645eea1bd70fb1d6febdcf47db178b0d99161d8e4eed18e7f62fe7"},
- {file = "coverage-7.5.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d3d117890b6eee85887b1eed41eefe2e598ad6e40523d9f94c4c4b213258e4a4"},
- {file = "coverage-7.5.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6afd2e84e7da40fe23ca588379f815fb6dbbb1b757c883935ed11647205111cb"},
- {file = "coverage-7.5.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a9960dd1891b2ddf13a7fe45339cd59ecee3abb6b8326d8b932d0c5da208104f"},
- {file = "coverage-7.5.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ced268e82af993d7801a9db2dbc1d2322e786c5dc76295d8e89473d46c6b84d4"},
- {file = "coverage-7.5.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e7c211f25777746d468d76f11719e64acb40eed410d81c26cefac641975beb88"},
- {file = "coverage-7.5.0-cp38-cp38-win32.whl", hash = "sha256:262fffc1f6c1a26125d5d573e1ec379285a3723363f3bd9c83923c9593a2ac25"},
- {file = "coverage-7.5.0-cp38-cp38-win_amd64.whl", hash = "sha256:eed462b4541c540d63ab57b3fc69e7d8c84d5957668854ee4e408b50e92ce26a"},
- {file = "coverage-7.5.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d0194d654e360b3e6cc9b774e83235bae6b9b2cac3be09040880bb0e8a88f4a1"},
- {file = "coverage-7.5.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:33c020d3322662e74bc507fb11488773a96894aa82a622c35a5a28673c0c26f5"},
- {file = "coverage-7.5.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cbdf2cae14a06827bec50bd58e49249452d211d9caddd8bd80e35b53cb04631"},
- {file = "coverage-7.5.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3235d7c781232e525b0761730e052388a01548bd7f67d0067a253887c6e8df46"},
- {file = "coverage-7.5.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2de4e546f0ec4b2787d625e0b16b78e99c3e21bc1722b4977c0dddf11ca84e"},
- {file = "coverage-7.5.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4d0e206259b73af35c4ec1319fd04003776e11e859936658cb6ceffdeba0f5be"},
- {file = "coverage-7.5.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:2055c4fb9a6ff624253d432aa471a37202cd8f458c033d6d989be4499aed037b"},
- {file = "coverage-7.5.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:075299460948cd12722a970c7eae43d25d37989da682997687b34ae6b87c0ef0"},
- {file = "coverage-7.5.0-cp39-cp39-win32.whl", hash = "sha256:280132aada3bc2f0fac939a5771db4fbb84f245cb35b94fae4994d4c1f80dae7"},
- {file = "coverage-7.5.0-cp39-cp39-win_amd64.whl", hash = "sha256:c58536f6892559e030e6924896a44098bc1290663ea12532c78cef71d0df8493"},
- {file = "coverage-7.5.0-pp38.pp39.pp310-none-any.whl", hash = "sha256:2b57780b51084d5223eee7b59f0d4911c31c16ee5aa12737c7a02455829ff067"},
- {file = "coverage-7.5.0.tar.gz", hash = "sha256:cf62d17310f34084c59c01e027259076479128d11e4661bb6c9acb38c5e19bb8"},
+ {file = "coverage-7.5.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c0884920835a033b78d1c73b6d3bbcda8161a900f38a488829a83982925f6c2e"},
+ {file = "coverage-7.5.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:39afcd3d4339329c5f58de48a52f6e4e50f6578dd6099961cf22228feb25f38f"},
+ {file = "coverage-7.5.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a7b0ceee8147444347da6a66be737c9d78f3353b0681715b668b72e79203e4a"},
+ {file = "coverage-7.5.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a9ca3f2fae0088c3c71d743d85404cec8df9be818a005ea065495bedc33da35"},
+ {file = "coverage-7.5.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fd215c0c7d7aab005221608a3c2b46f58c0285a819565887ee0b718c052aa4e"},
+ {file = "coverage-7.5.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4bf0655ab60d754491004a5efd7f9cccefcc1081a74c9ef2da4735d6ee4a6223"},
+ {file = "coverage-7.5.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:61c4bf1ba021817de12b813338c9be9f0ad5b1e781b9b340a6d29fc13e7c1b5e"},
+ {file = "coverage-7.5.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:db66fc317a046556a96b453a58eced5024af4582a8dbdc0c23ca4dbc0d5b3146"},
+ {file = "coverage-7.5.1-cp310-cp310-win32.whl", hash = "sha256:b016ea6b959d3b9556cb401c55a37547135a587db0115635a443b2ce8f1c7228"},
+ {file = "coverage-7.5.1-cp310-cp310-win_amd64.whl", hash = "sha256:df4e745a81c110e7446b1cc8131bf986157770fa405fe90e15e850aaf7619bc8"},
+ {file = "coverage-7.5.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:796a79f63eca8814ca3317a1ea443645c9ff0d18b188de470ed7ccd45ae79428"},
+ {file = "coverage-7.5.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4fc84a37bfd98db31beae3c2748811a3fa72bf2007ff7902f68746d9757f3746"},
+ {file = "coverage-7.5.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6175d1a0559986c6ee3f7fccfc4a90ecd12ba0a383dcc2da30c2b9918d67d8a3"},
+ {file = "coverage-7.5.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1fc81d5878cd6274ce971e0a3a18a8803c3fe25457165314271cf78e3aae3aa2"},
+ {file = "coverage-7.5.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:556cf1a7cbc8028cb60e1ff0be806be2eded2daf8129b8811c63e2b9a6c43bca"},
+ {file = "coverage-7.5.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:9981706d300c18d8b220995ad22627647be11a4276721c10911e0e9fa44c83e8"},
+ {file = "coverage-7.5.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:d7fed867ee50edf1a0b4a11e8e5d0895150e572af1cd6d315d557758bfa9c057"},
+ {file = "coverage-7.5.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ef48e2707fb320c8f139424a596f5b69955a85b178f15af261bab871873bb987"},
+ {file = "coverage-7.5.1-cp311-cp311-win32.whl", hash = "sha256:9314d5678dcc665330df5b69c1e726a0e49b27df0461c08ca12674bcc19ef136"},
+ {file = "coverage-7.5.1-cp311-cp311-win_amd64.whl", hash = "sha256:5fa567e99765fe98f4e7d7394ce623e794d7cabb170f2ca2ac5a4174437e90dd"},
+ {file = "coverage-7.5.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b6cf3764c030e5338e7f61f95bd21147963cf6aa16e09d2f74f1fa52013c1206"},
+ {file = "coverage-7.5.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2ec92012fefebee89a6b9c79bc39051a6cb3891d562b9270ab10ecfdadbc0c34"},
+ {file = "coverage-7.5.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:16db7f26000a07efcf6aea00316f6ac57e7d9a96501e990a36f40c965ec7a95d"},
+ {file = "coverage-7.5.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:beccf7b8a10b09c4ae543582c1319c6df47d78fd732f854ac68d518ee1fb97fa"},
+ {file = "coverage-7.5.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8748731ad392d736cc9ccac03c9845b13bb07d020a33423fa5b3a36521ac6e4e"},
+ {file = "coverage-7.5.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7352b9161b33fd0b643ccd1f21f3a3908daaddf414f1c6cb9d3a2fd618bf2572"},
+ {file = "coverage-7.5.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:7a588d39e0925f6a2bff87154752481273cdb1736270642aeb3635cb9b4cad07"},
+ {file = "coverage-7.5.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:68f962d9b72ce69ea8621f57551b2fa9c70509af757ee3b8105d4f51b92b41a7"},
+ {file = "coverage-7.5.1-cp312-cp312-win32.whl", hash = "sha256:f152cbf5b88aaeb836127d920dd0f5e7edff5a66f10c079157306c4343d86c19"},
+ {file = "coverage-7.5.1-cp312-cp312-win_amd64.whl", hash = "sha256:5a5740d1fb60ddf268a3811bcd353de34eb56dc24e8f52a7f05ee513b2d4f596"},
+ {file = "coverage-7.5.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e2213def81a50519d7cc56ed643c9e93e0247f5bbe0d1247d15fa520814a7cd7"},
+ {file = "coverage-7.5.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5037f8fcc2a95b1f0e80585bd9d1ec31068a9bcb157d9750a172836e98bc7a90"},
+ {file = "coverage-7.5.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c3721c2c9e4c4953a41a26c14f4cef64330392a6d2d675c8b1db3b645e31f0e"},
+ {file = "coverage-7.5.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca498687ca46a62ae590253fba634a1fe9836bc56f626852fb2720f334c9e4e5"},
+ {file = "coverage-7.5.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0cdcbc320b14c3e5877ee79e649677cb7d89ef588852e9583e6b24c2e5072661"},
+ {file = "coverage-7.5.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:57e0204b5b745594e5bc14b9b50006da722827f0b8c776949f1135677e88d0b8"},
+ {file = "coverage-7.5.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8fe7502616b67b234482c3ce276ff26f39ffe88adca2acf0261df4b8454668b4"},
+ {file = "coverage-7.5.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:9e78295f4144f9dacfed4f92935fbe1780021247c2fabf73a819b17f0ccfff8d"},
+ {file = "coverage-7.5.1-cp38-cp38-win32.whl", hash = "sha256:1434e088b41594baa71188a17533083eabf5609e8e72f16ce8c186001e6b8c41"},
+ {file = "coverage-7.5.1-cp38-cp38-win_amd64.whl", hash = "sha256:0646599e9b139988b63704d704af8e8df7fa4cbc4a1f33df69d97f36cb0a38de"},
+ {file = "coverage-7.5.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4cc37def103a2725bc672f84bd939a6fe4522310503207aae4d56351644682f1"},
+ {file = "coverage-7.5.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fc0b4d8bfeabd25ea75e94632f5b6e047eef8adaed0c2161ada1e922e7f7cece"},
+ {file = "coverage-7.5.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d0a0f5e06881ecedfe6f3dd2f56dcb057b6dbeb3327fd32d4b12854df36bf26"},
+ {file = "coverage-7.5.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9735317685ba6ec7e3754798c8871c2f49aa5e687cc794a0b1d284b2389d1bd5"},
+ {file = "coverage-7.5.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d21918e9ef11edf36764b93101e2ae8cc82aa5efdc7c5a4e9c6c35a48496d601"},
+ {file = "coverage-7.5.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c3e757949f268364b96ca894b4c342b41dc6f8f8b66c37878aacef5930db61be"},
+ {file = "coverage-7.5.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:79afb6197e2f7f60c4824dd4b2d4c2ec5801ceb6ba9ce5d2c3080e5660d51a4f"},
+ {file = "coverage-7.5.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d1d0d98d95dd18fe29dc66808e1accf59f037d5716f86a501fc0256455219668"},
+ {file = "coverage-7.5.1-cp39-cp39-win32.whl", hash = "sha256:1cc0fe9b0b3a8364093c53b0b4c0c2dd4bb23acbec4c9240b5f284095ccf7981"},
+ {file = "coverage-7.5.1-cp39-cp39-win_amd64.whl", hash = "sha256:dde0070c40ea8bb3641e811c1cfbf18e265d024deff6de52c5950677a8fb1e0f"},
+ {file = "coverage-7.5.1-pp38.pp39.pp310-none-any.whl", hash = "sha256:6537e7c10cc47c595828b8a8be04c72144725c383c4702703ff4e42e44577312"},
+ {file = "coverage-7.5.1.tar.gz", hash = "sha256:54de9ef3a9da981f7af93eafde4ede199e0846cd819eb27c88e2b712aae9708c"},
]
[package.dependencies]
@@ -850,13 +850,13 @@ requests = ">=2.6.0"
[[package]]
name = "datadog-lambda"
-version = "5.93.0"
+version = "5.94.0"
description = "The Datadog AWS Lambda Library"
optional = false
python-versions = "<4,>=3.8.0"
files = [
- {file = "datadog_lambda-5.93.0-py3-none-any.whl", hash = "sha256:16fd90ad9e7fbd7477eb7623d800aa737a7399a3aec2987b0ae9d354c0e41abb"},
- {file = "datadog_lambda-5.93.0.tar.gz", hash = "sha256:9db455647d39866c636da38049cbfcafab2fa1d6acbce8240232261011c011ca"},
+ {file = "datadog_lambda-5.94.0-py3-none-any.whl", hash = "sha256:de8e9a40b4dbee3314bfc1c2c91d071691a78e324a041dcb07bf52754ead3e10"},
+ {file = "datadog_lambda-5.94.0.tar.gz", hash = "sha256:2005c09351f0c10da63fd29d1f43d035c4c5c6a71492416817741536a6e45896"},
]
[package.dependencies]
@@ -1081,13 +1081,13 @@ test = ["pytest (>=6)"]
[[package]]
name = "execnet"
-version = "2.0.2"
+version = "2.1.1"
description = "execnet: rapid multi-Python deployment"
optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.8"
files = [
- {file = "execnet-2.0.2-py3-none-any.whl", hash = "sha256:88256416ae766bc9e8895c76a87928c0012183da3cc4fc18016e6f050e025f41"},
- {file = "execnet-2.0.2.tar.gz", hash = "sha256:cc59bc4423742fd71ad227122eb0dd44db51efb3dc4095b45ac9a08c770096af"},
+ {file = "execnet-2.1.1-py3-none-any.whl", hash = "sha256:26dee51f1b80cebd6d0ca8e74dd8745419761d3bef34163928cbebbdc4749fdc"},
+ {file = "execnet-2.1.1.tar.gz", hash = "sha256:5189b52c6121c24feae288166ab41b32549c7e2348652736540b9e6e7d4e72e3"},
]
[package.extras]
@@ -1109,13 +1109,13 @@ devel = ["colorama", "json-spec", "jsonschema", "pylint", "pytest", "pytest-benc
[[package]]
name = "filelock"
-version = "3.13.4"
+version = "3.14.0"
description = "A platform independent file lock."
optional = false
python-versions = ">=3.8"
files = [
- {file = "filelock-3.13.4-py3-none-any.whl", hash = "sha256:404e5e9253aa60ad457cae1be07c0f0ca90a63931200a47d9b6a6af84fd7b45f"},
- {file = "filelock-3.13.4.tar.gz", hash = "sha256:d13f466618bfde72bd2c18255e269f72542c6e70e7bac83a0232d6b1cc5c8cf4"},
+ {file = "filelock-3.14.0-py3-none-any.whl", hash = "sha256:43339835842f110ca7ae60f1e1c160714c5a6afd15a2873419ab185334975c0f"},
+ {file = "filelock-3.14.0.tar.gz", hash = "sha256:6ea72da3be9b8c82afd3edcf99f2fffbb5076335a5ae4d03248bb5b6c3eae78a"},
]
[package.extras]
@@ -1229,13 +1229,13 @@ socks = ["socksio (==1.*)"]
[[package]]
name = "hvac"
-version = "2.1.0"
+version = "2.2.0"
description = "HashiCorp Vault API client"
optional = false
-python-versions = ">=3.8,<4.0"
+python-versions = "<4.0,>=3.8"
files = [
- {file = "hvac-2.1.0-py3-none-any.whl", hash = "sha256:73bc91e58c3fc7c6b8107cdaca9cb71fa0a893dfd80ffbc1c14e20f24c0c29d7"},
- {file = "hvac-2.1.0.tar.gz", hash = "sha256:b48bcda11a4ab0a7b6c47232c7ba7c87fda318ae2d4a7662800c465a78742894"},
+ {file = "hvac-2.2.0-py3-none-any.whl", hash = "sha256:f287a19940c6fc518c723f8276cc9927f7400734303ee5872ac2e84539466d8d"},
+ {file = "hvac-2.2.0.tar.gz", hash = "sha256:e4b0248c5672cb9a6f5974e7c8f5271a09c6c663cbf8ab11733a227f3d2db2c2"},
]
[package.dependencies]
@@ -1417,13 +1417,13 @@ colors = ["colorama (>=0.4.6)"]
[[package]]
name = "jinja2"
-version = "3.1.3"
+version = "3.1.4"
description = "A very fast and expressive template engine."
optional = false
python-versions = ">=3.7"
files = [
- {file = "Jinja2-3.1.3-py3-none-any.whl", hash = "sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa"},
- {file = "Jinja2-3.1.3.tar.gz", hash = "sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90"},
+ {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"},
+ {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"},
]
[package.dependencies]
@@ -1461,13 +1461,13 @@ pbr = "*"
[[package]]
name = "jsii"
-version = "1.97.0"
+version = "1.98.0"
description = "Python client for jsii runtime"
optional = false
python-versions = "~=3.8"
files = [
- {file = "jsii-1.97.0-py3-none-any.whl", hash = "sha256:5dd347cc9d279072c109829aaff11dae1c7f13169ce60887f1c1ab2c4cd4abcd"},
- {file = "jsii-1.97.0.tar.gz", hash = "sha256:e6db98e34730cd972d180b7f4e21182b9a5105f537672716940b930ee933a1f2"},
+ {file = "jsii-1.98.0-py3-none-any.whl", hash = "sha256:3067d523126ce8178374dd958c60350efc831fc2ef3eb94a0a755d64fa4cc22d"},
+ {file = "jsii-1.98.0.tar.gz", hash = "sha256:64bbaf9c494626bc0afd1b95834f0dba66a2f2ecbb0da97fa3000c4b01d67857"},
]
[package.dependencies]
@@ -1756,24 +1756,28 @@ files = [
[[package]]
name = "mike"
-version = "1.1.2"
+version = "2.1.1"
description = "Manage multiple versions of your MkDocs-powered documentation"
optional = false
python-versions = "*"
files = [
- {file = "mike-1.1.2-py3-none-any.whl", hash = "sha256:4c307c28769834d78df10f834f57f810f04ca27d248f80a75f49c6fa2d1527ca"},
- {file = "mike-1.1.2.tar.gz", hash = "sha256:56c3f1794c2d0b5fdccfa9b9487beb013ca813de2e3ad0744724e9d34d40b77b"},
+ {file = "mike-2.1.1-py3-none-any.whl", hash = "sha256:0b1d01a397a423284593eeb1b5f3194e37169488f929b860c9bfe95c0d5efb79"},
+ {file = "mike-2.1.1.tar.gz", hash = "sha256:f39ed39f3737da83ad0adc33e9f885092ed27f8c9e7ff0523add0480352a2c22"},
]
[package.dependencies]
-jinja2 = "*"
+importlib-metadata = "*"
+importlib-resources = "*"
+jinja2 = ">=2.7"
mkdocs = ">=1.0"
+pyparsing = ">=3.0"
pyyaml = ">=5.1"
+pyyaml-env-tag = "*"
verspec = "*"
[package.extras]
-dev = ["coverage", "flake8 (>=3.0)", "shtab"]
-test = ["coverage", "flake8 (>=3.0)", "shtab"]
+dev = ["coverage", "flake8 (>=3.0)", "flake8-quotes", "shtab"]
+test = ["coverage", "flake8 (>=3.0)", "flake8-quotes", "shtab"]
[[package]]
name = "mkdocs"
@@ -1840,13 +1844,13 @@ mkdocs = ">=0.17"
[[package]]
name = "mkdocs-material"
-version = "9.5.19"
+version = "9.5.24"
description = "Documentation that simply works"
optional = false
python-versions = ">=3.8"
files = [
- {file = "mkdocs_material-9.5.19-py3-none-any.whl", hash = "sha256:ea96e150b6c95f5e4ffe47d78bb712c7bacdd91d2a0bec47f46b6fa0705a86ec"},
- {file = "mkdocs_material-9.5.19.tar.gz", hash = "sha256:7473e06e17e23af608a30ef583fdde8f36389dd3ef56b1d503eed54c89c9618c"},
+ {file = "mkdocs_material-9.5.24-py3-none-any.whl", hash = "sha256:e12cd75954c535b61e716f359cf2a5056bf4514889d17161fdebd5df4b0153c6"},
+ {file = "mkdocs_material-9.5.24.tar.gz", hash = "sha256:02d5aaba0ee755e707c3ef6e748f9acb7b3011187c0ea766db31af8905078a34"},
]
[package.dependencies]
@@ -2024,13 +2028,13 @@ typing-extensions = {version = ">=4.1.0", markers = "python_version < \"3.12\""}
[[package]]
name = "mypy-boto3-dynamodb"
-version = "1.34.91"
-description = "Type annotations for boto3.DynamoDB 1.34.91 service generated with mypy-boto3-builder 7.24.0"
+version = "1.34.97"
+description = "Type annotations for boto3.DynamoDB 1.34.97 service generated with mypy-boto3-builder 7.24.0"
optional = false
python-versions = ">=3.8"
files = [
- {file = "mypy_boto3_dynamodb-1.34.91-py3-none-any.whl", hash = "sha256:ec07e3f8826135ebb78cd782fb2edf54a355ad2f00ca0bdd24315dc7687a26cf"},
- {file = "mypy_boto3_dynamodb-1.34.91.tar.gz", hash = "sha256:b13e081ccfbbeb208fd4c759c1c50a7759c23cd6937c790c8bdbffa80fe662d7"},
+ {file = "mypy_boto3_dynamodb-1.34.97-py3-none-any.whl", hash = "sha256:4bb02b01506ba27cd7b63f3d2013147824c7504fa8f4f03242e51f5b78c31edf"},
+ {file = "mypy_boto3_dynamodb-1.34.97.tar.gz", hash = "sha256:3f67a291157dd94bef376c5490d9d29bbacc9741dfef124f9724bc5d29b0458a"},
]
[package.dependencies]
@@ -2066,13 +2070,13 @@ typing-extensions = {version = ">=4.1.0", markers = "python_version < \"3.12\""}
[[package]]
name = "mypy-boto3-s3"
-version = "1.34.91"
-description = "Type annotations for boto3.S3 1.34.91 service generated with mypy-boto3-builder 7.24.0"
+version = "1.34.105"
+description = "Type annotations for boto3.S3 1.34.105 service generated with mypy-boto3-builder 7.24.0"
optional = false
python-versions = ">=3.8"
files = [
- {file = "mypy_boto3_s3-1.34.91-py3-none-any.whl", hash = "sha256:0d37161fd0cd7ebf194cf9ccadb9101bf5c9b2426c2d00677b7e644d6f2298e4"},
- {file = "mypy_boto3_s3-1.34.91.tar.gz", hash = "sha256:70c8bad00db70704fb7ac0ee1440c7eb0587578ae9a2b00997f29f17f60f45e7"},
+ {file = "mypy_boto3_s3-1.34.105-py3-none-any.whl", hash = "sha256:95fbc6bcba2bb03c20a97cc5cf60ff66c6842c8c4fc4183c49bfa35905d5a1ee"},
+ {file = "mypy_boto3_s3-1.34.105.tar.gz", hash = "sha256:a137bca9bbe86c0fe35bbf36a2d44ab62526f41bb683550dd6cfbb5a10ede832"},
]
[package.dependencies]
@@ -2080,13 +2084,13 @@ typing-extensions = {version = ">=4.1.0", markers = "python_version < \"3.12\""}
[[package]]
name = "mypy-boto3-secretsmanager"
-version = "1.34.72"
-description = "Type annotations for boto3.SecretsManager 1.34.72 service generated with mypy-boto3-builder 7.23.2"
+version = "1.34.109"
+description = "Type annotations for boto3.SecretsManager 1.34.109 service generated with mypy-boto3-builder 7.24.0"
optional = false
python-versions = ">=3.8"
files = [
- {file = "mypy-boto3-secretsmanager-1.34.72.tar.gz", hash = "sha256:d0733c5b53e8b5e7bda00f4b42ed84af12e36a20c848917e49c173a0422ef03c"},
- {file = "mypy_boto3_secretsmanager-1.34.72-py3-none-any.whl", hash = "sha256:c5ed74e4a56e345a6396c609d2808fbe64570f90bb76b256d65e1294eaa24c69"},
+ {file = "mypy_boto3_secretsmanager-1.34.109-py3-none-any.whl", hash = "sha256:18c60597a72ef08bad722f1c2f4507a0cf853c1526b1cffb8c3d2a30f5649d1f"},
+ {file = "mypy_boto3_secretsmanager-1.34.109.tar.gz", hash = "sha256:29898fb1046fed5f83d05f08470d5cf07dfd1656b1da23f2bb875c9ff734ee65"},
]
[package.dependencies]
@@ -2250,13 +2254,13 @@ test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-
[[package]]
name = "pluggy"
-version = "1.4.0"
+version = "1.5.0"
description = "plugin and hook calling mechanisms for python"
optional = false
python-versions = ">=3.8"
files = [
- {file = "pluggy-1.4.0-py3-none-any.whl", hash = "sha256:7db9f7b503d67d1c5b95f59773ebb58a8c1c288129a88665838012cfb07b8981"},
- {file = "pluggy-1.4.0.tar.gz", hash = "sha256:8c85c2876142a764e5b7548e7d9a0e0ddb46f5185161049a79b7e974454223be"},
+ {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"},
+ {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"},
]
[package.extras]
@@ -2412,15 +2416,29 @@ pyyaml = "*"
[package.extras]
extra = ["pygments (>=2.12)"]
+[[package]]
+name = "pyparsing"
+version = "3.1.2"
+description = "pyparsing module - Classes and methods to define and execute parsing grammars"
+optional = false
+python-versions = ">=3.6.8"
+files = [
+ {file = "pyparsing-3.1.2-py3-none-any.whl", hash = "sha256:f9db75911801ed778fe61bb643079ff86601aca99fcae6345aa67292038fb742"},
+ {file = "pyparsing-3.1.2.tar.gz", hash = "sha256:a1bac0ce561155ecc3ed78ca94d3c9378656ad4c94c1270de543f621420f94ad"},
+]
+
+[package.extras]
+diagrams = ["jinja2", "railroad-diagrams"]
+
[[package]]
name = "pytest"
-version = "8.1.1"
+version = "8.2.1"
description = "pytest: simple powerful testing with Python"
optional = false
python-versions = ">=3.8"
files = [
- {file = "pytest-8.1.1-py3-none-any.whl", hash = "sha256:2a8386cfc11fa9d2c50ee7b2a57e7d898ef90470a7a34c4b949ff59662bb78b7"},
- {file = "pytest-8.1.1.tar.gz", hash = "sha256:ac978141a75948948817d360297b7aae0fcb9d6ff6bc9ec6d514b85d5a65c044"},
+ {file = "pytest-8.2.1-py3-none-any.whl", hash = "sha256:faccc5d332b8c3719f40283d0d44aa5cf101cec36f88cde9ed8f2bc0538612b1"},
+ {file = "pytest-8.2.1.tar.gz", hash = "sha256:5046e5b46d8e4cac199c373041f26be56fdb81eb4e67dc11d4e10811fc3408fd"},
]
[package.dependencies]
@@ -2428,11 +2446,11 @@ colorama = {version = "*", markers = "sys_platform == \"win32\""}
exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""}
iniconfig = "*"
packaging = "*"
-pluggy = ">=1.4,<2.0"
+pluggy = ">=1.5,<2.0"
tomli = {version = ">=1", markers = "python_version < \"3.11\""}
[package.extras]
-testing = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"]
+dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"]
[[package]]
name = "pytest-asyncio"
@@ -2523,18 +2541,18 @@ pytest = ">=6.2.5"
[[package]]
name = "pytest-xdist"
-version = "3.5.0"
+version = "3.6.1"
description = "pytest xdist plugin for distributed testing, most importantly across multiple CPUs"
optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.8"
files = [
- {file = "pytest-xdist-3.5.0.tar.gz", hash = "sha256:cbb36f3d67e0c478baa57fa4edc8843887e0f6cfc42d677530a36d7472b32d8a"},
- {file = "pytest_xdist-3.5.0-py3-none-any.whl", hash = "sha256:d075629c7e00b611df89f490a5063944bee7a4362a5ff11c7cc7824a03dfce24"},
+ {file = "pytest_xdist-3.6.1-py3-none-any.whl", hash = "sha256:9ed4adfb68a016610848639bb7e02c9352d5d9f03d04809919e2dafc3be4cca7"},
+ {file = "pytest_xdist-3.6.1.tar.gz", hash = "sha256:ead156a4db231eec769737f57668ef58a2084a34b2e55c4a8fa20d861107300d"},
]
[package.dependencies]
-execnet = ">=1.1"
-pytest = ">=6.2.0"
+execnet = ">=2.1"
+pytest = ">=7.0.0"
[package.extras]
psutil = ["psutil (>=3.0)"]
@@ -2818,13 +2836,13 @@ files = [
[[package]]
name = "requests"
-version = "2.31.0"
+version = "2.32.0"
description = "Python HTTP for Humans."
optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.8"
files = [
- {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"},
- {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"},
+ {file = "requests-2.32.0-py3-none-any.whl", hash = "sha256:f2c3881dddb70d056c5bd7600a4fae312b2a300e39be6a118d30b90bd27262b5"},
+ {file = "requests-2.32.0.tar.gz", hash = "sha256:fa5490319474c82ef1d2c9bc459d3652e3ae4ef4c4ebdd18a21145a47ca4b6b8"},
]
[package.dependencies]
@@ -2979,28 +2997,28 @@ files = [
[[package]]
name = "ruff"
-version = "0.4.2"
+version = "0.4.4"
description = "An extremely fast Python linter and code formatter, written in Rust."
optional = false
python-versions = ">=3.7"
files = [
- {file = "ruff-0.4.2-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:8d14dc8953f8af7e003a485ef560bbefa5f8cc1ad994eebb5b12136049bbccc5"},
- {file = "ruff-0.4.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:24016ed18db3dc9786af103ff49c03bdf408ea253f3cb9e3638f39ac9cf2d483"},
- {file = "ruff-0.4.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e2e06459042ac841ed510196c350ba35a9b24a643e23db60d79b2db92af0c2b"},
- {file = "ruff-0.4.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3afabaf7ba8e9c485a14ad8f4122feff6b2b93cc53cd4dad2fd24ae35112d5c5"},
- {file = "ruff-0.4.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:799eb468ea6bc54b95527143a4ceaf970d5aa3613050c6cff54c85fda3fde480"},
- {file = "ruff-0.4.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:ec4ba9436a51527fb6931a8839af4c36a5481f8c19e8f5e42c2f7ad3a49f5069"},
- {file = "ruff-0.4.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6a2243f8f434e487c2a010c7252150b1fdf019035130f41b77626f5655c9ca22"},
- {file = "ruff-0.4.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8772130a063f3eebdf7095da00c0b9898bd1774c43b336272c3e98667d4fb8fa"},
- {file = "ruff-0.4.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ab165ef5d72392b4ebb85a8b0fbd321f69832a632e07a74794c0e598e7a8376"},
- {file = "ruff-0.4.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:1f32cadf44c2020e75e0c56c3408ed1d32c024766bd41aedef92aa3ca28eef68"},
- {file = "ruff-0.4.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:22e306bf15e09af45ca812bc42fa59b628646fa7c26072555f278994890bc7ac"},
- {file = "ruff-0.4.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:82986bb77ad83a1719c90b9528a9dd663c9206f7c0ab69282af8223566a0c34e"},
- {file = "ruff-0.4.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:652e4ba553e421a6dc2a6d4868bc3b3881311702633eb3672f9f244ded8908cd"},
- {file = "ruff-0.4.2-py3-none-win32.whl", hash = "sha256:7891ee376770ac094da3ad40c116258a381b86c7352552788377c6eb16d784fe"},
- {file = "ruff-0.4.2-py3-none-win_amd64.whl", hash = "sha256:5ec481661fb2fd88a5d6cf1f83403d388ec90f9daaa36e40e2c003de66751798"},
- {file = "ruff-0.4.2-py3-none-win_arm64.whl", hash = "sha256:cbd1e87c71bca14792948c4ccb51ee61c3296e164019d2d484f3eaa2d360dfaf"},
- {file = "ruff-0.4.2.tar.gz", hash = "sha256:33bcc160aee2520664bc0859cfeaebc84bb7323becff3f303b8f1f2d81cb4edc"},
+ {file = "ruff-0.4.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:29d44ef5bb6a08e235c8249294fa8d431adc1426bfda99ed493119e6f9ea1bf6"},
+ {file = "ruff-0.4.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:c4efe62b5bbb24178c950732ddd40712b878a9b96b1d02b0ff0b08a090cbd891"},
+ {file = "ruff-0.4.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c8e2f1e8fc12d07ab521a9005d68a969e167b589cbcaee354cb61e9d9de9c15"},
+ {file = "ruff-0.4.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:60ed88b636a463214905c002fa3eaab19795679ed55529f91e488db3fe8976ab"},
+ {file = "ruff-0.4.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b90fc5e170fc71c712cc4d9ab0e24ea505c6a9e4ebf346787a67e691dfb72e85"},
+ {file = "ruff-0.4.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:8e7e6ebc10ef16dcdc77fd5557ee60647512b400e4a60bdc4849468f076f6eef"},
+ {file = "ruff-0.4.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b9ddb2c494fb79fc208cd15ffe08f32b7682519e067413dbaf5f4b01a6087bcd"},
+ {file = "ruff-0.4.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c51c928a14f9f0a871082603e25a1588059b7e08a920f2f9fa7157b5bf08cfe9"},
+ {file = "ruff-0.4.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b5eb0a4bfd6400b7d07c09a7725e1a98c3b838be557fee229ac0f84d9aa49c36"},
+ {file = "ruff-0.4.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:b1867ee9bf3acc21778dcb293db504692eda5f7a11a6e6cc40890182a9f9e595"},
+ {file = "ruff-0.4.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:1aecced1269481ef2894cc495647392a34b0bf3e28ff53ed95a385b13aa45768"},
+ {file = "ruff-0.4.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:9da73eb616b3241a307b837f32756dc20a0b07e2bcb694fec73699c93d04a69e"},
+ {file = "ruff-0.4.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:958b4ea5589706a81065e2a776237de2ecc3e763342e5cc8e02a4a4d8a5e6f95"},
+ {file = "ruff-0.4.4-py3-none-win32.whl", hash = "sha256:cb53473849f011bca6e754f2cdf47cafc9c4f4ff4570003a0dad0b9b6890e876"},
+ {file = "ruff-0.4.4-py3-none-win_amd64.whl", hash = "sha256:424e5b72597482543b684c11def82669cc6b395aa8cc69acc1858b5ef3e5daae"},
+ {file = "ruff-0.4.4-py3-none-win_arm64.whl", hash = "sha256:39df0537b47d3b597293edbb95baf54ff5b49589eb7ff41926d8243caa995ea6"},
+ {file = "ruff-0.4.4.tar.gz", hash = "sha256:f87ea42d5cdebdc6a69761a9d0bc83ae9b3b30d0ad78952005ba6568d6c022af"},
]
[[package]]
@@ -3037,13 +3055,13 @@ pbr = "*"
[[package]]
name = "sentry-sdk"
-version = "2.0.1"
+version = "2.2.0"
description = "Python client for Sentry (https://sentry.io)"
optional = false
python-versions = ">=3.6"
files = [
- {file = "sentry_sdk-2.0.1-py2.py3-none-any.whl", hash = "sha256:b54c54a2160f509cf2757260d0cf3885b608c6192c2555a3857e3a4d0f84bdb3"},
- {file = "sentry_sdk-2.0.1.tar.gz", hash = "sha256:c278e0f523f6f0ee69dc43ad26dcdb1202dffe5ac326ae31472e012d941bee21"},
+ {file = "sentry_sdk-2.2.0-py2.py3-none-any.whl", hash = "sha256:674f58da37835ea7447fe0e34c57b4a4277fad558b0a7cb4a6c83bcb263086be"},
+ {file = "sentry_sdk-2.2.0.tar.gz", hash = "sha256:70eca103cf4c6302365a9d7cf522e7ed7720828910eb23d43ada8e50d1ecda9d"},
]
[package.dependencies]
@@ -3052,6 +3070,7 @@ urllib3 = ">=1.26.11"
[package.extras]
aiohttp = ["aiohttp (>=3.5)"]
+anthropic = ["anthropic (>=0.16)"]
arq = ["arq (>=0.23)"]
asyncpg = ["asyncpg (>=0.23)"]
beam = ["apache-beam (>=2.12)"]
@@ -3067,6 +3086,8 @@ flask = ["blinker (>=1.1)", "flask (>=0.11)", "markupsafe"]
grpcio = ["grpcio (>=1.21.1)"]
httpx = ["httpx (>=0.16.0)"]
huey = ["huey (>=2)"]
+huggingface-hub = ["huggingface-hub (>=0.22)"]
+langchain = ["langchain (>=0.0.210)"]
loguru = ["loguru (>=0.5)"]
openai = ["openai (>=1.0.0)", "tiktoken (>=0.3.0)"]
opentelemetry = ["opentelemetry-distro (>=0.35b0)"]
@@ -3606,4 +3627,4 @@ validation = ["fastjsonschema"]
[metadata]
lock-version = "2.0"
python-versions = ">=3.8,<4.0.0"
-content-hash = "b35174c5fc5b4c6a343728478660c2efaea55693034f852b4f6299af63e2ac7b"
+content-hash = "6780ba0ed4ad3d75bbbc8df7a18584d65a6003c85ecf52cec3a65c73992f93da"
diff --git a/pyproject.toml b/pyproject.toml
index 35dc0765b60..416ff8ab8a2 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[tool.poetry]
name = "aws_lambda_powertools"
-version = "2.37.0"
+version = "2.38.1"
description = "Powertools for AWS Lambda (Python) is a developer toolkit to implement Serverless best practices and increase developer velocity."
authors = ["Amazon Web Services"]
include = ["aws_lambda_powertools/py.typed", "THIRD-PARTY-LICENSES"]
@@ -51,7 +51,7 @@ jsonpath-ng = { version = "^1.6.0", optional = true }
[tool.poetry.dev-dependencies]
coverage = { extras = ["toml"], version = "^7.5" }
-pytest = "^8.1.1"
+pytest = "^8.2.1"
black = "^24.4"
boto3 = "^1.26.164"
isort = "^5.13.2"
@@ -63,36 +63,36 @@ bandit = "^1.7.8"
radon = "^6.0.1"
xenon = "^0.9.1"
mkdocs-git-revision-date-plugin = "^0.3.2"
-mike = "^1.1.2"
-pytest-xdist = "^3.5.0"
-aws-cdk-lib = "^2.139.0"
+mike = "^2.1.1"
+pytest-xdist = "^3.6.1"
+aws-cdk-lib = "^2.142.1"
"aws-cdk.aws-apigatewayv2-alpha" = "^2.38.1-alpha.0"
"aws-cdk.aws-apigatewayv2-integrations-alpha" = "^2.38.1-alpha.0"
"aws-cdk.aws-apigatewayv2-authorizers-alpha" = "^2.38.1-alpha.0"
-"aws-cdk.aws-lambda-python-alpha" = "^2.139.0a0"
-"cdklabs.generative-ai-cdk-constructs" = "^0.1.131"
+"aws-cdk.aws-lambda-python-alpha" = "^2.142.1a0"
+"cdklabs.generative-ai-cdk-constructs" = "^0.1.154"
pytest-benchmark = "^4.0.0"
mypy-boto3-appconfig = "^1.34.58"
mypy-boto3-cloudformation = "^1.34.84"
mypy-boto3-cloudwatch = "^1.34.83"
-mypy-boto3-dynamodb = "^1.34.91"
+mypy-boto3-dynamodb = "^1.34.97"
mypy-boto3-lambda = "^1.34.77"
mypy-boto3-logs = "^1.34.66"
-mypy-boto3-secretsmanager = "^1.34.72"
+mypy-boto3-secretsmanager = "^1.34.109"
mypy-boto3-ssm = "^1.34.91"
-mypy-boto3-s3 = "^1.34.91"
+mypy-boto3-s3 = "^1.34.105"
mypy-boto3-xray = "^1.34.0"
types-requests = "^2.31.0"
typing-extensions = "^4.6.2"
-mkdocs-material = "^9.5.19"
-filelock = "^3.13.4"
+mkdocs-material = "^9.5.24"
+filelock = "^3.14.0"
checksumdir = "^1.2.0"
mypy-boto3-appconfigdata = "^1.34.24"
ijson = "^3.2.2"
typed-ast = { version = "^1.5.5", python = "< 3.8" }
-hvac = "^2.1.0"
+hvac = "^2.2.0"
aws-requests-auth = "^0.4.3"
-datadog-lambda = "^5.93.0"
+datadog-lambda = "^5.94.0"
[tool.poetry.extras]
parser = ["pydantic"]
@@ -110,12 +110,12 @@ datadog = ["datadog-lambda"]
datamasking = ["aws-encryption-sdk", "jsonpath-ng"]
[tool.poetry.group.dev.dependencies]
-cfn-lint = "0.86.4"
+cfn-lint = "0.87.3"
mypy = "^1.1.1"
types-python-dateutil = "^2.8.19.6"
httpx = ">=0.23.3,<0.28.0"
sentry-sdk = ">=1.22.2,<3.0.0"
-ruff = ">=0.0.272,<0.4.3"
+ruff = ">=0.0.272,<0.4.5"
retry2 = "^0.9.5"
pytest-socket = ">=0.6,<0.8"
types-redis = "^4.6.0.7"
@@ -129,6 +129,7 @@ omit = [
"aws_lambda_powertools/exceptions/*",
"aws_lambda_powertools/utilities/parser/types.py",
"aws_lambda_powertools/utilities/jmespath_utils/envelopes.py",
+ "aws_lambda_powertools/metrics/metric.py" # barrel import (export-only)
]
branch = true
diff --git a/tests/events/s3EventBridgeNotificationObjectDeletedEvent.json b/tests/events/s3EventBridgeNotificationObjectDeletedEvent.json
index af52ee2fef0..7c0995338a8 100644
--- a/tests/events/s3EventBridgeNotificationObjectDeletedEvent.json
+++ b/tests/events/s3EventBridgeNotificationObjectDeletedEvent.json
@@ -16,8 +16,6 @@
},
"object": {
"key": "IMG_m7fzo3.jpg",
- "size": 184662,
- "etag": "4e68adba0abe2dc8653dc3354e14c01d",
"sequencer": "006408CAD69598B05E"
},
"request-id": "0BH729840619AG5K",
@@ -26,4 +24,4 @@
"reason": "DeleteObject",
"deletion-type": "Delete Marker Created"
}
-}
\ No newline at end of file
+}
diff --git a/tests/functional/event_handler/test_api_gateway.py b/tests/functional/event_handler/test_api_gateway.py
index 3929496be50..14af1ad175e 100644
--- a/tests/functional/event_handler/test_api_gateway.py
+++ b/tests/functional/event_handler/test_api_gateway.py
@@ -291,12 +291,16 @@ def delete_func():
def patch_func():
raise RuntimeError()
+ @app.head("/no_matching_head")
+ def head_func():
+ raise RuntimeError()
+
def handler(event, context):
return app.resolve(event, context)
# Also check the route configurations
routes = app._static_routes
- assert len(routes) == 5
+ assert len(routes) == 6
for route in routes:
if route.func == get_func:
assert route.method == "GET"
@@ -308,6 +312,8 @@ def handler(event, context):
assert route.method == "DELETE"
elif route.func == patch_func:
assert route.method == "PATCH"
+ elif route.func == head_func:
+ assert route.method == "HEAD"
# WHEN calling the handler
# THEN return a 404
diff --git a/tests/functional/event_handler/test_openapi_swagger.py b/tests/functional/event_handler/test_openapi_swagger.py
index 11ec0cf24da..a8d9326efcf 100644
--- a/tests/functional/event_handler/test_openapi_swagger.py
+++ b/tests/functional/event_handler/test_openapi_swagger.py
@@ -118,6 +118,18 @@ def test_openapi_swagger_with_rest_api_stage():
assert "ui.specActions.updateUrl('/prod/swagger?format=json')" in result["body"]
+def test_openapi_swagger_with_persist_authorization():
+ app = APIGatewayRestResolver(enable_validation=True)
+ app.enable_swagger(persist_authorization=True)
+
+ event = load_event("apiGatewayProxyEvent.json")
+ event["path"] = "/swagger"
+
+ result = app(event, {})
+ assert result["statusCode"] == 200
+ assert "persistAuthorization: true" in result["body"]
+
+
def test_openapi_swagger_oauth2_without_powertools_dev():
with pytest.raises(ValueError) as exc:
OAuth2Config(app_name="OAuth2 app", client_id="client_id", client_secret="verysecret")
diff --git a/tests/functional/test_logger_utils.py b/tests/functional/test_logger_utils.py
index 7ca9e1198ac..5a95e2c54a2 100644
--- a/tests/functional/test_logger_utils.py
+++ b/tests/functional/test_logger_utils.py
@@ -131,8 +131,8 @@ def test_copy_config_to_ext_loggers_include_exclude(stdout, logger, log_level):
# AND external logger_1 is also in EXCLUDE list
utils.copy_config_to_registered_loggers(
source_logger=powertools_logger,
- include={logger_1.name, logger_2.name},
exclude={logger_1.name},
+ include={logger_1.name, logger_2.name},
)
msg = "test message3"
logger_2.info(msg)
@@ -175,8 +175,8 @@ def test_copy_config_to_ext_loggers_custom_log_level(stdout, logger, log_level,
# AND external logger used with custom log_level
utils.copy_config_to_registered_loggers(
source_logger=powertools_logger,
- include={logger.name},
log_level=level_to_set,
+ include={logger.name},
)
msg = "test message4"
logger.warning(msg)
@@ -263,7 +263,7 @@ def test_copy_config_to_ext_loggers_no_duplicate_logs(stdout, logger, log_level)
# WHEN configuration copied from Powertools for AWS Lambda (Python) logger
# AND external logger used with custom log_level
- utils.copy_config_to_registered_loggers(source_logger=powertools_logger, include={logger.name}, log_level=level)
+ utils.copy_config_to_registered_loggers(source_logger=powertools_logger, log_level=level, include={logger.name})
msg = "test message4"
logger.warning(msg)
@@ -294,3 +294,22 @@ def test_logger_name_is_included_during_copy(stdout, logger, log_level):
assert logger1_log["name"] == logger_1.name
assert logger2_log["name"] == logger_2.name
assert pt_log["name"] == powertools_logger.name
+
+
+def test_copy_config_to_ext_loggers_but_preserve_log_levels(stdout, logger, log_level):
+ # GIVEN two external loggers and Powertools for AWS Lambda (Python) logger initialized
+ third_party_log_level = logging.CRITICAL
+
+ logger_1 = logger()
+ logger_2 = logger()
+ logger_1.setLevel(third_party_log_level)
+ logger_2.setLevel(third_party_log_level)
+
+ powertools_logger = Logger(service=service_name(), stream=stdout)
+
+ # WHEN configuration copied from Powertools for AWS Lambda (Python) logger to ALL external loggers
+ utils.copy_config_to_registered_loggers(source_logger=powertools_logger, ignore_log_level=True)
+
+ # THEN external loggers log levels should be preserved
+ assert logger_1.level != powertools_logger.log_level
+ assert logger_2.level != powertools_logger.log_level
diff --git a/tests/unit/data_classes/test_api_gateway_proxy_event.py b/tests/unit/data_classes/test_api_gateway_proxy_event.py
index 7d464372135..d86e4b5e19b 100644
--- a/tests/unit/data_classes/test_api_gateway_proxy_event.py
+++ b/tests/unit/data_classes/test_api_gateway_proxy_event.py
@@ -89,8 +89,8 @@ def test_api_gateway_proxy_event():
assert request_context.api_id == request_context_raw["apiId"]
authorizer = request_context.authorizer
- assert authorizer.claims is None
- assert authorizer.scopes is None
+ assert authorizer.claims == {}
+ assert authorizer.scopes == []
assert request_context.domain_name == request_context_raw["domainName"]
assert request_context.domain_prefix == request_context_raw["domainPrefix"]
@@ -144,8 +144,8 @@ def test_api_gateway_proxy_event_with_principal_id():
request_context = parsed_event.request_context
authorizer = request_context.authorizer
- assert authorizer.claims is None
- assert authorizer.scopes is None
+ assert authorizer.claims == {}
+ assert authorizer.scopes == []
assert authorizer.principal_id == raw_event["requestContext"]["authorizer"]["principalId"]
assert authorizer.integration_latency == raw_event["requestContext"]["authorizer"]["integrationLatency"]
assert authorizer.get("integrationStatus", "failed") == "failed"
diff --git a/tests/unit/data_classes/test_lambda_function_url.py b/tests/unit/data_classes/test_lambda_function_url.py
index b7e8003d6c7..f8ce71b1543 100644
--- a/tests/unit/data_classes/test_lambda_function_url.py
+++ b/tests/unit/data_classes/test_lambda_function_url.py
@@ -1,4 +1,5 @@
from aws_lambda_powertools.utilities.data_classes import LambdaFunctionUrlEvent
+from aws_lambda_powertools.utilities.data_classes.api_gateway_proxy_event import RequestContextV2Authorizer
from tests.functional.utils import load_event
@@ -47,7 +48,7 @@ def test_lambda_function_url_event():
assert http.source_ip == http_raw["sourceIp"]
assert http.user_agent == http_raw["userAgent"]
- assert request_context.authorizer is None
+ assert isinstance(request_context.authorizer, RequestContextV2Authorizer)
def test_lambda_function_url_event_iam():
@@ -102,9 +103,9 @@ def test_lambda_function_url_event_iam():
authorizer = request_context.authorizer
assert authorizer is not None
- assert authorizer.jwt_claim is None
- assert authorizer.jwt_scopes is None
- assert authorizer.get_lambda is None
+ assert authorizer.jwt_claim == {}
+ assert authorizer.jwt_scopes == []
+ assert authorizer.get_lambda == {}
iam = authorizer.iam
iam_raw = raw_event["requestContext"]["authorizer"]["iam"]
@@ -112,9 +113,9 @@ def test_lambda_function_url_event_iam():
assert iam.access_key == iam_raw["accessKey"]
assert iam.account_id == iam_raw["accountId"]
assert iam.caller_id == iam_raw["callerId"]
- assert iam.cognito_amr is None
- assert iam.cognito_identity_id is None
- assert iam.cognito_identity_pool_id is None
- assert iam.principal_org_id is None
+ assert iam.cognito_amr == []
+ assert iam.cognito_identity_id == ""
+ assert iam.cognito_identity_pool_id == ""
+ assert iam.principal_org_id == ""
assert iam.user_id == iam_raw["userId"]
assert iam.user_arn == iam_raw["userArn"]
diff --git a/tests/unit/data_classes/test_s3_eventbridge_notification.py b/tests/unit/data_classes/test_s3_eventbridge_notification.py
index 391c3fa1788..ae27ad2965f 100644
--- a/tests/unit/data_classes/test_s3_eventbridge_notification.py
+++ b/tests/unit/data_classes/test_s3_eventbridge_notification.py
@@ -26,10 +26,10 @@ def test_s3_eventbridge_notification_detail_parsed(raw_event: Dict):
assert parsed_event.detail.deletion_type == raw_event["detail"].get("deletion-type")
assert parsed_event.detail.destination_access_tier == raw_event["detail"].get("destination-access-tier")
assert parsed_event.detail.destination_storage_class == raw_event["detail"].get("destination-storage-class")
- assert parsed_event.detail.object.etag == raw_event["detail"]["object"]["etag"]
+ assert parsed_event.detail.object.etag == raw_event["detail"]["object"].get("etag", "")
assert parsed_event.detail.object.key == raw_event["detail"]["object"]["key"]
assert parsed_event.detail.object.sequencer == raw_event["detail"]["object"]["sequencer"]
- assert parsed_event.detail.object.size == raw_event["detail"]["object"]["size"]
+ assert parsed_event.detail.object.size == raw_event["detail"]["object"].get("size")
assert parsed_event.detail.reason == raw_event["detail"].get("reason")
assert parsed_event.detail.version == raw_event["detail"].get("version")
assert parsed_event.detail.request_id == raw_event["detail"]["request-id"]
diff --git a/tests/unit/parser/test_s3_notification.py b/tests/unit/parser/test_s3_notification.py
index c77c70095a3..ca83851d06c 100644
--- a/tests/unit/parser/test_s3_notification.py
+++ b/tests/unit/parser/test_s3_notification.py
@@ -52,8 +52,8 @@ def test_s3_eventbridge_notification_object_deleted_event():
assert model.detail.version == raw_event["detail"]["version"]
assert model.detail.bucket.name == raw_event["detail"]["bucket"]["name"]
assert model.detail.object.key == raw_event["detail"]["object"]["key"]
- assert model.detail.object.size == raw_event["detail"]["object"]["size"]
- assert model.detail.object.etag == raw_event["detail"]["object"]["etag"]
+ assert model.detail.object.size == raw_event["detail"]["object"].get("size")
+ assert model.detail.object.etag == raw_event["detail"]["object"].get("etag", "")
assert model.detail.object.sequencer == raw_event["detail"]["object"]["sequencer"]
assert model.detail.request_id == raw_event["detail"]["request-id"]
assert model.detail.requester == raw_event["detail"]["requester"]