簡體   English   中英

AWS Lambda python:.so 模塊:ModuleNotFoundError:在子外殼中沒有名為“regex._regex”的模塊

[英]AWS Lambda python: .so module: ModuleNotFoundError: No module named 'regex._regex' when in subshell

我正在嘗試將一些簡單的 CI 作業(例如:linters)運行到 python 存儲庫的 lambda 函數中。

我為此使用 gitlab-ci,基本架構(與問題沒有直接關系,但可能有助於選擇)如下:

在我的例子中,CI 作業被定義為一組 shell 命令,只是運行black --check. (a python linter): 1. the shell commands are sent to my lambda 2. the lambda git clone the repo 3. the lambda execute in a subprocess the commands 4. the result is returned

所以我的 lambda 看起來像這樣:

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")}

並且 lambda 與此腳本一起打包:(python3 是 python3.7,我在 linux x86_64 上)

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

requirements.txt 如下:

gitpython
black

當我執行CI作業時,我進入了子進程的output:

$ 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 ,但是如果我直接將它導入到我的 lambda 代碼中,它可以正常工作。

關於 python 處理來自.so 庫的模塊的方式,我有什么遺漏嗎?

問題來自在其 shebang 中包含/usr/bin/python3並指向 python3.6 的二進制文件,因此 python3.6 無法加載為 python3.7 編譯的.so

奇怪的是,即使 Lambda 是使用 python3.7 運行時部署的。 在 lambda python3.7 位於/var/lang/bin/python3.7中,所以目前我已將我的 CI 修改為 /var/lang/bin/python3.7 中的符號鏈接/var/lang/bin/python3.7所以由pip對 lambda 來說是正確的,

您的機器上的 package lambda。 Lambda 運行時使用(可能)不同的 linux 發行版。 您可能想從那里使用 Docker 和 package lambda 啟動amazonlinux:latest映像。 (您可以在這里找到步驟https://smirnov-am.github.io/ci-ci-pipeline-for-aws-lambda-python-runtime/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM