You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Python无需下载至本地直接发送S3内CSV文件为邮件附件

可行性结论

该需求完全可以实现,全程不需要依赖本地存储,也不需要把S3文件下载到磁盘,所有文件读取、附件构造操作全在内存中完成即可,完全适配你在常规服务器上运行Python应用的场景,和是否使用Lambda没有关系。

核心逻辑

你之前参考的方案落盘的本质,是调用了S3 SDK的下载到本地文件的方法,先把文件写到磁盘路径,再从磁盘读文件构造邮件附件,这一步磁盘IO完全可以跳过:

  • S3 SDK的get_object接口会直接返回可读取的流式响应体,不需要落盘就能拿到完整文件内容
  • Python原生的邮件构造模块支持直接读取内存中的二进制内容生成附件,不需要从本地路径加载文件
    两者直接对接就能实现零本地存储依赖的发送逻辑。
实现步骤
  • 安装依赖:只需要安装boto3用于对接S3,邮件发送相关能力全部用Python标准库实现即可,执行安装命令pip install boto3
  • 初始化S3客户端,配置好对应存储桶的访问凭证、区域、访问地址
  • 调用get_object接口获取目标CSV对象,不要使用download_file这类会写本地磁盘的方法
  • 直接读取响应体中的二进制内容,存入内存字节对象
  • 构造标准MIME邮件,将内存中的CSV二进制内容封装为附件,设置好附件文件名
  • 通过SMTP协议完成邮件发送,全程不会产生任何本地文件写入操作
可直接运行的参考代码
import boto3
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.application import MIMEApplication

# 替换为你自己的配置项
S3_CONF = {
    "aws_access_key_id": "你的S3访问密钥ID",
    "aws_secret_access_key": "你的S3访问密钥",
    "region_name": "存储桶所在区域"
}
TARGET_BUCKET = "你的S3存储桶名称"
CSV_S3_KEY = "目标CSV在桶内的完整路径,例:report/202405/sales.csv"

MAIL_CONF = {
    "smtp_host": "你的SMTP服务器地址",
    "smtp_port": 465,
    "smtp_account": "发件邮箱账号",
    "smtp_password": "发件邮箱授权码",
    "sender_addr": "发件人邮箱地址",
    "receiver_addrs": ["收件人1邮箱", "收件人2邮箱"]
}

def send_csv_as_attachment():
    # 初始化S3客户端
    s3 = boto3.client("s3", **S3_CONF)
    # 拉取S3对象,全程不落盘
    s3_resp = s3.get_object(Bucket=TARGET_BUCKET, Key=CSV_S3_KEY)
    # 直接把文件内容读入内存
    csv_binary = s3_resp["Body"].read()
    csv_filename = CSV_S3_KEY.split("/")[-1]

    # 构造邮件内容
    mail = MIMEMultipart()
    mail["From"] = MAIL_CONF["sender_addr"]
    mail["To"] = ",".join(MAIL_CONF["receiver_addrs"])
    mail["Subject"] = "CSV数据文件"
    mail.attach(MIMEText("请查收附件中的CSV数据文件", "plain", "utf-8"))

    # 构造附件,直接使用内存中的二进制内容
    attachment = MIMEApplication(csv_binary)
    attachment.add_header(
        "Content-Disposition",
        "attachment",
        filename=csv_filename
    )
    mail.attach(attachment)

    # 发送邮件
    with smtplib.SMTP_SSL(MAIL_CONF["smtp_host"], MAIL_CONF["smtp_port"]) as smtp_conn:
        smtp_conn.login(MAIL_CONF["smtp_account"], MAIL_CONF["smtp_password"])
        smtp_conn.sendmail(
            MAIL_CONF["sender_addr"],
            MAIL_CONF["receiver_addrs"],
            mail.as_string()
        )

if __name__ == "__main__":
    send_csv_as_attachment()

注意:如果单个CSV文件体积超过服务器可用内存的1/3,建议改用分块流式读取的方式构造邮件内容,避免OOM。常规业务场景下MB级别的CSV文件用上述代码完全可以稳定运行,不会产生任何本地临时文件,符合你们公司的安全要求。

内容的提问来源于stack exchange,提问作者Stan Ostrovskii

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 21:51:44