diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 00000000000..d41dd7086a3 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,3 @@ +# https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners + +* @awslabs/aws-lambda-powertools-python diff --git a/.github/ISSUE_TEMPLATE/maintenance.yml b/.github/ISSUE_TEMPLATE/maintenance.yml new file mode 100644 index 00000000000..2f60a0f013a --- /dev/null +++ b/.github/ISSUE_TEMPLATE/maintenance.yml @@ -0,0 +1,73 @@ +name: Maintenance +description: Suggest an activity to help address tech debt, governance, and anything internal +title: "Maintenance: TITLE" +labels: ["internal", "triage"] +body: + - type: markdown + attributes: + value: | + Thank you for taking the time to help us improve operational excellence. + + *Future readers*: Please react with 👍 and your use case to help us understand customer demand. + - type: textarea + id: activity + attributes: + label: Summary + description: Please provide an overview in one or two paragraphs + validations: + required: true + - type: textarea + id: importance + attributes: + label: Why is this needed? + description: Please help us understand the value so we can prioritize it accordingly + validations: + required: true + - type: dropdown + id: area + attributes: + label: Which area does this relate to? + multiple: true + options: + - Automation + - Governance + - Tests + - Static typing + - Tracer + - Logger + - Metrics + - Event Handler - REST API + - Event Handler - GraphQL API + - Middleware factory + - Parameters + - Batch processing + - Typing + - Validation + - Event Source Data Classes + - Parser + - Idempotency + - Feature flags + - JMESPath functions + - Other + - type: textarea + id: suggestion + attributes: + label: Solution + description: If available, please share what a good solution would look like + validations: + required: false + - type: checkboxes + id: acknowledgment + attributes: + label: Acknowledgment + options: + - label: This request meets [Lambda Powertools Tenets](https://awslabs.github.io/aws-lambda-powertools-python/latest/#tenets) + required: true + - label: Should this be considered in other Lambda Powertools languages? i.e. [Java](https://github.com/awslabs/aws-lambda-powertools-java/), [TypeScript](https://github.com/awslabs/aws-lambda-powertools-typescript/) + required: false + - type: markdown + attributes: + value: | + --- + + **Disclaimer**: We value your time and bandwidth. As such, any pull requests created on non-triaged issues might not be successful. diff --git a/.github/scripts/enforce_acknowledgment.js b/.github/scripts/enforce_acknowledgment.js new file mode 100644 index 00000000000..3e3be636ede --- /dev/null +++ b/.github/scripts/enforce_acknowledgment.js @@ -0,0 +1,40 @@ +const { +PR_ACTION, +PR_AUTHOR, +PR_BODY, +PR_NUMBER, +IGNORE_AUTHORS, +LABEL_BLOCK, +LABEL_BLOCK_REASON +} = require("./constants") + +module.exports = async ({github, context, core}) => { + if (IGNORE_AUTHORS.includes(PR_AUTHOR)) { + return core.notice("Author in IGNORE_AUTHORS list; skipping...") + } + + if (PR_ACTION != "opened") { + return core.notice("Only newly open PRs are labelled to avoid spam; skipping") + } + + const RELATED_ISSUE_REGEX = /Issue number:[^\d\r\n]+(?\d+)/; + const isMatch = RELATED_ISSUE_REGEX.exec(PR_BODY); + if (isMatch == null) { + core.info(`No related issue found, maybe the author didn't use the template but there is one.`) + + let msg = "No related issues found. Please ensure there is an open issue related to this change to avoid significant delays or closure."; + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + body: msg, + issue_number: PR_NUMBER, + }); + + return await github.rest.issues.addLabels({ + issue_number: PR_NUMBER, + owner: context.repo.owner, + repo: context.repo.repo, + labels: [LABEL_BLOCK, LABEL_BLOCK_REASON] + }) + } +} diff --git a/.github/scripts/label_related_issue.js b/.github/scripts/label_related_issue.js index b55a56d795b..1da4cdc310e 100644 --- a/.github/scripts/label_related_issue.js +++ b/.github/scripts/label_related_issue.js @@ -58,6 +58,6 @@ module.exports = async ({github, context, core}) => { issue_number: relatedIssueNumber, owner: context.repo.owner, repo: context.repo.repo, - labels: [releaseLabel] + labels: [relatedIssueNumber] }) } diff --git a/.github/workflows/label_pr_on_title.yml b/.github/workflows/label_pr_on_title.yml index 562959bb516..3815a49e9bd 100644 --- a/.github/workflows/label_pr_on_title.yml +++ b/.github/workflows/label_pr_on_title.yml @@ -14,6 +14,7 @@ jobs: uses: ./.github/workflows/reusable_export_pr_details.yml with: record_pr_workflow_id: ${{ github.event.workflow_run.id }} + workflow_origin: ${{ github.event.repository.full_name }} secrets: token: ${{ secrets.GITHUB_TOKEN }} label_pr: diff --git a/.github/workflows/on_merged_pr.yml b/.github/workflows/on_merged_pr.yml index 3f1bcb57237..cd97e1c306e 100644 --- a/.github/workflows/on_merged_pr.yml +++ b/.github/workflows/on_merged_pr.yml @@ -12,6 +12,7 @@ jobs: uses: ./.github/workflows/reusable_export_pr_details.yml with: record_pr_workflow_id: ${{ github.event.workflow_run.id }} + workflow_origin: ${{ github.event.repository.full_name }} secrets: token: ${{ secrets.GITHUB_TOKEN }} release_label_on_merge: diff --git a/.github/workflows/on_opened_pr.yml b/.github/workflows/on_opened_pr.yml index 3d5aab45b5d..2663d605325 100644 --- a/.github/workflows/on_opened_pr.yml +++ b/.github/workflows/on_opened_pr.yml @@ -12,6 +12,7 @@ jobs: uses: ./.github/workflows/reusable_export_pr_details.yml with: record_pr_workflow_id: ${{ github.event.workflow_run.id }} + workflow_origin: ${{ github.event.repository.full_name }} secrets: token: ${{ secrets.GITHUB_TOKEN }} check_related_issue: @@ -19,6 +20,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 + - name: "Debug workflow_run event" + run: echo "${{ github }}" - name: "Ensure related issue is present" uses: actions/github-script@v6 env: diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 1c7cd4c2002..c2af2f2fae5 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -31,6 +31,7 @@ on: jobs: release: + environment: release runs-on: ubuntu-latest outputs: RELEASE_VERSION: ${{ steps.release_version.outputs.RELEASE_VERSION }} @@ -84,16 +85,15 @@ jobs: env: PYPI_USERNAME: __token__ PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }} + - name: aws credentials + uses: aws-actions/configure-aws-credentials@v1 + with: + aws-region: eu-west-1 + role-to-assume: ${{ secrets.AWS_SAR_ROLE_ARN }} - name: publish lambda layer in SAR by triggering the internal codepipeline run: | aws ssm put-parameter --name "powertools-python-release-version" --value $RELEASE_VERSION --overwrite - aws codepipeline start-pipeline-execution --name ${{ secrets.CODEPIPELINE_NAME }} - env: - # Maintenance: Migrate to new OAuth mechanism - AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - AWS_DEFAULT_REGION: eu-west-1 - AWS_DEFAULT_OUTPUT: json + aws codepipeline start-pipeline-execution --name ${{ secrets.AWS_SAR_PIPELINE_NAME }} docs: needs: release diff --git a/.github/workflows/publish_layer.yml b/.github/workflows/publish_layer.yml index 81d46226a4c..2ad83624111 100644 --- a/.github/workflows/publish_layer.yml +++ b/.github/workflows/publish_layer.yml @@ -16,7 +16,6 @@ on: types: - completed - jobs: build-layer: runs-on: ubuntu-latest @@ -65,18 +64,18 @@ jobs: needs: - build-layer uses: ./.github/workflows/reusable_deploy_layer_stack.yml + secrets: inherit with: stage: "BETA" artefact-name: "cdk-layer-artefact" - secrets: - target-account-role: arn:aws:iam::${{ secrets.LAYERS_BETA_ACCOUNT }}:role/${{ secrets.AWS_GITHUB_OIDC_ROLE }} + environment: "layer-beta" deploy-prod: needs: - deploy-beta uses: ./.github/workflows/reusable_deploy_layer_stack.yml + secrets: inherit with: stage: "PROD" artefact-name: "cdk-layer-artefact" - secrets: - target-account-role: arn:aws:iam::${{ secrets.LAYERS_PROD_ACCOUNT }}:role/${{ secrets.AWS_GITHUB_OIDC_ROLE }} + environment: "layer-prod" diff --git a/.github/workflows/reusable_deploy_layer_stack.yml b/.github/workflows/reusable_deploy_layer_stack.yml index 45c97860438..705ef530853 100644 --- a/.github/workflows/reusable_deploy_layer_stack.yml +++ b/.github/workflows/reusable_deploy_layer_stack.yml @@ -13,43 +13,45 @@ on: artefact-name: required: true type: string - secrets: - target-account-role: + environment: required: true + type: string jobs: deploy-cdk-stack: runs-on: ubuntu-latest + environment: ${{ inputs.environment }} defaults: run: working-directory: ./layer strategy: fail-fast: false matrix: - region: [ - "af-south-1", - # "eu-central-1", - # "us-east-1", - # "us-east-2", - # "us-west-1", - # "us-west-2", - # "ap-east-1", - # "ap-south-1", - # "ap-northeast-1", - # "ap-northeast-2", - # "ap-southeast-1", - # "ap-southeast-2", - # "ca-central-1", - # "eu-west-1", - # "eu-west-2", - # "eu-west-3", - # "eu-south-1", - # "eu-north-1", - # "sa-east-1", - # "ap-southeast-3", - # "ap-northeast-3", - # "me-south-1" - ] + region: + [ + "af-south-1", + "eu-central-1", + "us-east-1", + "us-east-2", + "us-west-1", + "us-west-2", + "ap-east-1", + "ap-south-1", + "ap-northeast-1", + "ap-northeast-2", + "ap-southeast-1", + "ap-southeast-2", + "ca-central-1", + "eu-west-1", + "eu-west-2", + "eu-west-3", + "eu-south-1", + "eu-north-1", + "sa-east-1", + "ap-southeast-3", + "ap-northeast-3", + "me-south-1", + ] steps: - name: checkout uses: actions/checkout@v3 @@ -57,7 +59,7 @@ jobs: uses: aws-actions/configure-aws-credentials@v1 with: aws-region: ${{ matrix.region }} - role-to-assume: ${{ secrets.target-account-role }} + role-to-assume: ${{ secrets.AWS_LAYERS_ROLE_ARN }} - name: Setup Node.js uses: actions/setup-node@v3 with: diff --git a/.github/workflows/reusable_export_pr_details.yml b/.github/workflows/reusable_export_pr_details.yml index dcbb959a4ea..86c3e7d645e 100644 --- a/.github/workflows/reusable_export_pr_details.yml +++ b/.github/workflows/reusable_export_pr_details.yml @@ -6,6 +6,9 @@ on: record_pr_workflow_id: required: true type: number + workflow_origin: # see https://github.com/awslabs/aws-lambda-powertools-python/issues/1349 + required: true + type: string secrets: token: required: true @@ -32,6 +35,8 @@ on: jobs: export_pr_details: + # see https://github.com/awslabs/aws-lambda-powertools-python/issues/1349 + if: inputs.workflow_origin == 'awslabs/aws-lambda-powertools-python' runs-on: ubuntu-latest env: FILENAME: pr.txt diff --git a/CHANGELOG.md b/CHANGELOG.md index 274ce07676c..f05bfdf87ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,48 @@ # Unreleased + +## [v1.26.5] - 2022-07-20 +## Bug Fixes + +* mathc the name of the cdk synth from the build phase +* typo in input for layer workflow +* no need to cache npm since we only install cdk cli and don't have .lock files +* add entire ARN role instead of account and role name +* path to artefact +* unzip the right artifact name +* download artefact into the layer dir +* sight, yes a whitespace character breaks the build +* **ci:** checkout project before validating related issue workflow +* **ci:** install poetry before calling setup/python with cache ([#1315](https://github.com/awslabs/aws-lambda-powertools-python/issues/1315)) +* **ci:** remove additional quotes in PR action ([#1317](https://github.com/awslabs/aws-lambda-powertools-python/issues/1317)) +* **ci:** lambda layer workflow release version and conditionals ([#1316](https://github.com/awslabs/aws-lambda-powertools-python/issues/1316)) +* **ci:** fetch all git info so we can check tags +* **ci:** lambda layer workflow release version and conditionals ([#1316](https://github.com/awslabs/aws-lambda-powertools-python/issues/1316)) +* **ci:** keep layer version permission ([#1318](https://github.com/awslabs/aws-lambda-powertools-python/issues/1318)) +* **ci:** regex to catch combination of related issues workflow +* **deps:** correct mypy types as dev dependency ([#1322](https://github.com/awslabs/aws-lambda-powertools-python/issues/1322)) +* **logger:** preserve std keys when using custom formatters ([#1264](https://github.com/awslabs/aws-lambda-powertools-python/issues/1264)) + +## Documentation + +* **event-handler:** snippets split, improved, and lint ([#1279](https://github.com/awslabs/aws-lambda-powertools-python/issues/1279)) +* **governance:** typos on PR template fixes [#1314](https://github.com/awslabs/aws-lambda-powertools-python/issues/1314) +* **governance:** add security doc to the root + +## Maintenance + +* **ci:** limits concurrency for docs workflow +* **ci:** adds caching when installing python dependencies ([#1311](https://github.com/awslabs/aws-lambda-powertools-python/issues/1311)) +* **ci:** update project with version 1.26.4 +* **ci:** fix reference error in related_issue +* **deps:** bump constructs from 10.1.1 to 10.1.51 ([#1323](https://github.com/awslabs/aws-lambda-powertools-python/issues/1323)) +* **deps-dev:** bump mypy from 0.961 to 0.971 ([#1320](https://github.com/awslabs/aws-lambda-powertools-python/issues/1320)) +* **governance:** fix typo on semantic commit link introduced in [#1](https://github.com/awslabs/aws-lambda-powertools-python/issues/1)aef4 +* **layers:** add release pipeline in GitHub Actions ([#1278](https://github.com/awslabs/aws-lambda-powertools-python/issues/1278)) +* **layers:** bump to 22 for 1.26.3 + + ## [v1.26.4] - 2022-07-18 ## Bug Fixes @@ -2025,7 +2067,8 @@ * Merge pull request [#5](https://github.com/awslabs/aws-lambda-powertools-python/issues/5) from jfuss/feat/python38 -[Unreleased]: https://github.com/awslabs/aws-lambda-powertools-python/compare/v1.26.4...HEAD +[Unreleased]: https://github.com/awslabs/aws-lambda-powertools-python/compare/v1.26.5...HEAD +[v1.26.5]: https://github.com/awslabs/aws-lambda-powertools-python/compare/v1.26.4...v1.26.5 [v1.26.4]: https://github.com/awslabs/aws-lambda-powertools-python/compare/v1.26.3...v1.26.4 [v1.26.3]: https://github.com/awslabs/aws-lambda-powertools-python/compare/v1.26.2...v1.26.3 [v1.26.2]: https://github.com/awslabs/aws-lambda-powertools-python/compare/v1.26.1...v1.26.2 diff --git a/MAINTAINERS.md b/MAINTAINERS.md index 4ccf87f7b42..7a8d2d2f8e8 100644 --- a/MAINTAINERS.md +++ b/MAINTAINERS.md @@ -57,39 +57,39 @@ Previous active maintainers who contributed to this project. These are the most common labels used by maintainers to triage issues, pull requests (PR), and for project management: -| Label | Usage | Notes | -| ---------------------- | ---------------------------------------------------------------- | --------------------------------------------------------------- | -| triage | New issues that require maintainers review | Issue template | -| bug | Unexpected, reproducible and unintended software behavior | PR/Release automation; Doc snippets are excluded; | -| not-a-bug | New and existing bug reports incorrectly submitted as bug | Analytics | -| documentation | Documentation improvements | PR/Release automation; Doc additions, fixes, etc.; | -| feature-request | New or enhancements to existing features | Issue template | -| typing | New or enhancements to static typing | Issue template | -| RFC | Technical design documents related to a feature request | Issue template | -| bug-upstream | Bug caused by upstream dependency | | -| help wanted | Tasks you want help from anyone to move forward | Bandwidth, complex topics, etc. | -| need-customer-feedback | Tasks that need more feedback before proceeding | 80/20% rule, uncertain, etc. | -| need-more-information | Missing information before making any calls | | -| need-documentation | PR is missing or has incomplete documentation | | -| need-issue | PR is missing a related issue for tracking change | Needs to be automated | -| need-rfc | Feature request requires a RFC to improve discussion | | -| pending-release | Merged changes that will be available soon | Release automation auto-closes/notifies it | -| revisit-in-3-months | Blocked issues/PRs that need to be revisited | Often related to `need-customer-feedback`, prioritization, etc. | -| breaking-change | Changes that will cause customer impact and need careful triage | | -| do-not-merge | PRs that are blocked for varying reasons | Timeline is uncertain | -| size/XS | PRs between 0-9 LOC | PR automation | -| size/S | PRs between 10-29 LOC | PR automation | -| size/M | PRs between 30-99 LOC | PR automation | -| size/L | PRs between 100-499 LOC | PR automation | -| size/XL | PRs between 500-999 LOC, often PRs that grown with feedback | PR automation | -| size/XXL | PRs with 1K+ LOC, largely documentation related | PR automation | -| tests | PRs that add or change tests | PR automation | -| `` | PRs related to a Powertools utility, e.g. `parameters`, `tracer` | PR automation | -| feature | New features or minor changes | PR/Release automation | -| dependencies | Changes that touch dependencies, e.g. Dependabot, etc. | PR/ automation | -| github-actions | Changes in GitHub workflows | PR automation | -| github-templates | Changes in GitHub issue/PR templates | PR automation | -| internal | Changes in governance and chores (linting setup, baseline, etc.) | PR automation | +| Label | Usage | Notes | +| ---------------------- | --------------------------------------------------------------------------- | --------------------------------------------------------------- | +| triage | New issues that require maintainers review | Issue template | +| bug | Unexpected, reproducible and unintended software behavior | PR/Release automation; Doc snippets are excluded; | +| not-a-bug | New and existing bug reports incorrectly submitted as bug | Analytics | +| documentation | Documentation improvements | PR/Release automation; Doc additions, fixes, etc.; | +| feature-request | New or enhancements to existing features | Issue template | +| typing | New or enhancements to static typing | Issue template | +| RFC | Technical design documents related to a feature request | Issue template | +| bug-upstream | Bug caused by upstream dependency | | +| help wanted | Tasks you want help from anyone to move forward | Bandwidth, complex topics, etc. | +| need-customer-feedback | Tasks that need more feedback before proceeding | 80/20% rule, uncertain, etc. | +| need-more-information | Missing information before making any calls | | +| need-documentation | PR is missing or has incomplete documentation | | +| need-issue | PR is missing a related issue for tracking change | Needs to be automated | +| need-rfc | Feature request requires a RFC to improve discussion | | +| pending-release | Merged changes that will be available soon | Release automation auto-closes/notifies it | +| revisit-in-3-months | Blocked issues/PRs that need to be revisited | Often related to `need-customer-feedback`, prioritization, etc. | +| breaking-change | Changes that will cause customer impact and need careful triage | | +| do-not-merge | PRs that are blocked for varying reasons | Timeline is uncertain | +| size/XS | PRs between 0-9 LOC | PR automation | +| size/S | PRs between 10-29 LOC | PR automation | +| size/M | PRs between 30-99 LOC | PR automation | +| size/L | PRs between 100-499 LOC | PR automation | +| size/XL | PRs between 500-999 LOC, often PRs that grown with feedback | PR automation | +| size/XXL | PRs with 1K+ LOC, largely documentation related | PR automation | +| tests | PRs that add or change tests | PR automation | +| `` | PRs related to a Powertools utility, e.g. `parameters`, `tracer` | PR automation | +| feature | New features or minor changes | PR/Release automation | +| dependencies | Changes that touch dependencies, e.g. Dependabot, etc. | PR/ automation | +| github-actions | Changes in GitHub workflows | PR automation | +| github-templates | Changes in GitHub issue/PR templates | PR automation | +| internal | Changes in governance, tech debt and chores (linting setup, baseline, etc.) | PR automation | ## Maintainer Responsibilities diff --git a/aws_lambda_powertools/utilities/data_classes/common.py b/aws_lambda_powertools/utilities/data_classes/common.py index 45f6bafc957..c651c225fab 100644 --- a/aws_lambda_powertools/utilities/data_classes/common.py +++ b/aws_lambda_powertools/utilities/data_classes/common.py @@ -32,9 +32,12 @@ def get_header_value( headers: Dict[str, str], name: str, default_value: Optional[str], case_sensitive: Optional[bool] ) -> Optional[str]: """Get header value by name""" + # If headers is NoneType, return default value + if not headers: + return default_value + if case_sensitive: return headers.get(name, default_value) - name_lower = name.lower() return next( diff --git a/docs/index.md b/docs/index.md index 6467dcdeb35..0a85d6ffa9b 100644 --- a/docs/index.md +++ b/docs/index.md @@ -14,7 +14,7 @@ A suite of utilities for AWS Lambda functions to ease adopting best practices su Powertools is available in the following formats: -* **Lambda Layer**: [**arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPython:22**](#){: .copyMe}:clipboard: +* **Lambda Layer**: [**arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPython:24**](#){: .copyMe}:clipboard: * **PyPi**: **`pip install aws-lambda-powertools`** ???+ hint "Support this project by using Lambda Layers :heart:" @@ -32,23 +32,23 @@ You can include Lambda Powertools Lambda Layer using [AWS Lambda Console](https: | Region | Layer ARN | | ---------------- | -------------------------------------------------------------------------------------------------------- | - | `us-east-1` | [arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPython:22](#){: .copyMe}:clipboard: | - | `us-east-2` | [arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPython:22](#){: .copyMe}:clipboard: | - | `us-west-1` | [arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPython:22](#){: .copyMe}:clipboard: | - | `us-west-2` | [arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPython:22](#){: .copyMe}:clipboard: | - | `ap-south-1` | [arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPython:22](#){: .copyMe}:clipboard: | - | `ap-northeast-1` | [arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPython:22](#){: .copyMe}:clipboard: | - | `ap-northeast-2` | [arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPython:22](#){: .copyMe}:clipboard: | - | `ap-northeast-3` | [arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPython:22](#){: .copyMe}:clipboard: | - | `ap-southeast-1` | [arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPython:22](#){: .copyMe}:clipboard: | - | `ap-southeast-2` | [arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPython:22](#){: .copyMe}:clipboard: | - | `eu-central-1` | [arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPython:22](#){: .copyMe}:clipboard: | - | `eu-west-1` | [arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPython:22](#){: .copyMe}:clipboard: | - | `eu-west-2` | [arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPython:22](#){: .copyMe}:clipboard: | - | `eu-west-3` | [arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPython:22](#){: .copyMe}:clipboard: | - | `eu-north-1` | [arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPython:22](#){: .copyMe}:clipboard: | - | `ca-central-1` | [arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPython:22](#){: .copyMe}:clipboard: | - | `sa-east-1` | [arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPython:22](#){: .copyMe}:clipboard: | + | `us-east-1` | [arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPython:24](#){: .copyMe}:clipboard: | + | `us-east-2` | [arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPython:24](#){: .copyMe}:clipboard: | + | `us-west-1` | [arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPython:24](#){: .copyMe}:clipboard: | + | `us-west-2` | [arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPython:24](#){: .copyMe}:clipboard: | + | `ap-south-1` | [arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPython:24](#){: .copyMe}:clipboard: | + | `ap-northeast-1` | [arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPython:24](#){: .copyMe}:clipboard: | + | `ap-northeast-2` | [arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPython:24](#){: .copyMe}:clipboard: | + | `ap-northeast-3` | [arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPython:24](#){: .copyMe}:clipboard: | + | `ap-southeast-1` | [arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPython:24](#){: .copyMe}:clipboard: | + | `ap-southeast-2` | [arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPython:24](#){: .copyMe}:clipboard: | + | `eu-central-1` | [arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPython:24](#){: .copyMe}:clipboard: | + | `eu-west-1` | [arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPython:24](#){: .copyMe}:clipboard: | + | `eu-west-2` | [arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPython:24](#){: .copyMe}:clipboard: | + | `eu-west-3` | [arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPython:24](#){: .copyMe}:clipboard: | + | `eu-north-1` | [arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPython:24](#){: .copyMe}:clipboard: | + | `ca-central-1` | [arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPython:24](#){: .copyMe}:clipboard: | + | `sa-east-1` | [arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPython:24](#){: .copyMe}:clipboard: | ??? question "Can't find our Lambda Layer for your preferred AWS region?" You can use [Serverless Application Repository (SAR)](#sar) method, our [CDK Layer Construct](https://github.com/aws-samples/cdk-lambda-powertools-python-layer){target="_blank"}, or PyPi like you normally would for any other library. @@ -62,7 +62,7 @@ You can include Lambda Powertools Lambda Layer using [AWS Lambda Console](https: Type: AWS::Serverless::Function Properties: Layers: - - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPython:22 + - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPython:24 ``` === "Serverless framework" @@ -72,7 +72,7 @@ You can include Lambda Powertools Lambda Layer using [AWS Lambda Console](https: hello: handler: lambda_function.lambda_handler layers: - - arn:aws:lambda:${aws:region}:017000801446:layer:AWSLambdaPowertoolsPython:22 + - arn:aws:lambda:${aws:region}:017000801446:layer:AWSLambdaPowertoolsPython:24 ``` === "CDK" @@ -88,7 +88,7 @@ You can include Lambda Powertools Lambda Layer using [AWS Lambda Console](https: powertools_layer = aws_lambda.LayerVersion.from_layer_version_arn( self, id="lambda-powertools", - layer_version_arn=f"arn:aws:lambda:{env.region}:017000801446:layer:AWSLambdaPowertoolsPython:22" + layer_version_arn=f"arn:aws:lambda:{env.region}:017000801446:layer:AWSLambdaPowertoolsPython:24" ) aws_lambda.Function(self, 'sample-app-lambda', @@ -137,7 +137,7 @@ You can include Lambda Powertools Lambda Layer using [AWS Lambda Console](https: role = aws_iam_role.iam_for_lambda.arn handler = "index.test" runtime = "python3.9" - layers = ["arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPython:22"] + layers = ["arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPython:24"] source_code_hash = filebase64sha256("lambda_function_payload.zip") } @@ -156,7 +156,7 @@ You can include Lambda Powertools Lambda Layer using [AWS Lambda Console](https: ? 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:AWSLambdaPowertoolsPython:22 + ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPython:24 ❯ amplify push -y @@ -167,7 +167,7 @@ You can include Lambda Powertools Lambda Layer using [AWS Lambda Console](https: - 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:AWSLambdaPowertoolsPython:22 + ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPython:24 ? Do you want to edit the local lambda function now? No ``` @@ -175,7 +175,7 @@ You can include Lambda Powertools Lambda Layer using [AWS Lambda Console](https: Change {region} to your AWS region, e.g. `eu-west-1` ```bash title="AWS CLI" - aws lambda get-layer-version-by-arn --arn arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPython:22 --region {region} + aws lambda get-layer-version-by-arn --arn arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPython:24 --region {region} ``` The pre-signed URL to download this Lambda Layer will be within `Location` key. diff --git a/layer/layer/canary_stack.py b/layer/layer/canary_stack.py index 15bc80214d3..426b3a4c87c 100644 --- a/layer/layer/canary_stack.py +++ b/layer/layer/canary_stack.py @@ -44,7 +44,6 @@ def __init__( canary_lambda = Function( self, "CanaryLambdaFunction", - function_name="CanaryLambdaFunction", code=Code.from_asset("layer/canary"), handler="app.on_event", layers=[layer], diff --git a/layer/layer/layer_stack.py b/layer/layer/layer_stack.py index c29c3816f55..f15232eb560 100644 --- a/layer/layer/layer_stack.py +++ b/layer/layer/layer_stack.py @@ -1,4 +1,4 @@ -from aws_cdk import RemovalPolicy, Stack +from aws_cdk import CfnOutput, RemovalPolicy, Stack from aws_cdk.aws_lambda import CfnLayerVersionPermission from aws_cdk.aws_ssm import StringParameter from cdk_lambda_powertools_python_layer import LambdaPowertoolsLayer @@ -27,3 +27,5 @@ def __init__( layer.apply_removal_policy(RemovalPolicy.RETAIN) StringParameter(self, "VersionArn", parameter_name=ssm_paramter_layer_arn, string_value=layer.layer_version_arn) + + CfnOutput(self, "LatestLayerArn", value=layer.layer_version_arn) diff --git a/layer/requirements.txt b/layer/requirements.txt index 5fb9d0f54b8..4e42439d2b3 100644 --- a/layer/requirements.txt +++ b/layer/requirements.txt @@ -27,9 +27,9 @@ cdk-lambda-powertools-python-layer==2.0.49 \ --hash=sha256:8055fc691539f16e22a40e3d3df9c3f59fb28012437b08c47c639aefb001f1b2 \ --hash=sha256:9b0a7b7344f9ccb486564af728cefeac743687bfb131631e6d9171a55800dbac # via -r requirements.txt -constructs==10.1.51 \ - --hash=sha256:b4abc463c368d8c01806a361faaa0799dc45985b6a4c9c99569daf9bbc0a79c4 \ - --hash=sha256:e42ade042c836c347c563e93366c19462e6db3ed50f2db7d78a75812304d1ec5 +constructs==10.1.52 \ + --hash=sha256:a1887a0ee28336d38cc61830eae9dd774b4b3628c33498645f93bcfa4b54ed99 \ + --hash=sha256:beabd1895cbe52a8b44dafe8b822e69585179e5e421ceb7e262a7ab327604fc8 # via # -r requirements.txt # aws-cdk-lib diff --git a/poetry.lock b/poetry.lock index 0a91ac12ac6..76fa6c625e4 100644 --- a/poetry.lock +++ b/poetry.lock @@ -741,8 +741,8 @@ typing-extensions = ">=4.1.0" [[package]] name = "mypy-boto3-cloudwatch" -version = "1.24.0" -description = "Type annotations for boto3.CloudWatch 1.24.0 service generated with mypy-boto3-builder 7.6.1" +version = "1.24.35" +description = "Type annotations for boto3.CloudWatch 1.24.35 service generated with mypy-boto3-builder 7.9.2" category = "dev" optional = false python-versions = ">=3.6" @@ -1323,7 +1323,7 @@ pydantic = ["pydantic", "email-validator"] [metadata] lock-version = "1.1" python-versions = "^3.6.2" -content-hash = "2ad17737aa164a36280e47d1578946adae4548376fe6f4584d458d3f00ad56fe" +content-hash = "242d708424414a3e52bf02ccbb2b6f49d88724c1d4583a133ebc703548b28e88" [metadata.files] atomicwrites = [ @@ -1690,8 +1690,8 @@ mypy-boto3-appconfig = [ {file = "mypy_boto3_appconfig-1.24.29-py3-none-any.whl", hash = "sha256:e9d9e2e25fdd82bffc6262dc184edf5d0d3d9fbb0ab35e597a1ea57ba13d4d80"}, ] mypy-boto3-cloudwatch = [ - {file = "mypy-boto3-cloudwatch-1.24.0.tar.gz", hash = "sha256:d19cd71aa07ecc69c1e2f9691af6a81bf1d65267ad4be1f9486bf683370727a5"}, - {file = "mypy_boto3_cloudwatch-1.24.0-py3-none-any.whl", hash = "sha256:82dac27b1dd0ad8969fedf874ea4713b36d37fe04229f7fdaaecf4addb59d4bd"}, + {file = "mypy-boto3-cloudwatch-1.24.35.tar.gz", hash = "sha256:92a818e2ea330f9afb5f8f9c15df47934736041e3ccfd696ffc0774bad14e0aa"}, + {file = "mypy_boto3_cloudwatch-1.24.35-py3-none-any.whl", hash = "sha256:28947763d70cdac24aca25779cd5b00cd995636f5815fac3d95009430ce02b72"}, ] mypy-boto3-dynamodb = [ {file = "mypy-boto3-dynamodb-1.24.27.tar.gz", hash = "sha256:c982d24f9b2525a70f408ad40eff69660d56928217597d88860b60436b25efbf"}, diff --git a/pyproject.toml b/pyproject.toml index 4d5fdc56adc..d7c79661808 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "aws_lambda_powertools" -version = "1.26.4" +version = "1.26.5" description = "A suite of utilities for AWS Lambda functions to ease adopting best practices such as tracing, structured logging, custom metrics, batching, idempotency, feature flags, and more." authors = ["Amazon Web Services"] include = ["aws_lambda_powertools/py.typed", "THIRD-PARTY-LICENSES"] @@ -63,7 +63,7 @@ retry = "^0.9.2" pytest-xdist = "^2.5.0" aws-cdk-lib = "^2.23.0" pytest-benchmark = "^3.4.1" -mypy-boto3-cloudwatch = "^1.24.0" +mypy-boto3-cloudwatch = "^1.24.35" mypy-boto3-lambda = "^1.24.0" mypy-boto3-xray = "^1.24.0" diff --git a/tests/functional/event_handler/test_api_gateway.py b/tests/functional/event_handler/test_api_gateway.py index 0c6d1954836..f1fb6a1f942 100644 --- a/tests/functional/event_handler/test_api_gateway.py +++ b/tests/functional/event_handler/test_api_gateway.py @@ -314,6 +314,24 @@ def return_text() -> Response: assert result["body"] == expected_value +def test_compress_no_accept_encoding_null_headers(): + # GIVEN a function with compress=True + # AND the request has no headers + app = ApiGatewayResolver() + expected_value = "Foo" + + @app.get("/my/path", compress=True) + def return_text() -> Response: + return Response(200, content_types.TEXT_PLAIN, expected_value) + + # WHEN calling the event handler + result = app({"path": "/my/path", "httpMethod": "GET", "headers": None}, None) + + # THEN don't perform any gzip compression + assert result["isBase64Encoded"] is False + assert result["body"] == expected_value + + def test_cache_control_200(): # GIVEN a function with cache_control set app = ApiGatewayResolver()