在 Python 中使用 AWS CDK - AWS Cloud Development Kit (AWS CDK) v2

这是 AWS CDK v2 开发者指南。旧版 CDK v1 于 2022 年 6 月 1 日进入维护阶段,并于 2023 年 6 月 1 日终止支持。

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

在 Python 中使用 AWS CDK

Python 是 C AWS loud Development Kit (AWS CDK) 完全支持的客户端语言,被认为是稳定的。在 Python 中使用 AWS CDK 使用熟悉的工具,包括标准 Python 实现 (CPython)、虚拟环境和 Python 包安装程序pipvirtualenv构成 AWS 构造库的模块通过 pypi .org 分发。Python 版本的 AWS CDK 甚至使用 Python 风格的标识符(例如,snake_case方法名称)。

您可以使用任何编辑器或 IDE。许多 AWS CDK 开发者使用 Visual Studio Code(或其开源代码的等效代码 VSCodium),该代码通过官方扩展对 Python 提供了良好的支持。Python 附带的 IDLE 编辑器足以帮助您入门。 AWS CDK 的 Python 模块确实有类型提示,这对于支持类型验证的 linting 工具或 IDE 非常有用。

开始使用 Python

要使用 AWS CDK,你必须拥有 AWS 账户和凭证,并已安装 Node.js 和 AWS CDK Toolkit。请参阅 AWS CDK 入门

Python AWS CDK 应用程序需要 Python 3.6 或更高版本。如果您尚未安装,请在 python. org 上下载适用于您的操作系统的兼容版本。如果您运行的是 Linux,则您的系统可能带有兼容版本,或者您可以使用发行版的软件包管理器(yumapt、等)进行安装。Mac 用户可能会对 Homebrew 感兴趣,这是一款适用于 macOS 的 Linux 风格的包管理器。

注意

第三方语言弃用:语言版本仅在供应商或社区共享其 EOL(生命周期终止)之前才受支持,如有更改,会另行通知。

还需要使用 Python 包安装程序 pip 和虚拟环境管理器 virtualenv。在 Windows 上安装兼容的 Python 版本需要使用这些工具。在 Linux 上,pipvirtualenv 可以在软件包管理器中作为单独的软件包进行提供。或者,您可以使用以下命令进行安装:

python -m ensurepip --upgrade python -m pip install --upgrade pip python -m pip install --upgrade virtualenv

如果遇到权限错误,请运行带有 --user 标志的上述命令,以便将模块安装在您的用户目录中,或者使用 sudo 来获取在系统范围内安装模块的权限。

注意

Linux 发行版通常使用可执行文件名称 python3 表示 Python 3.x,使用 python 表示 Python 2.x 安装。有些发行版有一个可以安装的可选包,可让 python 命令表示 Python 3。否则,您可以通过在项目的主目录cdk.json中进行编辑来调整用于运行应用程序的命令。

注意

在 Windows 上,你可能需要使用py可执行文件(适用于 Windows 的 Python 启动器pip)来调用 Python(和)。除此之外,启动器还允许您轻松指定要使用的 Python 安装版本。

如果在命令行键入 python 后会显示一条关于从 Windows 应用商店安装 Python 的消息,即使安装了 Windows 版本的 Python,也请打开 Windows 的“管理应用程序执行别名”设置面板并关闭 Python 的两个应用程序安装程序条目。

创建项目

您可以通过在空目录cdk init中调用来创建新的 AWS CDK 项目。使用 --language 选项并指定 python

$ mkdir my-project $ cd my-project $ cdk init app --language python

cdk init 使用项目文件夹的名称来命名项目的各种元素,包括类、子文件夹和文件。文件夹名称中的连字符都将转换为下划线。但是,名称应遵循 Python 标识符的形式;例如,名称不应以数字开头,也不应包含空格。

要使用新项目,请激活其虚拟环境。这允许将项目的依赖项安装在本地项目文件夹中,而不是全局安装在项目文件夹中。

$ source .venv/bin/activate
注意

您可将其视为用于激活虚拟环境的 Mac/Linux 命令。Python 模板包含一个批处理文件 source.bat,该文件允许在 Windows 上使用相同的命令。也可以使用传统的 Windows 命令 .\venv\Scripts\activate

如果您使用 AWS CDK Toolkit v1.70.0 或更早版本初始化 CDK 项目,则您的虚拟环境位于目录中,而不是。.env .venv

重要

每当你开始处理项目时,都要激活该项目的虚拟环境。否则,您将无法访问安装在那里的模块,并且您安装的模块将进入Python全局模块目录(或者会导致权限错误)。

首次激活虚拟环境后,安装应用程序的标准依赖项:

$ python -m pip install -r requirements.txt

管理 AWS 构造库模块

使用 Python 包安装程序安装和更新 AWS 构造库模块,供您的应用程序使用,以及您需要的其他包。pip pip还会自动安装这些模块的依赖关系。如果您的系统无法识别 pip 为独立命令,请将 pip 作为 Python 模块进行调用,如下所示:

$ python -m pip <PIP-COMMAND>

大多数 AWS CDK 结构都在。aws-cdk-lib实验性模块位于名称类似于 aws-cdk.<SERVICE-NAME>.alpha 的单独模块中。服务名称包含 aws 前缀。如果您不确定模块的名称,请在 Py PI 上进行搜索。例如,下面的命令安装该 AWS CodeStar 库。

$ python -m pip install aws-cdk.aws-codestar-alpha

某些服务的构造位于多个命名空间中。例如,除 aws-cdk.aws-route53 之外,还有另外三个 Amazon Route 53 命名空间,aws-route53-targetsaws-route53-patternsaws-route53resolver

注意

CDK API Reference 的 Python 版本也显示了包名称。

用于将 AWS 构造库模块导入 Python 代码的名称如下所示。

import aws_cdk.aws_s3 as s3 import aws_cdk.aws_lambda as lambda_

在应用程序中导入 AWS CDK 类和 AWS 构造库模块时,我们建议采用以下做法。遵循这些准则将有助于使您的代码与其他 AWS CDK 应用程序保持一致,并且更易于理解。

  • 通常,从顶层 aws_cdk 中导入单个类。

    from aws_cdk import App, Construct
  • 如果您需要 aws_cdk 中的许多类,则可以使用 cdk 的命名空间别名,而不是导入单个类。避免同时执行这两项操作。

    import aws_cdk as cdk
  • 通常,使用短命名空间别名导入 AWS 构造库。

    import aws_cdk.aws_s3 as s3

安装模块后,更新项目的requirements.txt文件,其中列出了项目的依赖关系。最好手动执行此操作,而不是使用 pip freezepip freeze 会捕获 Python 虚拟环境中安装的所有模块的当前版本,这在将项目捆绑到其他地方运行时非常有用。

但是,通常情况下,您的 requirements.txt 应该只列出顶级依赖项(您的应用程序直接依赖的模块),而不会列出这些库的依赖项。这种策略让更新依赖项变得更加简单。

您可以编辑 requirements.txt 以允许升级;只需将版本号前面的 == 替换为 ~= 即可升级到更高的兼容版本,或者完全删除版本要求以指定模块的最新可用版本。

requirements.txt经过适当编辑以允许升级后,可以随时发出以下命令来升级项目中已安装的模块:

$ pip install --upgrade -r requirements.txt

在 Python 中管理依赖关系

在 Python 中,您可以在应用程序的 requirements.txt 或构造库的 setup.py 中输入依赖项来指定依赖项。然后使用 PIP 工具来管理依赖关系。通过以下方式之一来调用 PIP:

pip <command options> python -m pip <command options>

python -m pip调用适用于大多数系统;pip要求 PIP 的可执行文件位于系统路径上。如果pip不起作用,请尝试将其替换为python -m pip

cdk init --language python 命令会为您的新项目创建一个虚拟环境。这样每个项目就都有自己的依赖项版本,还有一个基本 requirements.txt 文件。每次开始使用项目时,都必须运行 source .venv/bin/activate 来激活此虚拟环境。在 Windows 上,改为运行 .\venv\Scripts\activate

CDK 应用程序

下面是一个 requirements.txt 示例文件。由于 PIP 不具备依赖锁定功能,我们建议您使用 == 运算符为所有依赖项指定确切的版本,如下所示。

aws-cdk-lib==2.14.0 aws-cdk.aws-appsync-alpha==2.10.0a0

使用 pip install 来安装模块不会自动将其添加到 requirements.txt。必须自己动手添加。如果要升级到依赖项的更高版本,请在 requirements.txt 中编辑其版本号。

要在创建或编辑项目后安装或更新项目的依赖项requirements.txt,请运行以下命令:

python -m pip install -r requirements.txt
提示

pip freeze 命令以可写入文本文件的格式输出所有已安装依赖项的版本。这可以用作 pip install -r 的需求文件。此文件便于将所有依赖项(包括传递依赖项)固定到您测试过的确切版本。为避免以后升级软件包时出现问题,请为此使用单独的文件,例如 freeze.txt(不是 requirements.txt)。然后,在升级项目的依赖关系时重新生成它。

第三方构造库

在库中,依赖项在 setup.py 中进行指定,以便应用程序使用包时会自动下载传递依赖项。否则,每个想要使用包的应用程序都需要将您的依赖项复制到其 requirements.txt 中。此处显示了一个示例 setup.py

from setuptools import setup setup( name='my-package', version='0.0.1', install_requires=[ 'aws-cdk-lib==2.14.0', ], ... )

要使用包进行开发,请创建或激活虚拟环境,然后运行以下命令。

python -m pip install -e .

尽管 PIP 会自动安装传递依赖项,但每个包只能安装一个副本。已选择依赖项树中指定的最高版本;应用程序对安装哪个版本的软件包始终拥有最终决定权。

AWS Python 中的 CDK 成语

语言冲突

在 Python 中,lambda是一个语言关键字,因此您不能将其用作 Lambda 构造库模块 AWS 或 Lambda 函数的名称。对于此类冲突,Python 的惯例是在变量名称中使用尾随下划线,如 lambda_ 所示。

按照惯例, AWS CDK 构造的第二个参数是命名的。id在编写自己的堆栈和构造时,调用参数 id “阴影” Python 内置函数id(),该函数返回对象的唯一标识符。这个函数并不经常使用,但是如果你在构造中碰巧需要它,例如,可以重命名参数construct_id

参数和属性

所有 C AWS onstruct Library 类都使用三个参数进行实例化:定义构造的作用域(构造树中的父级)、idprops(构造函数用来配置其创建的资源的键/值对)。其他类和方法也使用“属性捆绑包”模式作为参数。

scopeid 应始终作为位置参数而不是关键字参数进行传递,因为如果构造接受名为 scopeid 的属性,其名称就会改变。

在 Python 中,props 表示为关键字参数。如果参数包含嵌套数据结构,则使用在实例化时采用其自身关键字参数的类来表示这些结构。同样的模式也适用于采用结构化参数的其他方法调用。

例如,在 Amazon S3 存储桶的add_lifecycle_rule方法中,该transitions属性是一个Transition实例列表。

bucket.add_lifecycle_rule( transitions=[ Transition( storage_class=StorageClass.GLACIER, transition_after=Duration.days(10) ) ] )

扩展某个类或重写某种方法时,您可能希望接受父类无法理解的其他参数,以满足自己的目的。在这种情况下,你应该使用**kwargs成语接受你不在乎的论点,并使用仅限关键字的参数来接受你感兴趣的参数。在调用父级的构造函数或被重写的方法时,只传递它期望的参数(通常只是**kwargs)。传递父类或方法不期望的参数会导致错误。

class MyConstruct(Construct): def __init__(self, id, *, MyProperty=42, **kwargs): super().__init__(self, id, **kwargs) # ...

Future 版本的 AWS CDK 可能会巧合地添加一个新属性,其名称是你用于自己的财产。这不会给你的构造或方法的用户造成任何技术问题(由于你的属性不是 “向上链” 传递的,所以父类或被重写的方法只会使用默认值),但可能会引起混淆。您可以对属性进行命名来避免这个潜在问题,这样它们就明确属于您的构造。如果有许多新属性,请将其捆绑到一个适当命名的类中,然后将其用作单个关键字参数进行传递。

缺失值

AWS CDK None 用来表示缺失或未定义的值。使用**kwargs 时,如果未提供属性,则使用字典的get()方法提供默认值。避免使用 kwargs[…​],因为这会引发缺失值的 KeyError

encrypted = kwargs.get("encrypted") # None if no property "encrypted" exists encrypted = kwargs.get("encrypted", False) # specify default of False if property is missing

某些 AWS CDK 方法(例如tryGetContext()获取运行时上下文值)可能会返回None,您需要明确检查这些方法。

使用接口

Python 不像其他一些语言那样具有接口功能,尽管它确实有类似的抽象基类。(如果你不熟悉界面,维基百科有一个很好的介绍。) TypeScript,实现 AWS CDK 所用的语言,确实提供了接口,而构造和其他 AWS CDK 对象通常需要一个附属于特定接口的对象,而不是从特定类继承的对象。因此,作为 JSI I 层的一部分, AWS CDK 提供了自己的接口功能。

要表示一个类实现了特定的接口,可以使用 @jsii.implements 装饰器:

from aws_cdk import IAspect, IConstruct import jsii @jsii.implements(IAspect) class MyAspect(): def visit(self, node: IConstruct) -> None: print("Visited", node.node.path)

类型陷阱

Python 使用动态类型,其中所有变量都可以表示任何类型的值。参数和返回值可以用类型进行注释,但这些是“提示”,不会强制执行。这意味着在 Python 中,很容易将错误类型的值传递给 AWS CDK 构造。当JSII层(在Python和 AWS CDK的 TypeScript 核心之间进行转换)无法处理意外类型时,您可能会遇到运行时错误,而不是像静态类型语言那样在构建过程中出现类型错误。

根据我们的经验,Python 程序员犯的类型错误往往属于以下类别。

  • 在构造需要容器(Python 列表或词典)的地方传递单个值,反之亦然。

  • 将与第 1 层 (CfnXxxxxx) 构造关联的类型的值传递给 L2 或 L3 构造,反之亦然。

AWS CDK Python 模块确实包含类型注释,因此您可以使用支持它们的工具来帮助处理类型。如果您使用的不是支持这些功能的 IDE(例如)PyCharm,则可能需要调用MyPy类型验证器作为构建过程中的一个步骤。还有一些运行时类型检查器,可以改进类型相关错误的错误消息。