Без сервера - Numpy - Невозможно найти хороший формат пути привязки - PullRequest
0 голосов
/ 26 декабря 2018

Я бился над этим более недели, просматривал всевозможные проблемы и сообщения на форуме и не могу решить.Я пытаюсь упаковать numpy в функцию, индивидуально создавая требования (у меня есть несколько функций с несколькими требованиями, которые я хотел бы разделить).

Среда :
Windows 10 Home

Docker Toolbox для Windows :

Client:
Version:       18.03.0-ce
API version:   1.37
Go version:    go1.9.4
Git commit:    0520e24302


Built: Fri Mar 23 08:31:36 2018
 OS/Arch:       windows/amd64
 Experimental:  false
 Orchestrator:  swarm

Server: Docker Engine - Community
 Engine:
  Version:      18.09.0
  API version:  1.39 (minimum version 1.12)
  Go version:   go1.10.4
  Git commit:   4d60db4
  Built:        Wed Nov  7 00:52:55 2018
  OS/Arch:      linux/amd64
  Experimental: false

Без сервераВерсия :

serverless version 6.4.1
serverless-python-requirements version 6.4.1

Структура каталогов :

|-test
  |-env.yml
  |-serverless.yml
  |-Dockerfile
  |-functions
    |-f1
      |-index.py
      |-requirements.txt
      |-sub_function_1.py
      |-sub_function_2.py
    |-f2
      |-index.py
      |-requirements.txt
      |-sub_function_3.py
      |-sub_function_4.py

serverless.yml

service: test 
plugins:
  - serverless-python-requirements
custom:
  pythonRequirements:
    zip: true                  
    dockerFile: Dockerfile      
    dockerizePip: non-linux     
provider:
  name: aws
  runtime: python3.6
  stage: dev
  environment: ${file(./env.yml):${opt:stage, self:provider.stage}.env}
  region: ${file(./env.yml):${opt:stage, self:provider.stage}.aws.region}
  profile: ${file(./env.yml):${opt:stage, self:provider.stage}.aws.profile}
package:
  individually: true
functions:
  f1:
    handler:index.handler
    module:functions/f1
  f2:
    handler:index.handleer
    module:functions/f2

У меня есть файлы моего проекта в C: \ Serverless \ test.Я запускаю npm init, а затем npm i --save serverless-python-requirements, принимая все значения по умолчанию.Я получаю следующее на sls deploy -v.даже несмотря на то, что я добавил C: \ в Shared Folders на работающей виртуальной машине по умолчанию в VirtualBox, и выбрал режим автоматического монтирования и постоянный.

image

Если я закомментирую как dockerizePip, так иdockerFile Я получаю следующее, как и ожидалось, основываясь на здесь и других SO сообщениях:

 Serverless: Invoke invoke
{
    "errorMessage": "Unable to import module 'index'"
}

Если я закомментирую dockerfile, я получаю:

Serverless: Docker Image: lambci/lambda:build-python3.6

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

    error during connect: Get https://XXXXXX/v1.37/version: dial tcp
    XXXXXXXXXX: connectex: A connection attempt failed because the 
    connected party did not properly respond after a period of time, or
    established connection failed because connected host has failed to 
    respond.

    at dockerCommand (C:\Serverless\test\node_modules\serverless-python-requirements\lib\docker.js:20:11)
    at getBindPath (C:\Serverless\test\node_modules\serverless-python-requirements\lib\docker.js:100:3)

С Dockerfile

# AWS Lambda execution environment is based on Amazon Linux 1
FROM amazonlinux:1

# Install Python 3.6
RUN yum -y install python36 python36-pip

# Install your dependencies
RUN curl -s https://bootstrap.pypa.io/get-pip.py | python3
RUN yum -y install python3-devel mysql-devel gcc

# Set the same WORKDIR as default image
RUN mkdir /var/task
WORKDIR /var/task

.

Serverless: Building custom docker image from Dockerfile...
Serverless: Docker Image: sls-py-reqs-custom

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

  Unable to find good bind path format

     For debugging logs, run again after setting the "SLS_DEBUG=*" environment variable.

  Stack Trace --------------------------------------------

Error: Unable to find good bind path format
    at getBindPath (C:\Serverless\test\node_modules\serverless-python-requirements\lib\docker.js:142:9)
    at installRequirements (C:\Serverless\test\node_modules\serverless-python-requirements\lib\pip.js:152:7)
    at installRequirementsIfNeeded (C:\Serverless\test\node_modules\serverless-python-requirements\lib\pip.js:451:3)

Если я перенесу свой проект в C: \ Users \, я получу это вместо:

Serverless: Docker Image: sls-py-reqs-custom
Serverless: Trying bindPath /c/Users/Serverless/test/.serverless/requirements (run,--rm,-v,/c/Users/Serverless/test/.serverless/req
uirements:/test,alpine,ls,/test/requirements.txt)
Serverless: /test/requirements.txt

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

  docker: Error response from daemon: create "/c/Users/Serverless/test/.serverless/requirements": "\"/c/Users/Serverless/test/.serv
erless/requirements\"" includes invalid characters for a local volume name, only "[a-zA-Z0-9][a-zA-Z0-9_.-]" are allowed. If you in
tended to pass a host directory, use absolute path.
See 'docker run --help'.


     For debugging logs, run again after setting the "SLS_DEBUG=*" environment variable.

  Stack Trace --------------------------------------------

Error: docker: Error response from daemon: create "/c/Users/Serverless/test/.serverless/requirements": "\"/c/Users/Serverless/test/
.serverless/requirements\"" includes invalid characters for a local volume name, only "[a-zA-Z0-9][a-zA-Z0-9_.-]" are allowed. If y
ou intended to pass a host directory, use absolute path.
See 'docker run --help'.

    at dockerCommand (C:\Users\Serverless\test\node_modules\serverless-python-requirements\lib\docker.js:20:11)
    at getDockerUid (C:\Users\Serverless\test\node_modules\serverless-python-requirements\lib\docker.js:162:14)

Я видел рекомендации по стилю Makefile от @brianz здесь , но я не уверен, как приспособить это к этому (Makefiles не моя сильная сторона).Я немного в растерянности относительно того, что делать дальше, и советы будут с благодарностью.ТИА.

Ответы [ 2 ]

0 голосов
/ 07 марта 2019

когда у меня возникла та же проблема, я открыл докер, зашел в настройки / общий диск, выбрал сброс учетных данных и после применения моих изменений, и это очистило ошибку

0 голосов
/ 03 января 2019

Мне не удалось заставить плагин работать, но я все равно нашел лучшее решение - Lambda Layers.Это бонус, потому что он уменьшает размер лямбды и позволяет повторно использовать код / ​​файл.Существует предустановленный лямбда-слой для numpy и scipy, который вы можете использовать, но я создал свой собственный, чтобы показать себе, как все это работает.Вот как я это сделал:

Создайте пакет слоя:

  1. Откройте экземпляр EC2, Ubuntu, Linux или любой другой - это необходимо, чтобы мы могли правильно скомпилировать исполняемые файлы
  2. Создайте zip-пакет пакета зависимостей - необходимо использовать структуру каталогов python/lib/python3.6/site-packages для поиска Python во время выполнения

    mkdir -p tmpdir/python/lib/python3.6/site-packages 
    pip install -r requirements.txt --no-deps -t tmpdir/python/lib/python3.6/site-packages 
    cd tmpdir zip -r ../py_dependencies.zip . 
    cd .. 
    rm -r tmpdir
    
  3. Передача zip-слоя в AWS - требуетсяпоследний awscli

    sudo pip install awscli --upgrade --user
    sudo aws lambda publish-layer-version \
    --layer-name py_dependencies \
    --description "Python 3.6 dependencies [numpy=0.15.4]" \
    --license-info "MIT" \
    --compatible-runtimes python3.6 \
    --zip-file fileb://py_dependencies.zip \
    --profile python_dev_serverless
    
  4. Чтобы использовать в любой функции, которая требует numpy, просто используйте arn, который показан в консоли или во время загрузки выше

    f1:
      handler: index.handler_f_use_numpy
      include:
        - functions/f_use_numpy.py
      layers:
        - arn:aws:lambda:us-west-2:XXXXX:layer:py_dependencies:1
    
  5. В качестве дополнительного бонуса вы также можете помещать в слой обычные файлы, такие как константыВот как я это сделал для тестирования использования в windows и на лямбде:

    import platform
    
    \# Set common path
    COMMON_PATH = "../../layers/common/"
    if platform.system() == "Linux": COMMON_PATH = "/opt/common/"
    
    def handler_common(event, context):
        # Read from a constants.json file
        with open(COMMON_PATH + 'constants.json') as f:
            return text = json.load(f)
    
...