Skip to content

Commit 083ed62

Browse files
New Python constructor for layers
1 parent 3173021 commit 083ed62

File tree

11 files changed

+478
-81
lines changed

11 files changed

+478
-81
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
name: Code quality - CDK constructor
2+
3+
# PROCESS
4+
#
5+
# 1. Install all dependencies and spin off containers for all supported Python versions
6+
# 2. Run code formatters and linters (various checks) for code standard
7+
# 3. Run static typing checker for potential bugs
8+
# 4. Run entire test suite for regressions except end-to-end (unit, functional, performance)
9+
# 5. Run static analysis (in addition to CodeQL) for common insecure code practices
10+
# 6. Run complexity baseline to avoid error-prone bugs and keep maintenance lower
11+
# 7. Collect and report on test coverage
12+
13+
# USAGE
14+
#
15+
# Always triggered on new PRs, PR changes and PR merge.
16+
17+
18+
on:
19+
pull_request:
20+
paths:
21+
- "layer/layer_constructors/**"
22+
branches:
23+
- develop
24+
- v3
25+
push:
26+
paths:
27+
- "layer/layer_constructors/**"
28+
branches:
29+
- develop
30+
- v3
31+
32+
permissions:
33+
contents: read
34+
35+
jobs:
36+
quality_check:
37+
runs-on: ubuntu-latest
38+
strategy:
39+
max-parallel: 4
40+
matrix:
41+
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
42+
env:
43+
PYTHON: "${{ matrix.python-version }}"
44+
permissions:
45+
contents: read # checkout code only
46+
defaults:
47+
run:
48+
working-directory: ./layer_v3/layer_constructors
49+
steps:
50+
- uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
51+
- name: Install poetry
52+
run: pipx install poetry
53+
- name: Set up Python ${{ matrix.python-version }}
54+
uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0
55+
with:
56+
python-version: ${{ matrix.python-version }}
57+
cache: "poetry"
58+
- name: Set up QEMU
59+
uses: docker/setup-qemu-action@e81a89b1732b9c48d79cd809d8d81d79c4647a18 # v2.0.0
60+
with:
61+
platforms: arm64
62+
# NOTE: we need QEMU to build Layer against a different architecture (e.g., ARM)
63+
- name: Set up Docker Buildx
64+
id: builder
65+
uses: docker/setup-buildx-action@f03ac48505955848960e80bbb68046aa35c7b9e7 # v2.4.1
66+
with:
67+
install: true
68+
driver: docker
69+
platforms: linux/amd64,linux/arm64
70+
- name: Install dependencies
71+
run: |
72+
pip install --upgrade pip pre-commit poetry
73+
poetry install
74+
- name: Test with pytest
75+
run: poetry run pytest tests

layer_v3/__init__.py

Whitespace-only changes.

layer_v3/layer/layer_stack.py

+5-4
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,10 @@
1414
)
1515
from aws_cdk.aws_lambda import Architecture, CfnLayerVersionPermission, Runtime
1616
from aws_cdk.aws_ssm import StringParameter
17-
from cdk_aws_lambda_powertools_layer import LambdaPowertoolsLayerPythonV3
1817
from constructs import Construct
1918

19+
from layer_v3.layer_constructors.layer_stack import LambdaPowertoolsLayerPythonV3
20+
2021

2122
@jsii.implements(IAspect)
2223
class ApplyCondition:
@@ -46,11 +47,11 @@ def __init__(
4647
layer = LambdaPowertoolsLayerPythonV3(
4748
self,
4849
"Layer",
49-
layer_version_name=layer_version_name,
50-
version=powertools_version,
50+
layer_name=layer_version_name,
51+
powertools_version=powertools_version,
5152
python_version=python_version,
5253
include_extras=True,
53-
compatible_architectures=[architecture] if architecture else [],
54+
architecture=architecture or Architecture.X86_64,
5455
)
5556
layer.apply_removal_policy(RemovalPolicy.RETAIN)
5657

layer_v3/layer_constructors/__init__.py

Whitespace-only changes.
+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
from __future__ import annotations
2+
3+
4+
def construct_build_args(include_extras: bool = True, version: str | None = None) -> str:
5+
"""
6+
This function creates a suffix string for the Powertools package based on
7+
whether extra dependencies should be included and a specific version is required.
8+
9+
Params
10+
------
11+
include_extras: bool | None:
12+
If True, include all extra dependencies in Powertools package
13+
version: str | None
14+
The version of Powertools to install. Can be a version number or a git reference.
15+
16+
Returns
17+
-------
18+
str
19+
A string suffix to be appended to the Powertools package name during installation.
20+
Examples:
21+
- "" (empty string) if no extras or version specified
22+
- "[all]" if include_extras is True
23+
- "==1.2.3" if version is "1.2.3"
24+
- "[all]==1.2.3" if include_extras is True and version is "1.2.3"
25+
- " @ git+https://github.com/..." if version starts with "git"
26+
27+
Example
28+
-------
29+
>>> construct_build_args(True, "1.2.3")
30+
'[all]==1.2.3'
31+
>>> construct_build_args(False, "git+https://github.com/...")
32+
' @ git+https://github.com/...'
33+
"""
34+
35+
suffix = ""
36+
37+
if include_extras:
38+
suffix = "[all]"
39+
if version:
40+
if version.startswith("git"):
41+
suffix = f"{suffix} @ {version}"
42+
else:
43+
suffix = f"{suffix}=={version}"
44+
45+
return suffix
+83
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
from __future__ import annotations
2+
3+
from pathlib import Path
4+
from typing import TYPE_CHECKING
5+
6+
from aws_cdk import aws_lambda as lambda_
7+
8+
if TYPE_CHECKING:
9+
from constructs import Construct
10+
11+
from layer_v3.layer_constructors.helpers import construct_build_args
12+
13+
14+
class LambdaPowertoolsLayerPythonV3(lambda_.LayerVersion):
15+
"""
16+
A CDK Stack that creates a Lambda Layer for Powertools for AWS Lambda (Python) V3.
17+
18+
This stack creates a Lambda Layer containing the Powertools for AWS Lambda (Python) V3 library.
19+
It allows customization of the Python runtime version, inclusion of extra dependencies,
20+
architecture, Powertools version, and layer name.
21+
22+
Attributes:
23+
scope (Construct): The scope in which to define this construct.
24+
construct_id (str): The scoped construct ID. Must be unique amongst siblings in the same scope.
25+
python_version (lambda_.Runtime): The Python runtime version for the layer. Defaults to Python 3.12.
26+
include_extras (bool): Whether to include extra dependencies. Defaults to True.
27+
architecture (lambda_.Architecture): The compatible Lambda architecture. Defaults to x86_64.
28+
powertools_version (str): The version of Powertools to use. If empty, uses the latest version.
29+
layer_name (str): Custom name for the Lambda Layer. If empty, a default name will be used.
30+
31+
Example:
32+
>>> app = cdk.App()
33+
>>> LambdaPowertoolsLayerPythonV3(app, "PowertoolsLayer",
34+
... python_version=lambda_.Runtime.PYTHON_3_11,
35+
... include_extras=False,
36+
... architecture=lambda_.Architecture.ARM_64,
37+
... powertools_version="2.10.0",
38+
... layer_name="MyCustomPowertoolsLayer")
39+
40+
"""
41+
42+
def __init__(
43+
self,
44+
scope: Construct,
45+
construct_id: str,
46+
python_version: lambda_.Runtime = lambda_.Runtime.PYTHON_3_12,
47+
include_extras: bool = True,
48+
architecture: lambda_.Architecture = lambda_.Architecture.X86_64,
49+
powertools_version: str = "",
50+
layer_name: str = "",
51+
) -> None:
52+
53+
docker_file_path = str(Path(__file__).parent.parent / "docker")
54+
55+
python_normalized_version: str = python_version.to_string().replace("python", "")
56+
57+
if architecture.to_string() == "x86_64":
58+
docker_architecture: str = "linux/amd64"
59+
else:
60+
docker_architecture: str = "linux/arm64"
61+
62+
super().__init__(
63+
scope,
64+
construct_id,
65+
code=lambda_.Code.from_docker_build(
66+
docker_file_path,
67+
build_args={
68+
"PACKAGE_SUFFIX": construct_build_args(
69+
include_extras,
70+
powertools_version,
71+
),
72+
"PYTHON_VERSION": python_normalized_version,
73+
},
74+
platform=docker_architecture,
75+
),
76+
layer_version_name=layer_name,
77+
license="MIT-0",
78+
compatible_runtimes=[python_version],
79+
description=f"Powertools for AWS Lambda (Python) V3 [{architecture.to_string()} - Python {python_normalized_version}]" # noqa E501
80+
+ (" with extra dependencies" if include_extras else "")
81+
+ (f" version {powertools_version}" if powertools_version else " latest version"),
82+
compatible_architectures=[architecture] if architecture else None,
83+
)

layer_v3/layer_constructors/tests/__init__.py

Whitespace-only changes.

layer_v3/layer_constructors/tests/unit/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)