Skip to content

Commit 8d6009d

Browse files
author
adi-avadhanam
committed
feat: add multi-platform ARM64 support for dependency packaging
- Support multiple manylinux platforms: aarch64-manylinux2014, aarch64-manylinux_2_17, aarch64-manylinux_2_28 - Try platforms in order of preference for better wheel compatibility - Fallback to next platform if current one fails to find compatible wheels
1 parent 65e7ff2 commit 8d6009d

File tree

2 files changed

+42
-19
lines changed

2 files changed

+42
-19
lines changed

src/bedrock_agentcore_starter_toolkit/utils/runtime/package.py

Lines changed: 37 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -350,23 +350,47 @@ def _install_dependencies(
350350
# Input: "PYTHON_3_10" or "python3.10" → Output: "3.10"
351351
python_version = runtime_version.upper().replace("PYTHON", "").replace("_", ".").strip("_. ")
352352

353-
cmd = self._build_uv_command(requirements_file, target_dir, python_version, cross_compile)
354-
log.info("Installing dependencies with uv%s...", " (cross-compiling for Linux ARM64)" if cross_compile else "")
355-
356-
try:
357-
subprocess.run(cmd, check=True, capture_output=True, text=True) # nosec B603 - using uv command
358-
log.info("✓ Dependencies installed with uv")
359-
except subprocess.CalledProcessError as e:
360-
raise RuntimeError(f"Failed to install dependencies with uv: {e.stderr}") from e
353+
if cross_compile:
354+
# Try multiple platforms in order of preference for better compatibility
355+
platforms = ["aarch64-manylinux2014", "aarch64-manylinux_2_17", "aarch64-manylinux_2_28"]
356+
357+
for i, platform in enumerate(platforms):
358+
cmd = self._build_uv_command(requirements_file, target_dir, python_version, platform)
359+
log.info(
360+
"Installing dependencies with uv for %s%s...",
361+
platform,
362+
" (cross-compiling for Linux ARM64)" if i == 0 else "",
363+
)
361364

362-
def _build_uv_command(self, requirements: Path, target: Path, py_version: str, cross: bool) -> List[str]:
365+
try:
366+
subprocess.run(cmd, check=True, capture_output=True, text=True) # nosec B603 - using uv command
367+
if i == 0:
368+
log.info("✓ Dependencies installed with uv")
369+
except subprocess.CalledProcessError as e:
370+
if i == len(platforms) - 1: # Last platform failed
371+
raise RuntimeError(f"Failed to install dependencies with uv: {e.stderr}") from e
372+
# Try next platform
373+
continue
374+
else:
375+
cmd = self._build_uv_command(requirements_file, target_dir, python_version, None)
376+
log.info("Installing dependencies with uv...")
377+
378+
try:
379+
subprocess.run(cmd, check=True, capture_output=True, text=True) # nosec B603 - using uv command
380+
log.info("✓ Dependencies installed with uv")
381+
except subprocess.CalledProcessError as e:
382+
raise RuntimeError(f"Failed to install dependencies with uv: {e.stderr}") from e
383+
384+
def _build_uv_command(
385+
self, requirements: Path, target: Path, py_version: str, platform: Optional[str]
386+
) -> List[str]:
363387
"""Build uv pip install command.
364388
365389
Args:
366390
requirements: Path to requirements.txt
367391
target: Target directory
368392
py_version: Python version (e.g., "3.10")
369-
cross: Whether to cross-compile
393+
platform: Platform string (e.g., "aarch64-manylinux2014") or None for native
370394
371395
Returns:
372396
Command as list of strings
@@ -381,13 +405,12 @@ def _build_uv_command(self, requirements: Path, target: Path, py_version: str, c
381405
py_version,
382406
]
383407

384-
# Always use aarch64-manylinux2014 for AgentCore Runtime (ARM64)
385-
# Note: uv uses --python-platform (not --platform like pip)
386-
if cross:
408+
# Add platform-specific options for cross-compilation
409+
if platform:
387410
cmd.extend(
388411
[
389412
"--python-platform",
390-
"aarch64-manylinux2014",
413+
platform,
391414
"--only-binary",
392415
":all:",
393416
]

tests/utils/runtime/test_package.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ def test_build_uv_command(self, tmp_path):
292292
target = tmp_path / "target"
293293

294294
packager = CodeZipPackager()
295-
cmd = packager._build_uv_command(reqs, target, "3.10", cross=False)
295+
cmd = packager._build_uv_command(reqs, target, "3.10", None)
296296

297297
assert "uv" in cmd
298298
assert "--python-version" in cmd
@@ -306,7 +306,7 @@ def test_build_uv_command_with_cross_compile(self, tmp_path):
306306
target = tmp_path / "target"
307307

308308
packager = CodeZipPackager()
309-
cmd = packager._build_uv_command(reqs, target, "3.10", cross=True)
309+
cmd = packager._build_uv_command(reqs, target, "3.10", "aarch64-manylinux2014")
310310

311311
assert "--python-platform" in cmd
312312
assert "aarch64-manylinux2014" in cmd
@@ -498,15 +498,15 @@ def test_runtime_version_normalization(self, tmp_path):
498498

499499
# Note: Normalization happens in _install_dependencies before calling _build_uv_command
500500
# This method receives already-normalized versions (e.g., "3.10")
501-
cmd1 = packager._build_uv_command(reqs, target, "3.10", cross=False)
501+
cmd1 = packager._build_uv_command(reqs, target, "3.10", None)
502502
assert "--python-version" in cmd1
503503
assert "3.10" in cmd1
504504

505-
cmd2 = packager._build_uv_command(reqs, target, "3.11", cross=False)
505+
cmd2 = packager._build_uv_command(reqs, target, "3.11", None)
506506
assert "--python-version" in cmd2
507507
assert "3.11" in cmd2
508508

509-
cmd3 = packager._build_uv_command(reqs, target, "3.12", cross=True)
509+
cmd3 = packager._build_uv_command(reqs, target, "3.12", "aarch64-manylinux2014")
510510
assert "--python-version" in cmd3
511511
assert "3.12" in cmd3
512512
assert "--python-platform" in cmd3

0 commit comments

Comments
 (0)