serverless-python-requirements
serverless-python-requirements copied to clipboard
Mixing nodejs and python results in "ENOENT: no such file or directory, scandir '.serverless/requirement"
I'm having lambda's of both the python and nodejs runtime. When building the dist, it results in the following error:
Serverless: Zipping required Python packages for ....
Serverless: Zipping required Python packages for src/func2...
Exception -----------------------------------------------
[OperationalError: ENOENT: no such file or directory, scandir '.serverless/requirements'] {
cause: [Error: ENOENT: no such file or directory, scandir '.serverless/requirements'] {
errno: -2,
code: 'ENOENT',
syscall: 'scandir',
path: '.serverless/requirements'
},
isOperational: true,
errno: -2,
code: 'ENOENT',
syscall: 'scandir',
path: '.serverless/requirements'
}
Get Support --------------------------------------------
Docs: docs.serverless.com
Bugs: github.com/serverless/serverless/issues
Issues: forum.serverless.com
Your Environment Information ---------------------------
Operating System: darwin
Node Version: 17.4.0
Framework Version: 2.72.3 (local)
Plugin Version: 5.5.4
SDK Version: 4.3.2
Components Version: 3.18.2
My serverless.yml contains:
plugins:
- serverless-python-requirements
package:
individually: true
custom:
pythonRequirements:
zip: true
slim: true
dockerizePip: non-linux
usePoetry: false # <- can't be true with package:individually:true
cacheLocation: ./.serverless-python-requirements-cache
provider:
name: aws
runtime: python3.8
functions:
func1:
handler: func1/index.main
runtime: nodejs12.x
func2:
handler: handler.handle
module: src/func2
My filetree structure is:
serverless.yml
package.json
yarn.lock
src
- func1
- index.js
- func2
- pyproject.tom
- poetry.lock
- handler
- __init__.py
I see a unzip_requirements.py being created in the project root
A quick check in the sourcecode at https://github.com/serverless/serverless-python-requirements/blob/3a898e5e707658c76f6063f44938366935b41812/lib/zip.js#L116 shows that it uses this.targetFuncs to determine for which functions to create a zip.
However, the inject.js filters the this.targetFuncs on the python runtime at https://github.com/serverless/serverless-python-requirements/blob/3a898e5e707658c76f6063f44938366935b41812/lib/inject.js#L109 .
Shouldn't all occurrences of this.targetFuncs be replaced with one that filters on the runtime?
update 1:
Note that if I add a module to the js function, the mentioned scandir in the exception changes.
For example:
functions:
func1:
handler: func1/index.main
runtime: nodejs12.x
module: src/func1
results in scandir '.serverless/src/func1/requirements'
update 2:
As the module is used as the root dir, and requirements are only packed for functions with a python runtime, I can make sls dist succeed by assigning the python module dir to the nodejs function:
functions:
func1:
handler: func1/index.main
runtime: nodejs12.x
module: src/func2
A possible workaround is to create an empty lambda:
#serverless.yml
functions:
empty_python:
handler: handler.handle
description: "Empty project to trick python-requirements into preparing requirements."
module: src/empty_python
func1:
handler: func1/index.main
runtime: nodejs12.x
module: src/empty_python
package:
patterns:
- "src/func1/**"
func2:
handler: handler.handle
module: src/func2
package:
patterns:
- "src/func2/handler/**"
- "src/func2/*.py
where src/empty_python only contains an empty requirements.txt.
Because it is specified first, it's requirements (which there are none) will be saved, and then reused by the nodejs functions. Not pretty, but at least it works for now.
Are you sure this doesn't still happen without node? I'm using just a single python function, and this happens as soon as I add zip: true (or layer: true which implicitly zips).