aws-lambda-builders 1.61.0__tar.gz → 1.62.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. {aws_lambda_builders-1.61.0/aws_lambda_builders.egg-info → aws_lambda_builders-1.62.0}/PKG-INFO +4 -3
  2. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/README.md +1 -0
  3. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/__init__.py +1 -1
  4. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/__init__.py +1 -0
  5. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/java_maven/maven.py +4 -4
  6. aws_lambda_builders-1.62.0/aws_lambda_builders/workflows/python_uv/DESIGN.md +363 -0
  7. aws_lambda_builders-1.62.0/aws_lambda_builders/workflows/python_uv/__init__.py +5 -0
  8. aws_lambda_builders-1.62.0/aws_lambda_builders/workflows/python_uv/actions.py +76 -0
  9. aws_lambda_builders-1.62.0/aws_lambda_builders/workflows/python_uv/exceptions.py +31 -0
  10. aws_lambda_builders-1.62.0/aws_lambda_builders/workflows/python_uv/packager.py +425 -0
  11. aws_lambda_builders-1.62.0/aws_lambda_builders/workflows/python_uv/utils.py +149 -0
  12. aws_lambda_builders-1.62.0/aws_lambda_builders/workflows/python_uv/workflow.py +173 -0
  13. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0/aws_lambda_builders.egg-info}/PKG-INFO +4 -3
  14. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders.egg-info/SOURCES.txt +7 -0
  15. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders.egg-info/requires.txt +2 -2
  16. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/requirements/dev.txt +2 -2
  17. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/LICENSE +0 -0
  18. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/MANIFEST.in +0 -0
  19. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/NOTICE +0 -0
  20. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/__main__.py +0 -0
  21. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/actions.py +0 -0
  22. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/architecture.py +0 -0
  23. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/binary_path.py +0 -0
  24. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/builder.py +0 -0
  25. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/exceptions.py +0 -0
  26. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/path_resolver.py +0 -0
  27. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/registry.py +0 -0
  28. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/supported_runtimes.py +0 -0
  29. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/utils.py +0 -0
  30. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/validator.py +0 -0
  31. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflow.py +0 -0
  32. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/custom_make/DESIGN.md +0 -0
  33. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/custom_make/__init__.py +0 -0
  34. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/custom_make/actions.py +0 -0
  35. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/custom_make/exceptions.py +0 -0
  36. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/custom_make/make.py +0 -0
  37. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/custom_make/utils.py +0 -0
  38. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/custom_make/validator.py +0 -0
  39. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/custom_make/workflow.py +0 -0
  40. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/dotnet_clipackage/DESIGN.md +0 -0
  41. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/dotnet_clipackage/__init__.py +0 -0
  42. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/dotnet_clipackage/actions.py +0 -0
  43. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/dotnet_clipackage/dotnetcli.py +0 -0
  44. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/dotnet_clipackage/dotnetcli_resolver.py +0 -0
  45. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/dotnet_clipackage/utils.py +0 -0
  46. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/dotnet_clipackage/workflow.py +0 -0
  47. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/go_modules/DESIGN.md +0 -0
  48. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/go_modules/__init__.py +0 -0
  49. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/go_modules/actions.py +0 -0
  50. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/go_modules/builder.py +0 -0
  51. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/go_modules/utils.py +0 -0
  52. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/go_modules/validator.py +0 -0
  53. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/go_modules/workflow.py +0 -0
  54. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/java/__init__.py +0 -0
  55. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/java/actions.py +0 -0
  56. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/java/utils.py +0 -0
  57. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/java_gradle/DESIGN.md +0 -0
  58. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/java_gradle/__init__.py +0 -0
  59. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/java_gradle/actions.py +0 -0
  60. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/java_gradle/gradle.py +0 -0
  61. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/java_gradle/gradle_resolver.py +0 -0
  62. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/java_gradle/gradle_validator.py +0 -0
  63. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/java_gradle/resources/lambda-build-init.gradle +0 -0
  64. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/java_gradle/workflow.py +0 -0
  65. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/java_maven/DESIGN.md +0 -0
  66. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/java_maven/__init__.py +0 -0
  67. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/java_maven/actions.py +0 -0
  68. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/java_maven/maven_resolver.py +0 -0
  69. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/java_maven/maven_validator.py +0 -0
  70. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/java_maven/workflow.py +0 -0
  71. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/nodejs_npm/DESIGN.md +0 -0
  72. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/nodejs_npm/__init__.py +0 -0
  73. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/nodejs_npm/actions.py +0 -0
  74. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/nodejs_npm/exceptions.py +0 -0
  75. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/nodejs_npm/npm.py +0 -0
  76. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/nodejs_npm/utils.py +0 -0
  77. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/nodejs_npm/workflow.py +0 -0
  78. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/nodejs_npm_esbuild/DESIGN.md +0 -0
  79. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/nodejs_npm_esbuild/__init__.py +0 -0
  80. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/nodejs_npm_esbuild/actions.py +0 -0
  81. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/nodejs_npm_esbuild/esbuild.py +0 -0
  82. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/nodejs_npm_esbuild/exceptions.py +0 -0
  83. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/nodejs_npm_esbuild/workflow.py +0 -0
  84. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/python_pip/DESIGN.md +0 -0
  85. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/python_pip/__init__.py +0 -0
  86. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/python_pip/actions.py +0 -0
  87. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/python_pip/compat.py +0 -0
  88. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/python_pip/exceptions.py +0 -0
  89. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/python_pip/packager.py +0 -0
  90. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/python_pip/utils.py +0 -0
  91. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/python_pip/validator.py +0 -0
  92. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/python_pip/workflow.py +0 -0
  93. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/ruby_bundler/DESIGN.md +0 -0
  94. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/ruby_bundler/__init__.py +0 -0
  95. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/ruby_bundler/actions.py +0 -0
  96. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/ruby_bundler/bundler.py +0 -0
  97. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/ruby_bundler/utils.py +0 -0
  98. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/ruby_bundler/workflow.py +0 -0
  99. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/rust_cargo/DESIGN.md +0 -0
  100. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/rust_cargo/__init__.py +0 -0
  101. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/rust_cargo/actions.py +0 -0
  102. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/rust_cargo/cargo_lambda.py +0 -0
  103. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/rust_cargo/exceptions.py +0 -0
  104. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/rust_cargo/feature_flag.py +0 -0
  105. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/rust_cargo/utils.py +0 -0
  106. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders/workflows/rust_cargo/workflow.py +0 -0
  107. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders.egg-info/dependency_links.txt +0 -0
  108. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders.egg-info/entry_points.txt +0 -0
  109. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/aws_lambda_builders.egg-info/top_level.txt +0 -0
  110. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/pyproject.toml +0 -0
  111. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/requirements/base.txt +0 -0
  112. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/requirements/python_pip.txt +0 -0
  113. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/setup.cfg +0 -0
  114. {aws_lambda_builders-1.61.0 → aws_lambda_builders-1.62.0}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aws_lambda_builders
3
- Version: 1.61.0
3
+ Version: 1.62.0
4
4
  Summary: Python library to compile, build & package AWS Lambda functions for several runtimes & frameworks.
5
5
  Home-page: https://github.com/awslabs/aws-lambda-builders
6
6
  Author: Amazon Web Services
@@ -39,9 +39,9 @@ Requires-Dist: pytest-cov==5.0.0; python_version < "3.9" and extra == "dev"
39
39
  Requires-Dist: pytest>=6.1.1; extra == "dev"
40
40
  Requires-Dist: parameterized==0.9.0; extra == "dev"
41
41
  Requires-Dist: pyelftools~=0.32; extra == "dev"
42
- Requires-Dist: black==25.9.0; python_version >= "3.9" and extra == "dev"
42
+ Requires-Dist: black==25.11.0; python_version >= "3.9" and extra == "dev"
43
43
  Requires-Dist: black==24.8.0; python_version < "3.9" and extra == "dev"
44
- Requires-Dist: ruff==0.11.13; extra == "dev"
44
+ Requires-Dist: ruff==0.14.13; extra == "dev"
45
45
  Dynamic: author
46
46
  Dynamic: author-email
47
47
  Dynamic: classifier
@@ -71,6 +71,7 @@ Lambda Builders currently contains the following workflows
71
71
  * Java with Maven
72
72
  * Dotnet with amazon.lambda.tools
73
73
  * Python with Pip
74
+ * Python with Uv (beta)
74
75
  * Javascript with Npm
75
76
  * Typescript with esbuild
76
77
  * Ruby with Bundler
@@ -14,6 +14,7 @@ Lambda Builders currently contains the following workflows
14
14
  * Java with Maven
15
15
  * Dotnet with amazon.lambda.tools
16
16
  * Python with Pip
17
+ * Python with Uv (beta)
17
18
  * Javascript with Npm
18
19
  * Typescript with esbuild
19
20
  * Ruby with Bundler
@@ -5,5 +5,5 @@ AWS Lambda Builder Library
5
5
  # Changing version will trigger a new release!
6
6
  # Please make the version change as the last step of your development.
7
7
 
8
- __version__ = "1.61.0"
8
+ __version__ = "1.62.0"
9
9
  RPC_PROTOCOL_VERSION = "0.3"
@@ -10,5 +10,6 @@ import aws_lambda_builders.workflows.java_maven
10
10
  import aws_lambda_builders.workflows.nodejs_npm
11
11
  import aws_lambda_builders.workflows.nodejs_npm_esbuild
12
12
  import aws_lambda_builders.workflows.python_pip
13
+ import aws_lambda_builders.workflows.python_uv
13
14
  import aws_lambda_builders.workflows.ruby_bundler
14
15
  import aws_lambda_builders.workflows.rust_cargo
@@ -28,21 +28,21 @@ class SubprocessMaven(object):
28
28
 
29
29
  def build(self, scratch_dir):
30
30
  args = ["clean", "install"]
31
- ret_code, stdout, _ = self._run(args, scratch_dir)
31
+ ret_code, stdout, stderr = self._run(args, scratch_dir)
32
32
 
33
33
  LOG.debug("Maven logs: %s", decode(stdout))
34
34
 
35
35
  if ret_code != 0:
36
- raise MavenExecutionError(message=decode(stdout))
36
+ raise MavenExecutionError(message=decode(stderr))
37
37
 
38
38
  def copy_dependency(self, scratch_dir):
39
39
  include_scope = "runtime"
40
40
  LOG.debug("Running copy_dependency with scope: %s", include_scope)
41
41
  args = ["dependency:copy-dependencies", f"-DincludeScope={include_scope}", "-Dmdep.prependGroupId=true"]
42
- ret_code, stdout, _ = self._run(args, scratch_dir)
42
+ ret_code, stdout, stderr = self._run(args, scratch_dir)
43
43
 
44
44
  if ret_code != 0:
45
- raise MavenExecutionError(message=decode(stdout))
45
+ raise MavenExecutionError(message=decode(stderr))
46
46
 
47
47
  def _run(self, args, cwd=None):
48
48
  p = self.os_utils.popen(
@@ -0,0 +1,363 @@
1
+ ## Python - UV Lambda Builder
2
+
3
+ ### Scope
4
+
5
+ This package provides a Python dependency builder that uses UV (An extremely fast Python package installer and resolver, written in Rust) as an alternative to the traditional pip-based workflow. The scope for this builder is to take an existing directory containing customer code, and dependency specification files (such as `pyproject.toml` or `requirements.txt`) and use UV to build and include the dependencies in the customer code bundle in a way that makes them importable in AWS Lambda.
6
+
7
+ UV offers several advantages over pip:
8
+ - **Performance**: UV is significantly faster than pip for dependency resolution and installation
9
+ - **Better dependency resolution**: More reliable and consistent dependency resolution
10
+ - **Lock file support**: Native support for lock files for reproducible builds
11
+ - **Modern Python packaging**: Built-in support for modern Python packaging standards (PEP 517/518)
12
+ - **Virtual environment management**: Integrated virtual environment handling
13
+
14
+ ### Challenges
15
+
16
+ Similar to the Python PIP workflow, Python packaging for AWS Lambda presents unique challenges:
17
+
18
+ 1. **Platform compatibility**: Python packages often contain platform-specific code or compiled extensions that must be compatible with the AWS Lambda runtime environment (Amazon Linux 2)
19
+
20
+ 2. **Architecture compatibility**: Packages must be compatible with the target Lambda architecture (x86_64 or arm64)
21
+
22
+ 3. **Dependency resolution complexity**: Complex dependency trees with potential conflicts need to be resolved consistently
23
+
24
+ 4. **Binary dependencies**: Some packages require compilation of C extensions or have binary dependencies that must be built for the target platform
25
+
26
+ 5. **Package size optimization**: Lambda has deployment package size limits, requiring efficient dependency packaging
27
+
28
+ UV addresses many of these challenges through:
29
+ - Better dependency resolution algorithms
30
+ - Improved handling of platform-specific wheels
31
+ - More efficient caching mechanisms
32
+ - Better support for lock files ensuring reproducible builds
33
+
34
+ ### Interface
35
+
36
+ The top level interface is presented by the `PythonUvDependencyBuilder` class. There will be one public method `build_dependencies`, which takes the provided arguments and builds python dependencies using UV under the hood.
37
+
38
+ ```python
39
+ def build_dependencies(artifacts_dir_path,
40
+ scratch_dir_path,
41
+ manifest_path,
42
+ architecture=None,
43
+ config=None,
44
+ ):
45
+ """Builds a python project's dependencies into an artifact directory using UV.
46
+
47
+ Note: The runtime parameter is passed to the PythonUvDependencyBuilder constructor,
48
+ not to this method.
49
+
50
+ :type artifacts_dir_path: str
51
+ :param artifacts_dir_path: Directory to write dependencies into.
52
+
53
+ :type scratch_dir_path: str
54
+ :param scratch_dir_path: Temporary directory for build operations and intermediate files.
55
+
56
+ :type manifest_path: str
57
+ :param manifest_path: Path to a dependency manifest file. Supported manifests:
58
+ - pyproject.toml (preferred for modern Python projects)
59
+ - requirements.txt (traditional pip format)
60
+ - requirements-*.txt (environment-specific: dev, test, prod, etc.)
61
+
62
+ Note: uv.lock is NOT a valid manifest - it's a lock file that automatically
63
+ enhances pyproject.toml builds when present in the same directory.
64
+
65
+ :type runtime: str
66
+ :param runtime: Python version to build dependencies for. This can
67
+ be python3.8, python3.9, python3.10, python3.11, python3.12, or python3.13.
68
+ These are currently the only supported values.
69
+ Note: This parameter is passed to the PythonUvDependencyBuilder constructor.
70
+
71
+ :type config: :class:`lambda_builders.actions.python_uv.utils.UvConfig`
72
+ :param config: Optional config object for customizing UV behavior,
73
+ including cache settings, index URLs, and build options.
74
+
75
+ :type architecture: str
76
+ :param architecture: Target architecture for Lambda compatibility (x86_64 or arm64).
77
+ Defaults to x86_64 if not specified.
78
+ """
79
+ ```
80
+
81
+ ### Usage Pattern
82
+
83
+ The `PythonUvDependencyBuilder` follows a constructor + method call pattern:
84
+
85
+ ```python
86
+ # 1. Create builder with runtime
87
+ builder = PythonUvDependencyBuilder(
88
+ osutils=osutils,
89
+ runtime="python3.9", # Runtime specified here
90
+ uv_runner=uv_runner
91
+ )
92
+
93
+ # 2. Call build_dependencies method
94
+ builder.build_dependencies(
95
+ artifacts_dir_path="/path/to/artifacts",
96
+ scratch_dir_path="/path/to/scratch",
97
+ manifest_path="/path/to/pyproject.toml",
98
+ architecture="x86_64",
99
+ config=uv_config
100
+ )
101
+ ```
102
+
103
+ ### Implementation
104
+
105
+ The general algorithm for preparing a python package using UV for use on AWS Lambda follows a streamlined approach that leverages UV's advanced capabilities:
106
+
107
+ #### Step 1: Smart manifest detection and dispatch
108
+
109
+ The workflow uses a smart dispatch system that recognizes actual manifest files:
110
+
111
+ **Supported Manifests:**
112
+ - `pyproject.toml` - Modern Python project manifest
113
+ - `requirements.txt` - Traditional pip requirements file
114
+ - `requirements-*.txt` - Environment-specific variants (dev, prod, test, etc.)
115
+
116
+ **Smart Lock File Detection:**
117
+ - Look for requirements.txt first
118
+ - When `pyproject.toml` is the manifest, automatically checks for `uv.lock` in the same directory
119
+ - If `uv.lock` exists alongside `pyproject.toml`, uses lock-based build for precise dependencies
120
+ - If no `uv.lock`, uses standard pyproject.toml build with UV's lock and export workflow
121
+
122
+ **Important:** `uv.lock` is NOT a standalone manifest - it's a lock file that enhances `pyproject.toml` builds when present.
123
+
124
+ #### Step 2: Build dependencies based on manifest type
125
+
126
+ **For pyproject.toml with uv.lock present:**
127
+ - Use `uv export` to convert lock file to requirements.txt format
128
+ - Install using `uv pip install` with platform targeting (--python-platform)
129
+ - Provides reproducible builds with locked dependency versions AND cross-platform support
130
+
131
+ **For pyproject.toml without uv.lock:**
132
+ - Use `uv lock` to create temporary lock file with resolved dependencies
133
+ - Use `uv export` to convert lock file to requirements.txt format
134
+ - Install dependencies using `uv pip install` with platform targeting
135
+
136
+ **For requirements.txt files:**
137
+ - Use `uv pip install` directly with Lambda-compatible settings
138
+
139
+ **Why export + pip install instead of uv sync?**
140
+ `uv sync` doesn't support cross-platform builds (no --python-platform flag). Since Lambda
141
+ requires building for Linux (x86_64 or ARM64) regardless of the build machine's OS, we use
142
+ `uv export` to convert lock files to requirements.txt, then `uv pip install` which supports
143
+ the `--python-platform` flag for cross-platform wheel selection.
144
+
145
+ #### Step 3: Configure Lambda-compatible installation
146
+
147
+ UV is configured with Lambda-specific settings:
148
+ - Target platform: `linux` (Amazon Linux 2)
149
+ - Target architecture: `x86_64` or `aarch64`
150
+ - Python version matching Lambda runtime
151
+ - Prefer wheels over source distributions for faster builds
152
+
153
+ #### Step 4: Install to target directory
154
+
155
+ Install resolved dependencies to the Lambda deployment package:
156
+ - Extract packages to artifacts directory
157
+ - Maintain proper Python package structure
158
+ - Ensure all packages are importable from Lambda function
159
+
160
+ This streamlined approach leverages UV's built-in capabilities rather than manually implementing dependency resolution, compilation handling, and optimization steps that UV already performs efficiently.
161
+
162
+ ### UV-Specific Features
163
+
164
+ This workflow leverages several UV-specific features that provide advantages over the traditional pip workflow:
165
+
166
+ #### Lock File Support
167
+ - **Reproducible builds**: `uv.lock` files ensure identical dependency versions across builds
168
+ - **Faster subsequent builds**: Lock files eliminate dependency resolution time
169
+ - **Conflict detection**: Early detection of dependency conflicts during resolution
170
+
171
+ #### Advanced Dependency Resolution
172
+ - **Better conflict resolution**: UV's resolver handles complex dependency graphs more reliably
173
+ - **Version range optimization**: More intelligent selection of compatible versions
174
+ - **Platform-aware resolution**: Better handling of platform-specific dependencies
175
+
176
+ #### Performance Optimizations
177
+ - **Parallel downloads**: Multiple packages downloaded simultaneously
178
+ - **Efficient caching**: Smart caching reduces redundant downloads and builds
179
+ - **Fast installs**: Rust-based implementation provides significant speed improvements
180
+
181
+ #### Modern Python Standards
182
+ - **PEP 517/518 support**: Native support for modern Python packaging standards
183
+ - **pyproject.toml first**: Preferred support for modern project configuration
184
+ - **Build isolation**: Proper build environment isolation for reliable builds
185
+
186
+ ### Error Handling and Diagnostics
187
+
188
+ The UV workflow provides enhanced error handling:
189
+
190
+ 1. **Dependency resolution errors**: Clear reporting of version conflicts and resolution failures
191
+ 2. **Platform compatibility warnings**: Explicit warnings about potential platform issues
192
+ 3. **Build failures**: Detailed error messages for compilation and build failures
193
+ 4. **Lock file conflicts**: Detection and reporting of lock file inconsistencies
194
+ 5. **Performance metrics**: Optional reporting of build times and cache efficiency
195
+
196
+ ### Configuration Options
197
+
198
+ The workflow supports various configuration options through the config parameter:
199
+
200
+ ```python
201
+ config = {
202
+ "index_url": "https://pypi.org/simple/", # Custom package index
203
+ "extra_index_urls": [], # Additional package indexes
204
+ "cache_dir": "/tmp/uv-cache", # Custom cache directory
205
+ "no_cache": False, # Disable caching
206
+ "prerelease": "disallow", # Handle pre-release versions
207
+ "resolution": "highest", # Resolution strategy
208
+ "compile_bytecode": True, # Compile .pyc files
209
+ "exclude_newer": None, # Exclude packages newer than date
210
+ "generate_hashes": False, # Generate package hashes
211
+ }
212
+ ```
213
+
214
+ ### Compatibility with Existing Workflows
215
+
216
+ The UV workflow is designed to be a drop-in replacement for the pip workflow:
217
+ - Supports the same manifest formats (requirements.txt, pyproject.toml)
218
+ - Uses native UV commands for pyproject.toml (lock/export workflow)
219
+ - Maintains the same output structure and package layout
220
+ - Compatible with existing Lambda deployment processes
221
+ - Provides migration path from pip-based builds
222
+ - Follows established requirements file naming conventions
223
+
224
+ ### Architecture Components
225
+
226
+ The UV workflow consists of several key components that mirror the PIP workflow structure:
227
+
228
+ #### Core Classes
229
+
230
+ 1. **PythonUvWorkflow**: Main workflow class that orchestrates the build process
231
+ 2. **PythonUvBuildAction**: Action class that handles dependency resolution
232
+ 3. **UvRunner**: Wrapper around UV command execution
233
+ 4. **SubprocessUv**: Low-level UV subprocess interface
234
+ 6. **PythonUvDependencyBuilder**: High-level dependency builder orchestrator
235
+
236
+ #### File Structure
237
+ ```
238
+ python_uv/
239
+ ├── __init__.py
240
+ ├── DESIGN.md
241
+ ├── workflow.py # Main workflow implementation
242
+ ├── actions.py # Build actions
243
+ ├── packager.py # Core packaging logic
244
+ ├── utils.py # Utility functions
245
+ └── exceptions.py # UV-specific exceptions
246
+ ```
247
+
248
+ #### Capability Definition
249
+ ```python
250
+ CAPABILITY = Capability(
251
+ language="python",
252
+ dependency_manager="uv",
253
+ application_framework=None
254
+ )
255
+ ```
256
+
257
+ #### Smart Manifest Detection and Dispatch
258
+
259
+ The workflow uses intelligent manifest detection:
260
+
261
+ **Supported Manifests (in order of preference):**
262
+ 1. `requirements.txt` - Standard pip format
263
+ 2. `requirements-*.txt` - Environment-specific variants (dev, test, prod, etc.)
264
+ 3. `pyproject.toml` - Modern Python project manifest
265
+
266
+ **Smart Lock File Enhancement:**
267
+ - When `pyproject.toml` is used, automatically detects `uv.lock` in the same directory
268
+ - If `uv.lock` exists, uses lock-based build for reproducible dependencies
269
+ - If no `uv.lock`, uses standard pyproject.toml workflow with UV's lock and export
270
+
271
+ **Important:** `uv.lock` is NOT a standalone manifest - attempting to use it as one will result in an "Unsupported manifest file" error.
272
+
273
+ #### Requirements File Naming Conventions
274
+ The workflow follows Python ecosystem standards for requirements files:
275
+ - `requirements.txt` - Standard format (primary)
276
+ - `requirements-dev.txt` - Development dependencies
277
+ - `requirements-test.txt` - Test dependencies
278
+ - `requirements-prod.txt` - Production dependencies
279
+ - `requirements-staging.txt` - Staging dependencies
280
+
281
+ Note: `requirements.in` (pip-tools format) is not supported to keep the implementation simple and focused.
282
+
283
+ #### UV Binary Requirements
284
+ - UV must be available on the system PATH
285
+ - Minimum UV version: 0.1.0 (to be determined based on feature requirements)
286
+ - Fallback: Attempt to install UV using pip if not found (optional behavior)
287
+
288
+ #### Error Handling Strategy
289
+ - **MissingUvError**: UV binary not found on PATH (includes path information)
290
+ - **UvInstallationError**: UV installation/setup failures
291
+ - **UvBuildError**: Package build failures
292
+ - **LockFileError**: Lock file parsing or validation errors
293
+
294
+ #### Platform Compatibility Matrix
295
+ | Python Version | x86_64 | arm64 | Status |
296
+ |---------------|--------|-------|---------|
297
+ | python3.8 | ✓ | ✓ | Supported |
298
+ | python3.9 | ✓ | ✓ | Supported |
299
+ | python3.10 | ✓ | ✓ | Supported |
300
+ | python3.11 | ✓ | ✓ | Supported |
301
+ | python3.12 | ✓ | ✓ | Supported |
302
+ | python3.13 | ✓ | ✓ | Supported |
303
+ | python3.13 | ✓ | ✓ | Supported |
304
+
305
+ #### Integration with Lambda Builders
306
+ - Registers with the workflow registry automatically
307
+ - Follows the same build lifecycle as other workflows
308
+ - Compatible with existing SAM CLI integration
309
+ - Supports all standard build options (scratch_dir, dependencies_dir, etc.)
310
+
311
+ ### Implementation Phases
312
+
313
+ #### Phase 1: Core Infrastructure
314
+ 1. Basic workflow and action classes
315
+ 2. UV binary detection and validation
316
+ 3. Simple requirements.txt support
317
+ 4. Basic error handling
318
+
319
+ #### Phase 2: Advanced Features
320
+ 1. pyproject.toml support
321
+ 2. Lock file handling
322
+ 3. Advanced configuration options
323
+ 4. Performance optimizations
324
+
325
+ #### Phase 3: Production Readiness
326
+ 1. Comprehensive testing
327
+ 2. Error message improvements
328
+ 3. Documentation and examples
329
+ 4. Performance benchmarking
330
+
331
+ ### Testing Strategy
332
+
333
+ #### Unit Tests
334
+ - UV binary detection and validation
335
+ - Manifest file parsing and detection
336
+ - Dependency resolution logic
337
+ - Error handling scenarios
338
+ - Platform compatibility checks
339
+
340
+ #### Integration Tests
341
+ - End-to-end build scenarios
342
+ - Different manifest file formats
343
+ - Lock file generation and usage
344
+ - Multi-architecture builds
345
+ - Performance comparisons with pip
346
+
347
+ #### Compatibility Tests
348
+ - Migration from pip to UV workflows
349
+ - Existing SAM CLI integration
350
+ - Various Python project structures
351
+ - Different dependency complexity levels
352
+
353
+ ### Future Enhancements
354
+
355
+ Potential future improvements to the UV workflow:
356
+ - **Dependency vulnerability scanning**: Integration with security scanning tools
357
+ - **Package size optimization**: Advanced techniques for reducing package size
358
+ - **Multi-platform builds**: Support for building packages for multiple architectures simultaneously
359
+ - **Custom build hooks**: Support for custom build steps and transformations
360
+ - **Integration with other tools**: Better integration with other Python development tools
361
+ - **UV auto-installation**: Automatic UV installation if not present on system
362
+ - **Build caching**: Advanced caching strategies for faster subsequent builds
363
+ - **Dependency analysis**: Detailed dependency tree analysis and reporting
@@ -0,0 +1,5 @@
1
+ """
2
+ Builds Python Lambda functions using UV dependency manager
3
+ """
4
+
5
+ from .workflow import PythonUvWorkflow
@@ -0,0 +1,76 @@
1
+ """
2
+ Action to resolve Python dependencies using UV
3
+ """
4
+
5
+ import logging
6
+ from typing import Optional
7
+
8
+ from aws_lambda_builders.actions import ActionFailedError, BaseAction, Purpose
9
+ from aws_lambda_builders.architecture import X86_64
10
+
11
+ from .exceptions import MissingUvError, UvBuildError, UvInstallationError
12
+ from .packager import PythonUvDependencyBuilder, SubprocessUv, UvRunner
13
+ from .utils import OSUtils, UvConfig
14
+
15
+ LOG = logging.getLogger(__name__)
16
+
17
+
18
+ class PythonUvBuildAction(BaseAction):
19
+ """Action for building Python dependencies using UV."""
20
+
21
+ NAME = "ResolveDependencies"
22
+ DESCRIPTION = "Installing dependencies using UV"
23
+ PURPOSE = Purpose.RESOLVE_DEPENDENCIES
24
+ LANGUAGE = "python"
25
+
26
+ def __init__(
27
+ self,
28
+ artifacts_dir,
29
+ scratch_dir,
30
+ manifest_path,
31
+ runtime,
32
+ dependencies_dir,
33
+ binaries,
34
+ architecture=X86_64,
35
+ config: Optional[UvConfig] = None,
36
+ ):
37
+ self.artifacts_dir = artifacts_dir
38
+ self.manifest_path = manifest_path
39
+ self.scratch_dir = scratch_dir
40
+ self.runtime = runtime
41
+ self.dependencies_dir = dependencies_dir
42
+ self.binaries = binaries
43
+ self.architecture = architecture
44
+ self.config = config or UvConfig()
45
+
46
+ self._os_utils = OSUtils()
47
+
48
+ def execute(self) -> None:
49
+ """Execute the build action for Python UV workflows."""
50
+ # Initialize UV components
51
+ uv_subprocess = SubprocessUv(osutils=self._os_utils)
52
+ uv_runner = UvRunner(uv_subprocess=uv_subprocess, osutils=self._os_utils)
53
+
54
+ # Create main package builder
55
+ package_builder = PythonUvDependencyBuilder(
56
+ osutils=self._os_utils,
57
+ runtime=self.runtime,
58
+ uv_runner=uv_runner,
59
+ )
60
+
61
+ try:
62
+ # Determine target directory
63
+ target_artifact_dir = self.artifacts_dir
64
+ if self.dependencies_dir:
65
+ target_artifact_dir = self.dependencies_dir
66
+
67
+ # Build dependencies
68
+ package_builder.build_dependencies(
69
+ artifacts_dir_path=target_artifact_dir,
70
+ scratch_dir_path=self.scratch_dir,
71
+ manifest_path=self.manifest_path,
72
+ architecture=self.architecture,
73
+ config=self.config,
74
+ )
75
+ except (MissingUvError, UvInstallationError, UvBuildError) as ex:
76
+ raise ActionFailedError(str(ex))
@@ -0,0 +1,31 @@
1
+ """
2
+ Python UV specific workflow exceptions.
3
+ """
4
+
5
+ from aws_lambda_builders.exceptions import LambdaBuilderError
6
+
7
+
8
+ class MissingUvError(LambdaBuilderError):
9
+ """Exception raised when UV executable is not found."""
10
+
11
+ MESSAGE = (
12
+ "uv executable not found in PATH. " "Please install uv: https://docs.astral.sh/uv/getting-started/installation/"
13
+ )
14
+
15
+
16
+ class UvInstallationError(LambdaBuilderError):
17
+ """Exception raised when UV installation or setup fails."""
18
+
19
+ MESSAGE = "Failed to install dependencies using uv: {reason}"
20
+
21
+
22
+ class UvBuildError(LambdaBuilderError):
23
+ """Exception raised when UV package build fails."""
24
+
25
+ MESSAGE = "UV package build failed: {reason}"
26
+
27
+
28
+ class LockFileError(LambdaBuilderError):
29
+ """Exception raised when lock file operations fail."""
30
+
31
+ MESSAGE = "Lock file operation failed: {reason}"