-
Notifications
You must be signed in to change notification settings - Fork 4k
/
Copy pathfunction.ts
119 lines (107 loc) · 4.03 KB
/
function.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import * as fs from 'fs';
import * as path from 'path';
import * as lambda from '@aws-cdk/aws-lambda';
import { AssetHashType } from '@aws-cdk/core';
import { bundle } from './bundling';
// keep this import separate from other imports to reduce chance for merge conflicts with v2-main
// eslint-disable-next-line no-duplicate-imports, import/order
import { Construct } from '@aws-cdk/core';
/**
* Properties for a PythonFunction
*/
export interface PythonFunctionProps extends lambda.FunctionOptions {
/**
* The path to the root directory of the function.
*/
readonly entry: string;
/**
* The path (relative to entry) to the index file containing the exported handler.
*
* @default index.py
*/
readonly index?: string;
/**
* The name of the exported handler in the index file.
*
* @default handler
*/
readonly handler?: string;
/**
* The runtime environment. Only runtimes of the Python family are
* supported.
*
* @default lambda.Runtime.PYTHON_3_7
*/
readonly runtime?: lambda.Runtime;
/**
* Determines how asset hash is calculated. Assets will get rebuild and
* uploaded only if their hash has changed.
*
* If asset hash is set to `SOURCE` (default), then only changes to the source
* directory will cause the asset to rebuild. This means, for example, that in
* order to pick up a new dependency version, a change must be made to the
* source tree. Ideally, this can be implemented by including a dependency
* lockfile in your source tree or using fixed dependencies.
*
* If the asset hash is set to `OUTPUT`, the hash is calculated after
* bundling. This means that any change in the output will cause the asset to
* be invalidated and uploaded. Bear in mind that `pip` adds timestamps to
* dependencies it installs, which implies that in this mode Python bundles
* will _always_ get rebuild and uploaded. Normally this is an anti-pattern
* since build
*
* @default AssetHashType.SOURCE By default, hash is calculated based on the
* contents of the source directory. This means that only updates to the
* source will cause the asset to rebuild.
*/
readonly assetHashType?: AssetHashType;
/**
* Specify a custom hash for this asset. If `assetHashType` is set it must
* be set to `AssetHashType.CUSTOM`. For consistency, this custom hash will
* be SHA256 hashed and encoded as hex. The resulting hash will be the asset
* hash.
*
* NOTE: the hash is used in order to identify a specific revision of the asset, and
* used for optimizing and caching deployment activities related to this asset such as
* packaging, uploading to Amazon S3, etc. If you chose to customize the hash, you will
* need to make sure it is updated every time the asset changes, or otherwise it is
* possible that some deployments will not be invalidated.
*
* @default - based on `assetHashType`
*/
readonly assetHash?: string;
}
/**
* A Python Lambda function
*/
export class PythonFunction extends lambda.Function {
constructor(scope: Construct, id: string, props: PythonFunctionProps) {
if (props.runtime && props.runtime.family !== lambda.RuntimeFamily.PYTHON) {
throw new Error('Only `PYTHON` runtimes are supported.');
}
if (props.index && !/\.py$/.test(props.index)) {
throw new Error('Only Python (.py) index files are supported.');
}
// Entry and defaults
const entry = path.resolve(props.entry);
const index = props.index ?? 'index.py';
const resolvedIndex = path.resolve(entry, index);
if (!fs.existsSync(resolvedIndex)) {
throw new Error(`Cannot find index file at ${resolvedIndex}`);
}
const handler = props.handler ?? 'handler';
const runtime = props.runtime ?? lambda.Runtime.PYTHON_3_7;
super(scope, id, {
...props,
runtime,
code: bundle({
runtime,
entry,
outputPathSuffix: '.',
assetHashType: props.assetHashType,
assetHash: props.assetHash,
}),
handler: `${index.slice(0, -3)}.${handler}`,
});
}
}