Skip to content

Commit 8dc36e8

Browse files
rivharantonbabenko
andauthored
feat: Add uv support for python packaging (#723)
Co-authored-by: Anton Babenko <[email protected]> Co-authored-by: Anton Babenko <[email protected]>
1 parent f71e78a commit 8dc36e8

File tree

10 files changed

+747
-5
lines changed

10 files changed

+747
-5
lines changed

examples/build-package/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ Configuration in this directory creates deployment packages in a variety of comb
55
This example demonstrates various packaging scenarios including:
66
- Python packages with pip requirements
77
- Poetry-based Python packages
8+
- UV-based Python packages
89
- Node.js packages with npm
910
- Docker-based builds
1011
- Quiet packaging - suppressing Poetry/pip/npm output during builds using `quiet_archive_local_exec = true`
@@ -46,12 +47,16 @@ Note that this example may create resources which cost money. Run `terraform des
4647
| <a name="module_lambda_layer"></a> [lambda\_layer](#module\_lambda\_layer) | ../../ | n/a |
4748
| <a name="module_lambda_layer_pip_requirements"></a> [lambda\_layer\_pip\_requirements](#module\_lambda\_layer\_pip\_requirements) | ../.. | n/a |
4849
| <a name="module_lambda_layer_poetry"></a> [lambda\_layer\_poetry](#module\_lambda\_layer\_poetry) | ../../ | n/a |
50+
| <a name="module_lambda_layer_uv"></a> [lambda\_layer\_uv](#module\_lambda\_layer\_uv) | ../../ | n/a |
4951
| <a name="module_npm_package_with_commands_and_patterns"></a> [npm\_package\_with\_commands\_and\_patterns](#module\_npm\_package\_with\_commands\_and\_patterns) | ../../ | n/a |
5052
| <a name="module_package_dir"></a> [package\_dir](#module\_package\_dir) | ../../ | n/a |
5153
| <a name="module_package_dir_pip_dir"></a> [package\_dir\_pip\_dir](#module\_package\_dir\_pip\_dir) | ../../ | n/a |
5254
| <a name="module_package_dir_poetry"></a> [package\_dir\_poetry](#module\_package\_dir\_poetry) | ../../ | n/a |
5355
| <a name="module_package_dir_poetry_no_docker"></a> [package\_dir\_poetry\_no\_docker](#module\_package\_dir\_poetry\_no\_docker) | ../../ | n/a |
5456
| <a name="module_package_dir_poetry_quiet"></a> [package\_dir\_poetry\_quiet](#module\_package\_dir\_poetry\_quiet) | ../../ | n/a |
57+
| <a name="module_package_dir_uv"></a> [package\_dir\_uv](#module\_package\_dir\_uv) | ../../ | n/a |
58+
| <a name="module_package_dir_uv_no_docker"></a> [package\_dir\_uv\_no\_docker](#module\_package\_dir\_uv\_no\_docker) | ../../ | n/a |
59+
| <a name="module_package_dir_uv_no_lock"></a> [package\_dir\_uv\_no\_lock](#module\_package\_dir\_uv\_no\_lock) | ../../ | n/a |
5560
| <a name="module_package_dir_with_npm_install"></a> [package\_dir\_with\_npm\_install](#module\_package\_dir\_with\_npm\_install) | ../../ | n/a |
5661
| <a name="module_package_dir_with_npm_install_lock_file"></a> [package\_dir\_with\_npm\_install\_lock\_file](#module\_package\_dir\_with\_npm\_install\_lock\_file) | ../../ | n/a |
5762
| <a name="module_package_dir_without_npm_install"></a> [package\_dir\_without\_npm\_install](#module\_package\_dir\_without\_npm\_install) | ../../ | n/a |

examples/build-package/main.tf

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,84 @@ module "package_dir_poetry_quiet" {
137137
quiet_archive_local_exec = true # Suppress Poetry/pip output during packaging
138138
}
139139

140+
# Create zip-archive of a single directory where "uv export" & "pip install" will be executed
141+
module "package_dir_uv_no_lock" {
142+
source = "../../"
143+
144+
create_function = false
145+
runtime = "python3.12"
146+
147+
source_path = [
148+
{
149+
path = "${path.module}/../fixtures/python-app-uv-no-lock"
150+
uv_install = true
151+
}
152+
]
153+
154+
artifacts_dir = "${path.root}/builds/package_dir_uv_no_lock/"
155+
}
156+
157+
# Create zip-archive of a single directory where "uv export" & "pip install" will be executed (using docker)
158+
module "package_dir_uv" {
159+
source = "../../"
160+
161+
create_function = false
162+
163+
build_in_docker = true
164+
runtime = "python3.12"
165+
docker_image = "build-python-uv"
166+
docker_file = "${path.module}/../fixtures/python-app-uv/docker/Dockerfile"
167+
168+
source_path = [
169+
{
170+
path = "${path.module}/../fixtures/python-app-uv"
171+
uv_install = true
172+
}
173+
]
174+
artifacts_dir = "${path.root}/builds/package_dir_uv/"
175+
}
176+
177+
# Create zip-archive of a single directory where "uv export" & "pip install" will be executed (not using docker)
178+
module "package_dir_uv_no_docker" {
179+
source = "../../"
180+
181+
create_function = false
182+
183+
runtime = "python3.12"
184+
185+
source_path = [
186+
{
187+
path = "${path.module}/../fixtures/python-app-uv"
188+
uv_install = true
189+
}
190+
]
191+
artifacts_dir = "${path.root}/builds/package_dir_uv_no_docker/"
192+
}
193+
194+
# Create a Lambda Layer using uv for dependency management (using docker)
195+
module "lambda_layer_uv" {
196+
source = "../../"
197+
198+
create_layer = true
199+
layer_name = "${random_pet.this.id}-layer-uv"
200+
compatible_runtimes = ["python3.12"]
201+
runtime = "python3.12"
202+
203+
build_in_docker = true
204+
docker_image = "build-python-uv"
205+
docker_file = "${path.module}/../fixtures/python-app-uv/docker/Dockerfile"
206+
207+
source_path = [
208+
{
209+
path = "${path.module}/../fixtures/python-app-uv"
210+
uv_install = true
211+
prefix_in_zip = "python"
212+
}
213+
]
214+
hash_extra = "uv-extra-hash-to-prevent-conflicts-with-module.package_dir"
215+
artifacts_dir = "${path.root}/builds/lambda_layer_uv/"
216+
}
217+
140218
# Create zip-archive of a single directory without running "pip install" (which is default for python runtime)
141219
module "package_dir_without_pip_install" {
142220
source = "../../"
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[project]
2+
name = "uv_lambda"
3+
version = "0.1.0"
4+
description = "Fixture project to test uv without uv.lock"
5+
requires-python = ">=3.12"
6+
7+
dependencies = [
8+
"requests>=2.31.0"
9+
]
10+
11+
[tool.uv]
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
def lambda_handler(event, context):
2+
return {"statusCode": 200, "body": "Hello from uv (no lock)!"}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
FROM public.ecr.aws/sam/build-python3.12
2+
3+
LABEL description="AWS Lambda build container with uv"
4+
5+
RUN pip install uv==0.9.21
6+
7+
WORKDIR /var/task
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
[project]
2+
name = "uv_lambda"
3+
version = "0.1.0"
4+
requires-python = ">=3.12"
5+
dependencies = [
6+
"requests==2.31.0",
7+
]
8+
9+
[tool.uv]
10+
# This marker is for our Terraform parser to detect UV
11+
12+
[build-system]
13+
requires = ["hatchling"]
14+
build-backend = "hatchling.build"
15+
16+
[tool.hatch.build.targets.wheel]
17+
packages = ["uv_lambda"]
18+
include = ["uv_lambda/*"]

0 commit comments

Comments
 (0)