Skip to content

Commit

Permalink
feat(aws-lambda-python-alpha): Cache python lambda dependencies using…
Browse files Browse the repository at this point in the history
… lambda layer
  • Loading branch information
orshemtov committed May 11, 2024
1 parent 3928eae commit c647690
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 8 deletions.
22 changes: 17 additions & 5 deletions packages/@aws-cdk/aws-lambda-python-alpha/lib/bundling.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@ export interface BundlingProps extends BundlingOptions {
* @default - BundlingFileAccess.BIND_MOUNT
*/
bundlingFileAccess?: BundlingFileAccess;

/**
* Whether or not to install the dependencies
* @default true
*/
readonly installDependencies?: boolean;
}

/**
Expand All @@ -73,6 +79,7 @@ export class Bundling implements CdkBundlingOptions {
public readonly securityOpt?: string;
public readonly network?: string;
public readonly bundlingFileAccess?: BundlingFileAccess;
public readonly installDependencies?: boolean;

constructor(props: BundlingProps) {
const {
Expand All @@ -85,6 +92,7 @@ export class Bundling implements CdkBundlingOptions {
poetryWithoutUrls,
commandHooks,
assetExcludes = [],
installDependencies = true,
} = props;

const outputPath = path.posix.join(AssetStaging.BUNDLING_OUTPUT_DIR, outputPathSuffix);
Expand All @@ -97,6 +105,7 @@ export class Bundling implements CdkBundlingOptions {
poetryWithoutUrls,
commandHooks,
assetExcludes,
installDependencies,
});

this.image = image ?? DockerImage.fromBuild(path.join(__dirname, '..', 'lib'), {
Expand All @@ -119,17 +128,19 @@ export class Bundling implements CdkBundlingOptions {
}

private createBundlingCommand(options: BundlingCommandOptions): string[] {
const packaging = Packaging.fromEntry(options.entry, options.poetryIncludeHashes, options.poetryWithoutUrls);
let bundlingCommands: string[] = [];
bundlingCommands.push(...options.commandHooks?.beforeBundling(options.inputDir, options.outputDir) ?? []);
const exclusionStr = options.assetExcludes?.map(item => `--exclude='${item}'`).join(' ');
bundlingCommands.push([
'rsync', '-rLv', exclusionStr ?? '', `${options.inputDir}/`, options.outputDir,
].filter(item => item).join(' '));
bundlingCommands.push(`cd ${options.outputDir}`);
bundlingCommands.push(packaging.exportCommand ?? '');
if (packaging.dependenciesFile) {
bundlingCommands.push(`python -m pip install -r ${DependenciesFile.PIP} -t ${options.outputDir}`);
if (options.installDependencies) {
const packaging = Packaging.fromEntry(options.entry, options.poetryIncludeHashes, options.poetryWithoutUrls);
bundlingCommands.push(`cd ${options.outputDir}`);
bundlingCommands.push(packaging.exportCommand ?? '');
if (packaging.dependenciesFile) {
bundlingCommands.push(`python -m pip install -r ${DependenciesFile.PIP} -t ${options.outputDir}`);
}
}
bundlingCommands.push(...options.commandHooks?.afterBundling(options.inputDir, options.outputDir) ?? []);
return bundlingCommands;
Expand All @@ -144,6 +155,7 @@ interface BundlingCommandOptions {
readonly poetryIncludeHashes?: boolean;
readonly poetryWithoutUrls?: boolean;
readonly commandHooks?: ICommandHooks;
readonly installDependencies: boolean;
}

/**
Expand Down
35 changes: 32 additions & 3 deletions packages/@aws-cdk/aws-lambda-python-alpha/lib/function.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import * as fs from 'fs';
import * as path from 'path';
import { Function, FunctionOptions, Runtime, RuntimeFamily } from 'aws-cdk-lib/aws-lambda';
import { Stack } from 'aws-cdk-lib/core';
import { Architecture, Function, FunctionOptions, Runtime, RuntimeFamily } from 'aws-cdk-lib/aws-lambda';
import { AssetHashType, Stack } from 'aws-cdk-lib/core';
import { Construct } from 'constructs';
import { Bundling } from './bundling';
import { BundlingOptions } from './types';
import { PythonLayerVersion } from './layer';

/**
* Properties for a PythonFunction
Expand Down Expand Up @@ -42,6 +43,11 @@ export interface PythonFunctionProps extends FunctionOptions {
* @default - Use the default bundling Docker image, with x86_64 architecture.
*/
readonly bundling?: BundlingOptions;

/**
* Whether or not to create a layer for the function's dependencies.
*/
readonly layer?: boolean;
}

/**
Expand All @@ -60,13 +66,31 @@ export class PythonFunction extends Function {
if (!fs.existsSync(resolvedIndex)) {
throw new Error(`Cannot find index file at ${resolvedIndex}`);
}

const resolvedHandler =`${index.slice(0, -3)}.${handler}`.replace(/\//g, '.');

if (props.runtime && props.runtime.family !== RuntimeFamily.PYTHON) {
throw new Error('Only `PYTHON` runtimes are supported.');
}

// Layer
let layer: PythonLayerVersion | undefined;
if (props.layer) {
layer = new PythonLayerVersion(scope, `${id}Layer`, {
entry,
compatibleRuntimes: [props.runtime],
compatibleArchitectures: [props.architecture ?? Architecture.X86_64],
bundling: {
...props.bundling,
installDependencies: true,
// TODO: Make sure the layer is updated only when the dependencies change
// assetExcludes: ["TODO: exclude everything except the dependencies file"]
// assetHashType: AssetHashType.CUSTOM,
// assetHash: "TODO: hash of the dependencies file"
},
});
}

super(scope, id, {
...props,
runtime,
Expand All @@ -77,8 +101,13 @@ export class PythonFunction extends Function {
// define architecture based on the target architecture of the function, possibly overriden in bundling options
architecture: props.architecture,
...props.bundling,
installDependencies: layer ? false : true,
}),
handler: resolvedHandler,
layers: layer ? [
...(props.layers ?? []),
layer,
] : props.layers,
});
}
}
6 changes: 6 additions & 0 deletions packages/@aws-cdk/aws-lambda-python-alpha/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,12 @@ export interface BundlingOptions extends DockerRunOptions {
* @default - BundlingFileAccess.BIND_MOUNT
*/
readonly bundlingFileAccess?: BundlingFileAccess;

/**
* Whether or not to install the dependencies
* @default true
*/
readonly installDependencies?: boolean;
}

/**
Expand Down

0 comments on commit c647690

Please sign in to comment.