AWS Lambda Python: .so модуль: ModuleNotFoundError: Нет модуля с именем 'regex._regex' в подоболочке - PullRequest
3 голосов
/ 04 ноября 2019

Я пытаюсь запустить некоторые из моих простых заданий CI (например, линтеры) в лямбда-функции для моих репозиториев Python.

Я использую для этого gitlab-ci и базовую архитектуру (ненепосредственно связана с проблемой, но это может помочь при выборе):

задания CI определяются как набор команд оболочки, в моем случае просто выполняющихся black --check . (подстилка Python): 1. Команды оболочки отправляются в мою лямбду 2. лямбда-мерзавец клонирует репозиторий 3. лямбда выполняет в подпроцессе команды 4. результат возвращается

, поэтому моя лямбда выглядит так:

import os
import stat
import sys
import json
import subprocess
import stat
import shutil

from git import Repo


def main(event, lambda_context):
    # I've commented out, so that if you like trying to reproduce it
    # at home, you don't need the additional dependencies :) 
    #Repo.clone_from("https://example.com/the/repo.git")

    # the command sent by the CI having a shebang in it
    # the quick and dirty solution we found is to write it into 
    # a shell script and then executing said script
    script = open("/tmp/script.sh", "w")
    script.write(event["command"])
    script.close()

    st = os.stat("/tmp/script.sh")
    os.chmod("/tmp/script.sh", st.st_mode | stat.S_IEXEC)

    # the copy is just to be extra-safe
    copy_env_variables = os.environ.copy()
    # for all the binary added by the requirements.txt
    # we edit PYTHONPATH for black in the subshell to find the modules
    lambda_root_dir = os.environ["LAMBDA_TASK_ROOT"]
    copy_env_variables["PATH"] = copy_env_variables["PATH"] + f":{lambda_root_dir}/bin"
    copy_env_variables["PYTHONPATH"] = (
        copy_env_variables.get("PYTHONPATH", "") + ":" + lambda_root_dir
    )
    proc = subprocess.Popen(
        "/tmp/script.sh",
        shell=False,
        stdout=subprocess.PIPE,
        stderr=subprocess.STDOUT,
        env=copy_env_variables,
    )
    (stdout, _) = proc.communicate()

    return {"return_code": proc.returncode, "output": stdout.decode("utf-8")}

и лямбда-пакет упакован с этим сценарием: (python3 - это python3.7, а я нахожусь на linux x86_64)

python3 -m pip install -r requirements.txt -t  ./
zip -r archive.zip . -x \*.pyc *.git*

файл needs.txt следующий:

gitpython
black

и когда я выполняю задание CI, я получаю выходные данные подпроцесса:

$ black --check .
Traceback (most recent call last):
  File "/var/task/bin/black", line 6, in <module>
    from black import patched_main
  File "/var/task/black.py", line 15, in <module>
    import regex as re
  File "/var/task/regex/__init__.py", line 1, in <module>
    from .regex import *
  File "/var/task/regex/regex.py", line 402, in <module>
    import regex._regex_core as _regex_core
  File "/var/task/regex/_regex_core.py", line 21, in <module>
    import regex._regex as _regex
ModuleNotFoundError: No module named 'regex._regex'

Особенностью regex._regexp является то, что это скомпилированный модуль с именем regex/_regex.cpython-37m-x86_64-linux-gnu.so, однако, если яимпортировать его прямо в мой лямбда-код, он работает без проблемlem.

Что-то мне не хватает в том, как python работает с модулями из библиотек .so?

Ответы [ 2 ]

0 голосов
/ 05 ноября 2019

Вы упаковываете лямбду на своей машине. Lambda runtime использует (возможно) разные дистрибутивы Linux. Вы можете раскрутить amazonlinux:latest изображение с помощью Docker и оттуда упаковать лямбду. (Вы можете найти шаги здесь https://smirnov -am.github.io / ci-ci-pipeline-for-aws-lambda-python-runtime / )

0 голосов
/ 05 ноября 2019

Проблема заключается в том, что двоичный файл имеет /usr/bin/python3 в своем шебанге и указывает на python3.6, поэтому python3.6 не может загрузить .so, скомпилированный для python3.7

Странно, хотя Lambdaбыл развернут с помощью среды исполнения Python3.7. В lambda python3.7 находится в /var/lang/bin/python3.7, так что на данный момент я изменил свой CI на символическую ссылку python3.7 в /var/lang/bin/python3.7, поэтому shebang, сгенерированный pip, является правильным для lambda,

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...