使用Python AWS Lambda读取S3图片通过xhtml2pdf生成PDF报错求助
问题根因
该报错核心原因是xhtml2pdf依赖的Pillow图像处理库缺少Lambda运行环境下的底层系统依赖,仅打包Python层面的库到Lambda层是不够的,缺失了libjpeg-turbo、libpng等处理图片的系统动态链接库,所以不管是读取本地/tmp文件还是解析base64格式图片都会触发识别失败的错误。
修复步骤
- 第一步:重新构建包含系统依赖的Lambda层
不能直接在本地打包Python库上传,需要使用和Lambda运行时完全一致的环境构建层,推荐用官方Amazon Linux容器打包:- 启动和你Lambda使用的Python版本匹配的官方容器(比如Python3.9对应
public.ecr.aws/lambda/python:3.9) - 安装基础系统依赖:
yum install -y libjpeg-turbo-devel libpng-devel zlib-devel - 安装Python依赖到指定目录:
pip install xhtml2pdf pillow -t python/lib/python3.9/site-packages/(注意替换成你对应的Python版本号) - 拷贝系统依赖的动态链接库到层目录:
cp /usr/lib64/libjpeg.so* python/lib/ && cp /usr/lib64/libpng.so* python/lib/ && cp /usr/lib64/libz.so* python/lib/ - 将整个python目录打包为zip文件,上传作为新的Lambda层替换原有层即可
- 启动和你Lambda使用的Python版本匹配的官方容器(比如Python3.9对应
- 第二步:优化Lambda代码(可选,降低IO开销)
现有逻辑先下载到/tmp再转base64属于冗余操作,可以直接从S3读取文件流转base64,无需写入本地存储:
import boto3 import base64 import botocore from xhtml2pdf import pisa s3 = boto3.client('s3') bucketName = 'fileholder' def getFileFromS3(fileKey): try: response = s3.get_object(Bucket=bucketName, Key=fileKey) img_bytes = response['Body'].read() return 'data:image/jpeg;base64,' + base64.b64encode(img_bytes).decode('utf-8') except botocore.exceptions.ClientError as e: raise # 后续生成HTML、输出PDF的逻辑保持原有写法即可
- 第三步:运行配置校验
给Lambda配置至少512MB以上的运行内存,同时如果处理的图片数量多、PDF体积大,建议将/tmp临时存储调整到1024MB以上,避免资源不足导致的执行中断。
轻量替代方案
如果不想手动构建带系统依赖的层,可以换用无额外系统依赖的PDF生成逻辑:直接用reportlab库绘制PDF,跳过xhtml2pdf的HTML转译步骤,直接将图片和文字按排版要求插入到PDF画布即可,依赖更少,在Lambda环境下运行稳定性更高。
内容的提问来源于stack exchange,提问作者Roberto Caetano
相关产品推荐
相关产品推荐

