跳转到内容

Python 项目

Python 项目生成器可用于创建现代化的 Python 库或应用程序,配置了最佳实践,使用 UV 进行管理,在 UV 工作空间中使用单一锁文件和虚拟环境,使用 pytest 运行测试,使用 Ruff 进行静态分析,使用 ty 进行类型检查。

您可以通过两种方式生成新的 Python 项目:

Terminal window
pnpm nx g @aws/nx-plugin:py#project
您还可以执行试运行以查看哪些文件会被更改
Terminal window
pnpm nx g @aws/nx-plugin:py#project --dry-run
参数类型默认值描述
name 必需string-Python 项目的名称
directory stringpackages项目所在的父目录
subDirectory string-项目所在的子目录。默认情况下为项目名称。
type 必需application | libraryapplication项目是应用程序还是库
moduleName string-Python 模块名称
preferInstallDependencies booleantrue是否在生成器运行后优先安装依赖项。设置为 false 可在批量运行多个生成器时延迟安装(如果后续生成器需要计算 Nx 项目图,仍会运行安装);在最后统一安装一次。

生成器将在 <directory>/<name> 目录中创建以下项目结构:

  • 文件夹<module-name>
    • __init__.py Module initialisation
  • 文件夹tests
    • __init__.py Module initialisation
    • conftest.py Test configuration
    • test_noop.py Placeholder test
  • project.json Project configuration and build targets
  • pyproject.toml Packaging configuration file used by UV
  • .python-version Contains the project’s Python version

您还可能注意到在工作空间根目录中创建/更新了以下文件:

  • pyproject.toml Workspace level packaging configuration for UV
  • .python-version Contains the workspace Python version
  • uv.lock Lockfile for Python dependencies

<module-name> 目录中添加您的 Python 源代码。

使用 add 目标向 Python 项目添加依赖项。

假设我们创建了两个 Python 项目,my_appmy_lib。它们的完全限定项目名称将是 my_scope.my_appmy_scope.my_lib,默认情况下,它们的模块名称分别为 my_scope_my_appmy_scope_my_lib

要让 my_app 依赖于 my_lib,我们可以运行以下命令:

Terminal window
pnpm nx run my_scope.my_app:add my_scope.my_lib

然后您可以导入您的库代码:

packages/my_app/my_scope_my_app/main.py
from my_scope_my_lib.my_module import my_function

上面,my_scope_my_lib 是库的模块名称,my_module 对应于 Python 源文件 my_module.pymy_function 是该文件中定义的方法。

要向您的项目添加依赖项,您可以在 Python 项目中运行 add 目标,例如:

Terminal window
pnpm nx run my_scope.my_library:add some-pip-package

这将把依赖项添加到您项目的 pyproject.toml 文件中,并更新根目录的 uv.lock

当您将 Python 项目用作运行时代码(例如作为 AWS lambda 函数的处理程序)时,您需要创建源代码及其所有依赖项的捆绑包。您可以通过向 project.json 文件添加如下目标来实现:

project.json
{
...
"targets": {
...
"bundle": {
"cache": true,
"executor": "nx:run-commands",
"outputs": ["{workspaceRoot}/dist/packages/my_library/bundle"],
"options": {
"commands": [
"uv export --frozen --no-dev --no-editable --project packages/my_library --package my_scope.my_library -o dist/packages/my_library/bundle/requirements.txt",
"uv pip install -n --no-deps --no-installer-metadata --no-compile-bytecode --python-platform x86_64-manylinux_2_28 --python `uv python pin` --target dist/packages/my_library/bundle -r dist/packages/my_library/bundle/requirements.txt"
],
"parallel": false
},
"dependsOn": ["compile"]
},
},
}

您的 Python 项目配置了 build 目标(在 project.json 中定义),您可以通过以下方式运行:

Terminal window
pnpm nx build <project-name>

其中 <project-name> 是您项目的完全限定名称。

build 目标将编译、检查、测试和类型检查您的项目。

构建输出可以在工作空间根目录的 dist 文件夹中找到,位于您的包和目标的目录中,例如 dist/packages/<my-library>/build

要构建工作空间中的所有项目,请运行:

Terminal window
pnpm nx run-many --target build

或使用简写命令:

Terminal window
pnpm build

pytest 已配置用于测试您的项目。

测试应该写在项目中的 test 目录中,在以 test_ 为前缀的 Python 文件中,例如:

  • 文件夹my_library
    • my_module.py
  • 文件夹tests
    • test_my_module.py Tests for my_module.py

测试是以 test_ 开头并进行断言以验证预期的方法,例如:

tests/test_my_module.py
from my_library.my_module import say_hello
def test_say_hello():
assert say_hello("Darth Vader") == "Hello, Darth Vader!"

有关如何编写测试的更多详细信息,请参阅 pytest 文档

测试将作为项目的 build 目标的一部分运行,但您也可以通过运行 test 目标单独运行它们:

Terminal window
pnpm nx test <project-name>

您可以使用 -k 标志运行单个测试或测试套件,指定测试文件或方法的名称:

Terminal window
pnpm nx test <project-name> -k 'test_say_hello'

Python 项目使用 ty 进行类型检查。

类型检查作为项目的 build 目标的一部分运行,但您也可以通过 typecheck 目标单独运行它:

Terminal window
pnpm nx run <project-name>:typecheck

要抑制单行的特定诊断,请在行尾添加 # ty: ignore[<rule>] 注释,例如:

value: int = "not an int" # ty: ignore[invalid-assignment]

要在整个项目中配置类型检查行为,请在项目的 pyproject.toml 中添加 [tool.ty] 部分。有关可用选项,请参阅 ty 配置参考

Python 项目使用 Ruff 进行代码检查。

要调用代码检查器检查您的项目,您可以运行 lint 目标。

Terminal window
pnpm nx lint <project-name>

大多数代码检查或格式化问题可以自动修复。您可以通过使用 --configuration=fix 参数运行来告诉 Ruff 修复代码检查问题。

Terminal window
pnpm nx lint <project-name> --configuration=fix

同样,如果您想修复工作空间中所有包的所有代码检查问题,您可以运行:

Terminal window
pnpm nx run-many --target lint --all --configuration=fix

为了避免代码检查问题在开发过程中拖慢您的速度(特别是如果您的项目中有无法自动修复的问题),您可以使用 skip-lint 配置运行构建:

Terminal window
pnpm nx run-many --target build --configuration=skip-lint

这仍然会在构建过程中运行 Ruff,但代码检查目标将始终被视为成功。