Serverless-python-requirements: Poetry path dependencies and dockerizePip: true

Created on 2 Oct 2020  ยท  7Comments  ยท  Source: UnitedIncome/serverless-python-requirements

Hi, I am having issue deploying a service with some poetry path dependencies and the option dockerizePip: true.

Here is my project structure:

โ”œโ”€โ”€ lambdas
โ”‚   โ”œโ”€โ”€ serverless.yaml
โ”‚   โ”œโ”€โ”€ handler.py
โ”‚   โ”œโ”€โ”€ pyproject.toml
โ”‚   โ””โ”€โ”€ ...
โ”œโ”€โ”€ project2  # Some other project using common, not using serverless at all
โ”‚   โ””โ”€โ”€ ...
โ””โ”€โ”€ common  # Common libraries
    โ””โ”€โ”€ utils
        โ”œโ”€โ”€ pyproject.toml
        โ””โ”€โ”€ utils
            โ”œโ”€โ”€ __init__.py
            โ””โ”€โ”€ ...

lambdas/pyproject.toml:

[tool.poetry]
name = "lambdas"
version = "0.1.0"
description = ""

[tool.poetry.dependencies]
python = "^3.8"
pandas = "^1.1.2"
utils = {path = "../common/utils"}

[build-system]
requires = ["poetry>=0.12"]
build-backend = "poetry.masonry.api"

Note the utils path dependency.

As my project depends on non pure-python libraries (numpy, which is a pandas dependency), I need to use the dockerizePip: true option.

Here is my serverless.yaml:

service: project-lambdas
provider:
  name: aws
  runtime: python3.8

functions:
  hello:
    description: Hello function
    handler: handler.hello

plugins:
  - serverless-python-requirements

custom:
  pythonRequirements:
    usePoetry: true
    dockerizePip: true

But as the dependency installation runs inside of a docker container that does not know about the common directory, it fails with this error:

  Error: STDOUT: 

  STDERR: ERROR: Invalid requirement: '../common/utils' (from line 1 of /var/task/requirements.txt)
  Hint: It looks like a path. File '../common/utils' does not exist.

I tried mounting the common directory inside of the container with dockerRunCmdExtraArgs: ['-v', '${env:PROJECT_ROOT_DIR}/common:/var/common'], but then I get the following error:

  STDERR: ERROR: Exception:
  Traceback (most recent call last):
    File "/var/lang/lib/python3.8/shutil.py", line 788, in move
      os.rename(src, real_dst)
  OSError: [Errno 18] Invalid cross-device link: '/tmp/pip-target-ifpetc_3/lib/python/pytz' -> '/var/task/pytz'

  During handling of the above exception, another exception occurred:

  Traceback (most recent call last):
    File "/var/lang/lib/python3.8/site-packages/pip/_internal/cli/base_command.py", line 216, in _main
      status = self.run(options, args)
    File "/var/lang/lib/python3.8/site-packages/pip/_internal/cli/req_command.py", line 182, in wrapper
      return func(self, options, args)
    File "/var/lang/lib/python3.8/site-packages/pip/_internal/commands/install.py", line 470, in run
      self._handle_target_dir(
    File "/var/lang/lib/python3.8/site-packages/pip/_internal/commands/install.py", line 527, in _handle_target_dir
      shutil.move(
    File "/var/lang/lib/python3.8/shutil.py", line 798, in move
      copytree(src, real_dst, copy_function=copy_function,
    File "/var/lang/lib/python3.8/shutil.py", line 554, in copytree
      return _copytree(entries=entries, src=src, dst=dst, symlinks=symlinks,
    File "/var/lang/lib/python3.8/shutil.py", line 510, in _copytree
      raise Error(errors)
  shutil.Error: [('/tmp/pip-target-ifpetc_3/lib/python/pytz/zoneinfo/America/Argentina/Ushuaia', '/var/task/pytz/zoneinfo/America/Argentina/Ushuaia', '[Errno 5] Input/output error')]

When I set dockerizePip to false, the deployement doesn't fail, but of course the lambda invokation does with the error Importing the numpy C-extensions failed.

Is there a way to make poetry path dependencies work with dockerizePip: true?

Thank you for your help

Most helpful comment

I turned off "Use gRPC FUSE for file sharing" and I think it fixed the problem for me.

image

All 7 comments

Having the same issue with local libs although I don't think it's related to poetry. Issue seems to be that the common lib is not mounted properly to the container.

Project structure:

โ”œโ”€โ”€ README.md
โ”œโ”€โ”€ services
    โ”œโ”€โ”€ common
        โ”œโ”€โ”€ poetry.lock
        โ”œโ”€โ”€ pyproject.toml
        โ”œโ”€โ”€ src
            โ”œโ”€โ”€ common
                โ”œโ”€โ”€ __init__.py
                โ”œโ”€โ”€ common.py
    โ”œโ”€โ”€ service1
        โ”œโ”€โ”€ pyproject.toml
        โ”œโ”€โ”€ handler.py
        โ”œโ”€โ”€ serverless.yml
    โ””โ”€โ”€ ...

services/service1/pyproject.toml

[tool.poetry]
name = "service1"
version = "0.1.0"
description = ""
authors = ["None"]

[tool.poetry.dependencies]
python = "^3.7"
common = { path = "../common/" }

[build-system]
requires = ["poetry>=0.12"]
build-backend = "poetry.masonry.api"

services/service1/serverless.yml

service: project

provider:
  name: aws
  runtime: python3.7

plugins:
  - serverless-python-requirements

custom:
  pythonRequirements:
    dockerizePip: true
    usePoetry: true

functions:
  project:
    handler: handler.main
    description: handler

Environment information

Your Environment Information ---------------------------
     Operating System:          darwin
     Node Version:              12.18.3
     Framework Version:         1.51.0
     Plugin Version:            1.3.11
     SDK Version:               2.3.2

services/service1/package.lock

{
  "name": "project",
  "description": "",
  "version": "0.1.0",
  "dependencies": {},
  "devDependencies": {
    "serverless-python-requirements": "^5.1.0"
  }
}

Then when running sls package or sls deploy the following error pops up:

Error --------------------------------------------------

  Error: STDOUT: 

  STDERR: ERROR: Invalid requirement: '../common' (from line 1 of /var/task/requirements.txt)
  Hint: It looks like a path. File '../common' does not exist.
  WARNING: You are using pip version 20.1.1; however, version 20.2.4 is available.
  You should consider upgrading via the '/var/lang/bin/python3.7 -m pip install --upgrade pip' command.

When I set dockerizePip: false all works fine, but then you run into the issue as described by @MarwanDebbiche

I'm getting the OSError: [Errno 18] Invalid cross-device link error as well. I have usePoetry: false in my serverless file. The problem seems to be intermittent for me.

I turned off "Use gRPC FUSE for file sharing" and I think it fixed the problem for me.

image

Can confirm that @john-feusi-neuro's fix worked for me, and I'm not using poetry

This trick was a lifesaver, thanks @john-feusi-neuro for finding this, it's been driving me bananas.

DiTo. Here the Tipp from @john-feusi-neuro helped!

Thank you @john-feusi-neuro ๐Ÿ’ฏ!
This fixed my issue which was only running a pip install within a Docker container.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

miketheman picture miketheman  ยท  3Comments

brettdh picture brettdh  ยท  5Comments

tmclaugh picture tmclaugh  ยท  4Comments

simplesteph picture simplesteph  ยท  5Comments

nknotts picture nknotts  ยท  5Comments