跳转到内容

Python 项目

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

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

运行此生成器@aws/nx-plugin:py#project

pnpm nx g @aws/nx-plugin:py#project
构建你的命令6

必需

必需

生成器选项6 个选项
name必需string

Python 项目的名称

type必需enum默认值: application

项目是应用程序还是库

applicationlibrary
directorystring默认值: packages

项目所在的父目录

subDirectorystring

项目所在的子目录。默认情况下为项目名称。

moduleNamestring

Python 模块名称

preferInstallDependenciesboolean默认值: true

是否在生成器运行后优先安装依赖项。设置为 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 函数的处理程序)时,您需要创建源代码及其所有依赖项的捆绑包。py#lambda-functionpy#apipy#mcp-server 生成器会为您添加此功能。要手动添加,请向您的 project.json 文件添加如下目标,匹配这些生成器提供的形式:

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

使用以下命令安装 Python 依赖项:

终端窗口
uv sync

您的 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

您的项目还有一个 assemble 目标,它生成项目对部署的贡献内容(例如其编译或捆绑的输出),而不运行代码检查、测试或类型检查关卡。

Terminal window
pnpm nx assemble <project-name>

部署目标依赖于 assemble,因此部署仅构建即将部署的内容。

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

测试应该写在项目中的 tests 目录中,在以 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'

您项目的 tests 目录被排除在 nx.json 中的 production 命名输入之外。

输出不能包含测试文件的目标(例如 compile 和任何捆绑目标)读取 production 而不是 default,因此编辑测试不会使它们或依赖于您的项目中的任何任务失效。

排除范围被有意限制在 tests 目录。包目录中的 test_*.py 文件被视为生产代码,因为它会被打包到构建的分发版本中,因此仍会使构建失效。

testlintformattypecheck 目标读取 default,因此在您编辑测试时仍会重新运行。请注意,typecheck 也会对您的测试进行类型检查,因此测试中的类型错误仍会被报告。

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,但代码检查目标将始终被视为成功。