Skip to content

Commit

Permalink
Add support for additional Python Lambda handler filenames
Browse files Browse the repository at this point in the history
  • Loading branch information
ryanblock committed Aug 3, 2023
1 parent 69e4c1b commit 2086104
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 4 deletions.
9 changes: 9 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@

---

## [3.6.0] 2023-08-02

### Added

- Added support for additional Python Lambda handler filenames, including `lambda.py`, `handler.py`, and `__main__.py`
- Architect's legacy `index.py` root filename remains

---

## [3.5.7] 2023-07-09

### Changed
Expand Down
6 changes: 5 additions & 1 deletion src/config/pragmas/populate-lambda/get-handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ let nodeHandlers = [ 'index.js', 'index.mjs', 'index.cjs' ]
let denoHandlers = [ 'mod.ts', 'mod.js' ]
// TODO: these are all prob going away
.concat([ 'mod.tsx', 'index.ts', 'index.js', 'index.tsx' ])
let snekHandlers = [ 'lambda.py', 'handler.py', '__main__.py', 'index.py' ]

function getExt ({ runtime, src, errors }) {
try {
Expand Down Expand Up @@ -71,7 +72,10 @@ function getExt ({ runtime, src, errors }) {
}
return { file, ext, handlerModuleSystem }
}
if (runtime.startsWith('python')) return { ext: 'py' }
if (runtime.startsWith('python')) {
let { file = 'lambda', ext = 'py' } = findHandler(snekHandlers, src)
return { file, ext }
}
if (runtime.startsWith('ruby')) return { ext: 'rb' }
if (runtime.startsWith('deno')) {
let { file = 'mod', ext = 'ts' } = findHandler(denoHandlers, src)
Expand Down
55 changes: 52 additions & 3 deletions test/unit/src/config/pragmas/populate-lambda/get-handler-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ test('Set up env', t => {
})

test('Handler properties (built-in runtimes)', t => {
t.plan(20)
let config, errors, result
t.plan(32)
let config, errors, pythonHandler, result

// Defaults to Node.js
config = defaultFunctionConfig()
Expand All @@ -50,11 +50,60 @@ test('Handler properties (built-in runtimes)', t => {
// Python
config = defaultFunctionConfig()
errors = []
pythonHandler = 'lambda.py'
config.runtime = 'python3.8'
result = getHandler({ config, src, errors })
t.notOk(errors.length, 'Did not get handler errors')
t.equal(result.handlerFile, srcPath(pythonHandler), `Got correct handlerFile: ${result.handlerFile}`)
t.equal(result.handlerMethod, handler, `Got correct handlerMethod: ${result.handlerMethod}`)

// Verify priority of the updated default handler name
config = defaultFunctionConfig()
errors = []
mockFs({ [src]: {
[pythonHandler]: 'hi',
'index.py': 'hi',
} })
config.runtime = 'python3.8'
result = getHandler({ config, src, errors })
t.notOk(errors.length, 'Did not get handler errors')
t.equal(result.handlerFile, srcPath(pythonHandler), `Got correct handlerFile: ${result.handlerFile}`)
t.equal(result.handlerMethod, handler, `Got correct handlerMethod: ${result.handlerMethod}`)
mockFs.restore()

config = defaultFunctionConfig()
errors = []
pythonHandler = 'handler.py'
mockFs(fakeFile(pythonHandler))
config.runtime = 'python3.8'
result = getHandler({ config, src, errors })
t.notOk(errors.length, 'Did not get handler errors')
t.equal(result.handlerFile, srcPath(`${file}.py`), `Got correct handlerFile: ${result.handlerFile}`)
t.equal(result.handlerFile, srcPath(pythonHandler), `Got correct handlerFile: ${result.handlerFile}`)
t.equal(result.handlerMethod, handler, `Got correct handlerMethod: ${result.handlerMethod}`)
mockFs.restore()

config = defaultFunctionConfig()
errors = []
pythonHandler = '__main__.py'
mockFs(fakeFile(pythonHandler))
config.runtime = 'python3.8'
result = getHandler({ config, src, errors })
t.notOk(errors.length, 'Did not get handler errors')
t.equal(result.handlerFile, srcPath(pythonHandler), `Got correct handlerFile: ${result.handlerFile}`)
t.equal(result.handlerMethod, handler, `Got correct handlerMethod: ${result.handlerMethod}`)
mockFs.restore()

// Old school Architect default
config = defaultFunctionConfig()
errors = []
pythonHandler = 'index.py'
mockFs(fakeFile(pythonHandler))
config.runtime = 'python3.8'
result = getHandler({ config, src, errors })
t.notOk(errors.length, 'Did not get handler errors')
t.equal(result.handlerFile, srcPath(pythonHandler), `Got correct handlerFile: ${result.handlerFile}`)
t.equal(result.handlerMethod, handler, `Got correct handlerMethod: ${result.handlerMethod}`)
mockFs.restore()

// Ruby
config = defaultFunctionConfig()
Expand Down

0 comments on commit 2086104

Please sign in to comment.