如何使用 ctypes.util.find_library 在 AWS lambda (python) 中导入 .so 库?
How to use ctypes.util.find_library to import .so libraries in AWS lambda (python)?
我正在尝试什么
我在 Lambda 上使用的 python 包 (OCRMYPDF) 需要 leptonica 库 liblept.so.5。在隔离导入代码时,我发现问题出在 find_library('lept')。打印结果 returns None.
from ctypes.util import find_library
def lambda_handler(event, context):
liblept=find_library('lept')
print("liblept:%s"%liblept)
我正在使用的 python 包需要许多本机编译的依赖项。我正在尝试使用 lambda 层导入这些。
层结构
/opt/
/opt/bin/
/opt/lib/
/opt/lib/liblept.so.5
/opt/tesseract
我可以使用 CDLL(下面的代码)访问该文件。但我不想重写包并将每个 find_library() 替换为 CDLL。是否可以为 find_library 设置导入目录?
liblept=CDLL("/opt/lib/liblept.so.5") # found
print("liblept:%s"%liblept)
我的图层代码有效
我使用 docker 图像构建图层。 /opt/bin 中依赖于 leptonica 的文件正在运行(tesseract 运行正常,也测试了 OCR)。
logging.info(os.system("tesseract --version"))
输出
START RequestId: d826d36c-4ce9-4b67-b501-8c9042edcf80 Version: $LATEST
tesseract 4.1.0
leptonica-1.78.0
libgif 5.1.4 : libjpeg 6b (libjpeg-turbo 1.2.90) : libpng 1.2.49 : libtiff 4.0.3 : zlib 1.2.8 : libwebp 0.3.0
Found AVX
Found SSE
END RequestId: d826d36c-4ce9-4b67-b501-8c9042edcf80
在 Python:3.7 AWS lambda 环境中测试:
您需要将 liblept.so
(只需重命名 liblept.so.5
)添加到 lambda 包的 /lib
文件夹或层的 /opt/lib
中。该文件必须称为 liblept.so
,因为 find_library
仅查找 ".so"
个文件,而不查找 ".so.5"
个文件:
来自 python 文档:https://docs.python.org/3/library/ctypes.html
ctypes.util.find_library(name)
Try to find a library and return a pathname. name is the library name without any prefix like lib, suffix like .so, .dylib or version number (this is the form used for the posix linker option -l). If no library can be found, returns None.
当只添加"liblept.so"
时,链接器报错找不到"liblept.so.5"
,所以我也在lib
文件夹中添加了"liblept.so.5"
也许其他人可以参与并找到不使用重复文件的解决方案。
AWS lambda 将通过 LD_LIBRARY_PATH
.
自动生成 /opt/lib
或 /lib
中的任何文件
在 Python 3.8 上,您可能还需要包括 ld
和 objdump
,按照这个线程:https://forums.aws.amazon.com/thread.jspa?threadID=313506,虽然我还没有测试过。
我正在尝试什么
我在 Lambda 上使用的 python 包 (OCRMYPDF) 需要 leptonica 库 liblept.so.5。在隔离导入代码时,我发现问题出在 find_library('lept')。打印结果 returns None.
from ctypes.util import find_library
def lambda_handler(event, context):
liblept=find_library('lept')
print("liblept:%s"%liblept)
我正在使用的 python 包需要许多本机编译的依赖项。我正在尝试使用 lambda 层导入这些。
层结构
/opt/
/opt/bin/
/opt/lib/
/opt/lib/liblept.so.5
/opt/tesseract
我可以使用 CDLL(下面的代码)访问该文件。但我不想重写包并将每个 find_library() 替换为 CDLL。是否可以为 find_library 设置导入目录?
liblept=CDLL("/opt/lib/liblept.so.5") # found
print("liblept:%s"%liblept)
我的图层代码有效
我使用 docker 图像构建图层。 /opt/bin 中依赖于 leptonica 的文件正在运行(tesseract 运行正常,也测试了 OCR)。
logging.info(os.system("tesseract --version"))
输出
START RequestId: d826d36c-4ce9-4b67-b501-8c9042edcf80 Version: $LATEST
tesseract 4.1.0
leptonica-1.78.0
libgif 5.1.4 : libjpeg 6b (libjpeg-turbo 1.2.90) : libpng 1.2.49 : libtiff 4.0.3 : zlib 1.2.8 : libwebp 0.3.0
Found AVX
Found SSE
END RequestId: d826d36c-4ce9-4b67-b501-8c9042edcf80
在 Python:3.7 AWS lambda 环境中测试:
您需要将 liblept.so
(只需重命名 liblept.so.5
)添加到 lambda 包的 /lib
文件夹或层的 /opt/lib
中。该文件必须称为 liblept.so
,因为 find_library
仅查找 ".so"
个文件,而不查找 ".so.5"
个文件:
来自 python 文档:https://docs.python.org/3/library/ctypes.html
ctypes.util.find_library(name)
Try to find a library and return a pathname. name is the library name without any prefix like lib, suffix like .so, .dylib or version number (this is the form used for the posix linker option -l). If no library can be found, returns None.
当只添加"liblept.so"
时,链接器报错找不到"liblept.so.5"
,所以我也在lib
文件夹中添加了"liblept.so.5"
也许其他人可以参与并找到不使用重复文件的解决方案。
AWS lambda 将通过 LD_LIBRARY_PATH
.
/opt/lib
或 /lib
中的任何文件
在 Python 3.8 上,您可能还需要包括 ld
和 objdump
,按照这个线程:https://forums.aws.amazon.com/thread.jspa?threadID=313506,虽然我还没有测试过。