如何用Python编写Lambda将WorkMail附件存到tmp后上传至S3并支持动态文件名
修复方案
你当前代码无法适配不同附件的核心原因是硬编码了固定的文件名/tmp/filename.csv,没有读取附件自带的原始文件名与扩展名,按照以下步骤修改即可适配任意名称、任意后缀的附件:
- 从WorkMail返回的附件MIME对象中调用
get_filename()方法,获取附件的原始完整文件名(包含扩展名) - 将原始文件名拼接到Lambda临时目录路径
/tmp/后,作为临时存储路径 - 上传到S3时可直接使用原始文件名作为S3对象键,也可按需添加前缀避免重名覆盖
修改后的核心代码
替换你原来的文件写入代码即可:
# 读取附件原始文件名(包含后缀) original_filename = attachment.get_filename() # 拼接临时存储路径 tmp_file_path = f"/tmp/{original_filename}" # 写入临时文件(with写法会自动关闭文件句柄,更安全) with open(tmp_file_path, 'wb') as f: f.write(attachment.get_payload(decode=True))
S3上传参考代码
配合boto3即可完成上传,你可以根据需求调整S3的存储路径规则:
import boto3 # 初始化S3客户端 s3_client = boto3.client('s3') # 替换为你自己的S3存储桶名称 TARGET_S3_BUCKET = "你的存储桶名称" # 方式1:上传本地临时文件到S3 s3_client.upload_file( Filename=tmp_file_path, Bucket=TARGET_S3_BUCKET, Key=original_filename # 直接用原始文件名作为S3对象名 # 若要避免重名覆盖,可以加前缀,比如 Key=f"workmail_attachments/{original_filename}" ) # 方式2:优化写法,无需写入临时文件,直接上传二进制内容,节省Lambda临时空间 s3_client.put_object( Bucket=TARGET_S3_BUCKET, Key=original_filename, Body=attachment.get_payload(decode=True) )
额外注意事项
- Lambda的
/tmp临时目录最大容量为512MB,若存在超过这个体积的附件,必须用上述方式2直接上传 - 如果需要进一步区分同文件名的不同附件,可以在文件名前增加时间戳、邮件ID等唯一标识:
import time # 增加时间戳前缀示例 timestamp = int(time.time()) s3_key = f"{timestamp}_{original_filename}"
内容的提问来源于stack exchange,提问作者Shailesh
相关产品推荐
相关产品推荐

