diff --git a/.chglog/CHANGELOG.tpl.md b/.chglog/CHANGELOG.tpl.md index ed0c0f823f6..b1fa7de1f58 100755 --- a/.chglog/CHANGELOG.tpl.md +++ b/.chglog/CHANGELOG.tpl.md @@ -1,6 +1,6 @@ {{ if .Versions -}} -## [Unreleased] +## Unreleased {{ if .Unreleased.CommitGroups -}} {{ range .Unreleased.CommitGroups -}} diff --git a/.chglog/config.yml b/.chglog/config.yml index 035aa04e2fa..3392563d445 100755 --- a/.chglog/config.yml +++ b/.chglog/config.yml @@ -13,6 +13,7 @@ options: - refactor - docs - chore + - revert commit_groups: title_maps: feat: Features @@ -21,6 +22,7 @@ options: refactor: Code Refactoring docs: Documentation chore: Maintenance + revert: Regression header: pattern: "^(\\w*)(?:\\(([\\w\\$\\.\\-\\*\\s]*)\\))?\\:\\s(.*)$" pattern_maps: diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 95296da6565..69416cb52fe 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -23,9 +23,21 @@ name: Publish to PyPi # 9. Push latest release source code to master using release title as the commit message # 10. Builds latest documentation for new release, and update latest alias pointing to the new release tag +# +# === Fallback mechanism due to external failures === +# +# 1. Trigger "Publish to PyPi" workflow manually: https://docs.github.com/en/actions/managing-workflow-runs/manually-running-a-workflow +# 2. Use the version released under Releases e.g. v1.13.0 +# + on: release: types: [published] + workflow_dispatch: + inputs: + publish_version: + description: 'Version to publish, e.g. v1.13.0' + required: true jobs: release: @@ -40,7 +52,9 @@ jobs: python-version: "3.8" - name: Set release notes tag run: | - export RELEASE_TAG_VERSION=${{ github.event.release.tag_name }} + RELEASE_TAG_VERSION=${{ github.event.release.tag_name }} + # Replace publishing version if the workflow was triggered manually + test -n $RELEASE_TAG_VERSION && RELEASE_TAG_VERSION=${{ github.event.inputs.publish_version }} echo "RELEASE_TAG_VERSION=${RELEASE_TAG_VERSION:1}" >> $GITHUB_ENV - name: Ensure new version is also set in pyproject and CHANGELOG run: | diff --git a/CHANGELOG.md b/CHANGELOG.md index 70b8d32c004..41065b6c722 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,22 @@ This project follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) fo ## [Unreleased] +## 1.21.1 - 2021-10-07 + +### Regression + +* **metrics:** typing regression on log_metrics callable ([#744](https://github.com/awslabs/aws-lambda-powertools-python/issues/744)) + +### Documentation + +* add new public layer ARNs ([#746](https://github.com/awslabs/aws-lambda-powertools-python/issues/746)) +### Maintenance + +* ignore constants in test cov ([#745](https://github.com/awslabs/aws-lambda-powertools-python/issues/745)) +* github-actions: add support for publishing fallback +* **deps:** bump boto3 from 1.18.54 to 1.18.56 ([#742](https://github.com/awslabs/aws-lambda-powertools-python/issues/742)) +* **deps-dev:** bump mkdocs-material from 7.3.1 to 7.3.2 ([#741](https://github.com/awslabs/aws-lambda-powertools-python/issues/741)) + ## 1.21.0 - 2021-10-05 ### Bug Fixes diff --git a/aws_lambda_powertools/metrics/metrics.py b/aws_lambda_powertools/metrics/metrics.py index 23e9f542eea..927b6873648 100644 --- a/aws_lambda_powertools/metrics/metrics.py +++ b/aws_lambda_powertools/metrics/metrics.py @@ -2,9 +2,8 @@ import json import logging import warnings -from typing import Any, Callable, Dict, Optional, Union, cast +from typing import Any, Callable, Dict, Optional, Union -from ..shared.types import AnyCallableT from .base import MetricManager, MetricUnit from .metric import single_metric @@ -130,7 +129,7 @@ def log_metrics( capture_cold_start_metric: bool = False, raise_on_empty_metrics: bool = False, default_dimensions: Optional[Dict[str, str]] = None, - ) -> AnyCallableT: + ): """Decorator to serialize and publish metrics at the end of a function execution. Be aware that the log_metrics **does call* the decorated function (e.g. lambda_handler). @@ -170,14 +169,11 @@ def handler(event, context): # Return a partial function with args filled if lambda_handler is None: logger.debug("Decorator called with parameters") - return cast( - AnyCallableT, - functools.partial( - self.log_metrics, - capture_cold_start_metric=capture_cold_start_metric, - raise_on_empty_metrics=raise_on_empty_metrics, - default_dimensions=default_dimensions, - ), + return functools.partial( + self.log_metrics, + capture_cold_start_metric=capture_cold_start_metric, + raise_on_empty_metrics=raise_on_empty_metrics, + default_dimensions=default_dimensions, ) @functools.wraps(lambda_handler) @@ -198,7 +194,7 @@ def decorate(event, context): return response - return cast(AnyCallableT, decorate) + return decorate def __add_cold_start_metric(self, context: Any) -> None: """Add cold start metric and function_name dimension diff --git a/docs/index.md b/docs/index.md index b79a2e7074f..7f58de4fe8a 100644 --- a/docs/index.md +++ b/docs/index.md @@ -36,7 +36,126 @@ Powertools is available in PyPi. You can use your favourite dependency managemen ### Lambda Layer -Powertools is also available as a Lambda Layer, and it is distributed via the [AWS Serverless Application Repository (SAR)](https://docs.aws.amazon.com/serverlessrepo/latest/devguide/what-is-serverlessrepo.html) to support semantic versioning. +Powertools is also available as a Lambda Layer with public ARNs in each region or distributed via the [AWS Serverless Application Repository (SAR)](https://docs.aws.amazon.com/serverlessrepo/latest/devguide/what-is-serverlessrepo.html) to support semantic versioning. + +#### Public ARNs + +We build, release and distribute packaged Lambda Powertools layers for each region. This means you can copy a specific ARN and use it in your Lambda deployment. The layer region must be equal to the region of your lambda function. The public layers do not contain the `pydantic` library that is required for the `parser` utility. + + +=== "SAM" + + ```yaml hl_lines="5" + MyLambdaFunction: + Type: AWS::Serverless::Function + Properties: + Layers: + - arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPython:3 + ``` + +=== "Serverless framework" + + ```yaml hl_lines="5" + functions: + main: + handler: lambda_function.lambda_handler + layers: + - arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPython:3 + ``` + +=== "CDK" + + ```python hl_lines="14" + from aws_cdk import core, aws_lambda + + class SampleApp(core.Construct): + + def __init__(self, scope: core.Construct, id_: str) -> None: + super().__init__(scope, id_) + + 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: ["arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPython:3"] + ) + ``` + +=== "Terraform" + + ```terraform hl_lines="9 38" + terraform { + required_version = "~> 1.0.5" + required_providers { + aws = "~> 3.50.0" + } + } + + provider "aws" { + region = "us-east-1" + } + + resource "aws_iam_role" "iam_for_lambda" { + name = "iam_for_lambda" + + assume_role_policy = < { +function copyToClipboard(e) { + e.preventDefault() + navigator.clipboard.writeText(e.target.textContent) + alert$.next("Copied to clipboard") +} + +function enableSearchOnBlurElement() { /* Register handler to log search on blur */ document.addEventListener("DOMContentLoaded", function () { recordPageView({ @@ -41,6 +47,18 @@ const attachListeners = () => { }; } +function enableClipboardElements() { + let copyElements = document.querySelectorAll('.copyMe'); + copyElements.forEach(element => { + element.addEventListener('click', copyToClipboard); + }) +} + +const attachListeners = () => { + enableSearchOnBlurElement() + enableClipboardElements() +} + const init = () => { Analytics.addPluggable(new KinesisFirehoseProvider()) Amplify.configure(awsconfig); diff --git a/docs/stylesheets/extra.css b/docs/stylesheets/extra.css index f24b32faa14..0d37af692cb 100644 --- a/docs/stylesheets/extra.css +++ b/docs/stylesheets/extra.css @@ -33,3 +33,8 @@ [data-md-color-scheme="slate"] { --md-typeset-a-color: rgb(28, 152, 152) } + +.copyMe { + cursor: pointer; + border-bottom: 0.1px dashed black; +} diff --git a/mkdocs.yml b/mkdocs.yml index b90ba4376de..fc51acb8b47 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -69,6 +69,7 @@ markdown_extensions: - attr_list - pymdownx.emoji - pymdownx.inlinehilite + - attr_list copyright: Copyright © 2021 Amazon Web Services diff --git a/poetry.lock b/poetry.lock index 8e6806f9848..1d1e5366e12 100644 --- a/poetry.lock +++ b/poetry.lock @@ -81,14 +81,14 @@ d = ["aiohttp (>=3.3.2)", "aiohttp-cors"] [[package]] name = "boto3" -version = "1.18.54" +version = "1.18.56" description = "The AWS SDK for Python" category = "main" optional = false python-versions = ">= 3.6" [package.dependencies] -botocore = ">=1.21.54,<1.22.0" +botocore = ">=1.21.56,<1.22.0" jmespath = ">=0.7.1,<1.0.0" s3transfer = ">=0.5.0,<0.6.0" @@ -97,7 +97,7 @@ crt = ["botocore[crt] (>=1.21.0,<2.0a0)"] [[package]] name = "botocore" -version = "1.21.54" +version = "1.21.56" description = "Low-level, data-driven core of boto 3." category = "main" optional = false @@ -577,17 +577,18 @@ mkdocs = ">=0.17" [[package]] name = "mkdocs-material" -version = "7.3.1" +version = "7.3.2" description = "A Material Design theme for MkDocs" category = "dev" optional = false python-versions = "*" [package.dependencies] +jinja2 = ">=2.11.1" markdown = ">=3.2" mkdocs = ">=1.2.2" mkdocs-material-extensions = ">=1.0" -Pygments = ">=2.4" +pygments = ">=2.4" pymdown-extensions = ">=9.0" [[package]] @@ -1054,7 +1055,7 @@ pydantic = ["pydantic", "email-validator"] [metadata] lock-version = "1.1" python-versions = "^3.6.1" -content-hash = "a0358de807bcf4fe1af43ac28f40f41552d559b11cfc5ebd099a4e3842f87a8d" +content-hash = "829128c92690e9cfa6ed3387bb6927fcca65a5478baadb59db5c489b99f71bfd" [metadata.files] appdirs = [ @@ -1081,12 +1082,12 @@ black = [ {file = "black-20.8b1.tar.gz", hash = "sha256:1c02557aa099101b9d21496f8a914e9ed2222ef70336404eeeac8edba836fbea"}, ] boto3 = [ - {file = "boto3-1.18.54-py3-none-any.whl", hash = "sha256:f22a77098cd70ddf848df6981ec57b92178e9d8eb74637edbdf4173bfa9279fa"}, - {file = "boto3-1.18.54.tar.gz", hash = "sha256:2d81dc484020059fc738165984304107d4db1c6774b6310d08c892a1751f6980"}, + {file = "boto3-1.18.56-py3-none-any.whl", hash = "sha256:42828d83acddfa2361411b13683eedf7c1c0a15e896b45960ed04a26efe7adfb"}, + {file = "boto3-1.18.56.tar.gz", hash = "sha256:d43e3651ad1b0b5de6f77df82df27e0f1e6cd854f725c808c70a1fb956f0b699"}, ] botocore = [ - {file = "botocore-1.21.54-py3-none-any.whl", hash = "sha256:56b74a5186bec835baf580b2d062ea1738d3ff5a573653d41b3ad1598a5b77c4"}, - {file = "botocore-1.21.54.tar.gz", hash = "sha256:46127b3a385d0ec73d1994b8958b23b79e0613e12c486371a100df992b72a1b9"}, + {file = "botocore-1.21.56-py3-none-any.whl", hash = "sha256:d712f572022670916bd77fbe421155dcf575398b9dced88035ed3658679883bd"}, + {file = "botocore-1.21.56.tar.gz", hash = "sha256:43fab79905e3dfe56f92a137314ef1afbf040f7c06516a003351c24322cbfd7c"}, ] certifi = [ {file = "certifi-2020.12.5-py2.py3-none-any.whl", hash = "sha256:719a74fb9e33b9bd44cc7f3a8d94bc35e4049deebe19ba7d8e108280cfd59830"}, @@ -1327,8 +1328,8 @@ mkdocs-git-revision-date-plugin = [ {file = "mkdocs_git_revision_date_plugin-0.3.1-py3-none-any.whl", hash = "sha256:8ae50b45eb75d07b150a69726041860801615aae5f4adbd6b1cf4d51abaa03d5"}, ] mkdocs-material = [ - {file = "mkdocs-material-7.3.1.tar.gz", hash = "sha256:d1ab269da2025f22b8fba079d7eadc05cd97ac2a21d87b09d414e69915f247a7"}, - {file = "mkdocs_material-7.3.1-py2.py3-none-any.whl", hash = "sha256:8d59c8ac241d59eef1a883c49ca685c8d8446eb054675a212fb748daff24099c"}, + {file = "mkdocs-material-7.3.2.tar.gz", hash = "sha256:02aeb2f9d9826b5c5ba4e320b4008bdc89f7b30ca00ded72ee43385a1690eaa4"}, + {file = "mkdocs_material-7.3.2-py2.py3-none-any.whl", hash = "sha256:a9b7c6432ebadd0e192e3b341b25bd41bd1c1b167061ea629a9887a1e4129176"}, ] mkdocs-material-extensions = [ {file = "mkdocs-material-extensions-1.0.1.tar.gz", hash = "sha256:6947fb7f5e4291e3c61405bad3539d81e0b3cd62ae0d66ced018128af509c68f"}, diff --git a/pyproject.toml b/pyproject.toml index abcff627870..19797484c8f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "aws_lambda_powertools" -version = "1.21.0" +version = "1.21.1" 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"] @@ -50,7 +50,7 @@ radon = "^5.1.0" xenon = "^0.8.0" flake8-eradicate = "^1.1.0" flake8-bugbear = "^21.9.2" -mkdocs-material = "^7.3.1" +mkdocs-material = "^7.3.2" mkdocs-git-revision-date-plugin = "^0.3.1" mike = "^0.6.0" mypy = "^0.910" @@ -61,7 +61,7 @@ pydantic = ["pydantic", "email-validator"] [tool.coverage.run] source = ["aws_lambda_powertools"] -omit = ["tests/*", "aws_lambda_powertools/exceptions/*", "aws_lambda_powertools/utilities/parser/types.py"] +omit = ["tests/*", "aws_lambda_powertools/exceptions/*", "aws_lambda_powertools/utilities/parser/types.py", "aws_lambda_powertools/utilities/jmespath_utils/envelopes.py"] branch = true [tool.coverage.html]