[英]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.