Source code for aws_lbd_art_builder_core.layer.package
# -*- coding: utf-8 -*-"""Lambda layer packaging — Step 2 of the layer workflow.This module provides two tool-agnostic functions that every downstream builderneeds after dependencies have been installed:1. :func:`move_to_dir_python` — relocate installed packages into the ``python/`` directory that AWS Lambda requires for layers.2. :func:`create_layer_zip_file` — compress that directory into a deployable ``layer.zip``.**Why a separate ``python/`` directory?**AWS Lambda layers are extracted into ``/opt``. For Python packages to beimportable, they must live under ``/opt/python`` so that Python's default``sys.path`` picks them up. The zip must therefore contain ``python/`` as itstop-level entry — not a bare set of packages and not an absolute path.**Why ``temp_cwd`` before zipping?**The ``zip`` command records paths relative to the current working directory.By ``cd``-ing into the artifacts directory first, the resulting zip entriesstart with ``python/…`` instead of the full host filesystem path."""importglobimportshutilimportsubprocessfrompathlibimportPathfrom..vendor.better_pathlibimporttemp_cwd
[docs]defmove_to_dir_python(dir_site_packages:Path,dir_python:Path,):""" Relocate installed packages into the Lambda layer's ``python/`` directory. **Why this is needed:** Different build tools place packages in different locations (e.g. ``.venv/lib/python3.x/site-packages/``). Lambda layers require all packages under a single ``python/`` directory so they appear on ``sys.path`` at runtime. This function bridges that gap by moving (not copying) the site-packages tree into the target. :param dir_site_packages: Path to the source site-packages directory :param dir_python: Path to the target ``python/`` directory :raises FileNotFoundError: If the source site-packages directory doesn't exist """ifdir_site_packages.exists():ifdir_site_packages!=dir_python:ifdir_python.exists():shutil.rmtree(dir_python)shutil.move(dir_site_packages,dir_python)# otherwise, dir_site_packages is the same as dir_python, do nothingelse:raiseFileNotFoundError(f"dir_site_packages {dir_site_packages} not found")
default_ignore_package_list=["boto3","botocore","s3transfer","urllib3","setuptools","pip","wheel","twine","_pytest","pytest",]"""Default packages to exclude from Lambda layer zip files.- **AWS Runtime Provided**: boto3, botocore, s3transfer, urllib3 are pre-installed in Lambda — bundling them wastes space and can cause version conflicts with the runtime.- **Build Tools**: setuptools, pip, wheel, twine are not needed at runtime.- **Development Tools**: pytest, _pytest are testing frameworks not needed in production."""
[docs]defcreate_layer_zip_file(dir_python:Path,path_layer_zip:Path,ignore_package_list:list[str]|None=None,verbose:bool=True,):""" Create optimized zip file for AWS Lambda layer deployment. Compresses the ``python/`` directory into a zip file with maximum compression (``-9``) and selective package exclusions. :param dir_python: Path to the ``python/`` directory containing layer packages :param path_layer_zip: Output path for the layer zip file :param ignore_package_list: Packages to exclude from the zip. If None, uses :data:`default_ignore_package_list`. :param verbose: If True, shows detailed zip creation progress """ifignore_package_listisNone:ignore_package_list=list(default_ignore_package_list)args=["zip",f"{path_layer_zip}","-r","-9",]ifverboseisFalse:args.append("-q")# cd into artifacts dir so zip entries start with "python/…"withtemp_cwd(dir_python.parent):args.extend(glob.glob("*"))ifignore_package_list:args.append("-x")forpackageinignore_package_list:args.append(f"python/{package}*")subprocess.run(args,check=True)