如何安装Poppler以在AWS Lambda上使用

14

我需要在AWS上的Python Lambda函数中运行pdf2image,但这需要在机器上安装poppler和poppler-utils。

我已经尝试在许多不同的地方搜索如何做到这一点,但是找不到任何人使用Lambda函数完成这个任务。

您是否知道如何生成poppler二进制文件,将其放入我的Lambda包中并告诉Lambda使用它?

谢谢大家。

5个回答

5

4

我的方法是使用AWS Linux 2映像作为基础,以确保与Lambda环境的最大兼容性,在容器构建中编译openjpeg和poppler,并构建一个zip文件,其中包含所需的二进制文件和库,然后可以将其用作层。

这使您可以在自己的Lambda中编写代码,该代码将poppler依赖项作为层引入,简化了构建和部署。

层的内容将解压缩到/opt/中。这意味着默认情况下,在Lambda环境中,这些内容将自动可用,因为:

  • $PATH/usr/local/bin:/usr/bin/:/bin:/opt/bin
  • $LD_LIBRARY_PATH/lib64:/usr/lib64:$LAMBDA_RUNTIME_DIR:$LAMBDA_RUNTIME_DIR/lib:$LAMBDA_TASK_ROOT:$LAMBDA_TASK_ROOT/lib:/opt/lib

Dockerfile:

# https://www.petewilcock.com/using-poppler-pdftotext-and-other-custom-binaries-on-aws-lambda/

ARG POPPLER_VERSION="21.10.0"
ARG POPPLER_DATA_VERSION="0.4.11"
ARG OPENJPEG_VERSION="2.4.0"


FROM amazonlinux:2

ARG POPPLER_VERSION
ARG POPPLER_DATA_VERSION
ARG OPENJPEG_VERSION

WORKDIR /root

RUN yum update -y
RUN yum install -y \
   cmake \
   cmake3 \
   fontconfig-devel \
   gcc \
   gcc-c++ \
   gzip \
   libjpeg-devel \
   libpng-devel \
   libtiff-devel \
   make \
   tar \
   xz \
   zip

RUN curl -o poppler.tar.xz https://poppler.freedesktop.org/poppler-${POPPLER_VERSION}.tar.xz
RUN tar xf poppler.tar.xz
RUN curl -o poppler-data.tar.gz https://poppler.freedesktop.org/poppler-data-${POPPLER_DATA_VERSION}.tar.gz
RUN tar xf poppler-data.tar.gz
RUN curl -o openjpeg.tar.gz https://codeload.github.com/uclouvain/openjpeg/tar.gz/refs/tags/v${OPENJPEG_VERSION}
RUN tar xf openjpeg.tar.gz

WORKDIR poppler-data-${POPPLER_DATA_VERSION}
RUN make install

WORKDIR /root
RUN mkdir openjpeg-${OPENJPEG_VERSION}/build
WORKDIR openjpeg-${OPENJPEG_VERSION}/build
RUN cmake .. -DCMAKE_BUILD_TYPE=Release
RUN make
RUN make install

WORKDIR /root
RUN mkdir poppler-${POPPLER_VERSION}/build
WORKDIR poppler-${POPPLER_VERSION}/build
RUN cmake3 .. -DCMAKE_BUILD_TYPE=release -DBUILD_GTK_TESTS=OFF -DBUILD_QT5_TESTS=OFF -DBUILD_QT6_TESTS=OFF \
    -DBUILD_CPP_TESTS=OFF -DBUILD_MANUAL_TESTS=OFF -DENABLE_BOOST=OFF -DENABLE_CPP=OFF -DENABLE_GLIB=OFF \
    -DENABLE_GOBJECT_INTROSPECTION=OFF -DENABLE_GTK_DOC=OFF -DENABLE_QT5=OFF -DENABLE_QT6=OFF \
    -DENABLE_LIBOPENJPEG=openjpeg2 -DENABLE_CMS=none  -DBUILD_SHARED_LIBS=OFF
RUN make
RUN make install


WORKDIR /root
RUN mkdir -p package/{lib,bin,share}
RUN cp -d /usr/lib64/libexpat* package/lib
RUN cp -d /usr/lib64/libfontconfig* package/lib
RUN cp -d /usr/lib64/libfreetype* package/lib
RUN cp -d /usr/lib64/libjbig* package/lib
RUN cp -d /usr/lib64/libjpeg* package/lib
RUN cp -d /usr/lib64/libpng* package/lib
RUN cp -d /usr/lib64/libtiff* package/lib
RUN cp -d /usr/lib64/libuuid* package/lib
RUN cp -d /usr/lib64/libz* package/lib
RUN cp -rd /usr/local/lib/* package/lib
RUN cp -rd /usr/local/lib64/* package/lib
RUN cp -d /usr/local/bin/* package/bin
RUN cp -rd /usr/local/share/poppler package/share

WORKDIR package
RUN zip -r9 ../package.zip *

并且要运行...

docker build -t poppler .
docker run --name poppler -d -t poppler cat
docker cp poppler:/root/package.zip .

然后使用控制台或 AWS CLI 上传 package.zip 作为一层。


很不幸,所接受的答案使用的是 2017 年版本为 0.59 的代码,对于较新版本已失效。如果按照以下方式添加一行代码到复制语句中,可解决该问题: RUN cp -d /usr/lib64/libbz* package/lib - teyzer
对于某些PDF文件,其他PDF查看器中显示的一些文本未被呈现,可能是字体问题。但使用https://github.com/jeylabs/aws-lambda-poppler-layer可以解决该问题。 - teyzer

4

这个过程有没有实现?如何告诉lambda选择二进制文件? - Pankhuri Agarwal
你不需要告诉lambda,只需确保在代码中导入了库,然后创建对象并使用它们。 - Subrata Fouzdar

1

使用Docker在Lambda上构建Poppler的简单指南

为了将Poppler放在Lambda上,我们将构建一个包含poppler的压缩文件夹,并将其作为层添加。请按照以下步骤在运行Amazon Linux 2的EC2实例(t2micro已足够)上执行。

  1. 设置机器

在EC2机器上安装Docker。请参阅此处的说明。

mkdir -p poppler_binaries
  1. 创建一个Dockerfile

使用此链接或从以下内容复制/粘贴。

FROM ubuntu:18.04

# Installing dependencies
RUN apt update
RUN apt-get update
RUN apt-get install -y locate \
                       libopenjp2-7 \
                       poppler-utils

RUN rm -rf /poppler_binaries;  mkdir /poppler_binaries;
RUN updatedb
RUN cp $(locate libpoppler.so) /poppler_binaries/.
RUN cp $(which pdftoppm) /poppler_binaries/.
RUN cp $(which pdfinfo) /poppler_binaries/.
RUN cp $(which pdftocairo) /poppler_binaries/.
RUN cp $(locate libjpeg.so.8 ) /poppler_binaries/.
RUN cp $(locate libopenjp2.so.7 ) /poppler_binaries/.
RUN cp $(locate libpng16.so.16 ) /poppler_binaries/.
RUN cp $(locate libz.so.1 ) /poppler_binaries/.
  1. 构建Docker镜像并创建zip文件

运行下面的命令将在您的主目录中生成一个zip文件。

docker build -t poppler-build .
# Run the container
docker run -d --name poppler-build-cont poppler-build sleep 20 
#docker exec poppler-build-cont 
sudo docker cp poppler-build-cont:/poppler_binaries .
# Cleaning up
docker kill poppler-build-cont
docker rm poppler-build-cont
docker image rm poppler-build
cd poppler_binaries
zip -r9 ..poppler.zip .
cd ..
  1. 制作并添加Lambda Layer

下载您的zip文件或将其上传到S3。前往Lambda控制台页面创建一个Layer,然后将其添加到您的函数中。有关层的信息在此处

  1. 向Lambda添加环境变量

为了避免像这里所描述的那样添加不必要的文件夹结构到zip中,我们将添加一个环境变量来指向我们的依赖项。

PYTHONPATH: /opt/

完成!您现在拥有一个带有Poppler的工作Lambda函数!

注意:感谢这两篇文章,它们帮助我将这些内容整合在一起。

警告:不要尝试将pdf2image添加到同一层中。我不确定为什么,但当它们在同一层中时,pdf2image找不到poppler。


1
嗨,@Alex Albracht,感谢您的回复...我会尝试运行这个程序,以便我可以接受它作为答案。真的很详细!感谢您! - DaviRod
@DaviRod 那太棒了!我尽力校对和测试它,如果你遇到任何问题或错误,请告诉我。 - Alex Albracht
1
这是一个不错的基础,但我不得不做很多更改才能让它适合我。例如Lambda现在使用Yum,而不是libjpeg.so.8,我只选择了libjpeg.so之类的东西。并添加了额外的二进制文件。但它给了我一个大纲,所以谢谢。 - MattC

0

嗨@Alex Albracht,感谢您编写易于理解的说明!它们帮了我很多忙。但是,我确实很难让lambda函数找到poppler路径。因此,我将尝试添加一些内容来澄清这一点。

二进制文件应该放在具有以下结构的zip文件夹中: poppler.zip -> bin/poppler 其中poppler文件夹包含二进制文件。然后可以将此zip文件夹作为AWS lambda中的层上传。

要使pdf2image正常工作,它需要poppler路径。应以格式“/opt/bin/poppler”将其包含在lambda函数中。

例如, poppler_path = "/opt/bin/poppler" pages = convert_from_path(PDF_file, 500, poppler_path=poppler_path)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接