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

Python Flask下载GCP存储桶Blob的App Engine部署及用户端下载问题

你当前的代码仅实现了将GCS存储桶的PDF文件下载到App Engine实例的本地临时目录/tmp,并没有将文件内容返回给访问应用的用户浏览器,因此无法触发用户本地的下载动作。Web场景下要实现用户下载文件,需要将文件内容以符合规范的HTTP响应返回给客户端,由浏览器触发本地保存逻辑。


方案1:直接读取GCS流返回(推荐)

无需将文件写入App Engine实例本地磁盘,直接将GCS文件读取为内存流返回给用户,性能更高,也避免了临时文件的清理问题。
首先导入依赖:

from flask import send_file
from google.cloud import storage
import io

路由实现代码:

@app.route('/download/<file_name>')
def download_file(file_name):
    # 初始化GCS客户端(生产环境建议省略密钥参数,直接使用App Engine默认服务账号权限)
    storage_client = storage.Client.from_service_account_json("ebillaae7f0224519.json")
    bucket = storage_client.get_bucket("bill_storage1")
    blob = bucket.blob(file_name)
    
    # 校验文件是否存在,避免报错
    if not blob.exists():
        return "文件不存在", 404

    # 将GCS文件读取到内存流
    file_buffer = io.BytesIO()
    blob.download_to_file(file_buffer)
    # 重置流指针到起始位置,否则返回的文件是空的
    file_buffer.seek(0)

    # 返回文件响应,触发浏览器下载
    return send_file(
        file_buffer,
        mimetype="application/pdf",
        as_attachment=True,
        download_name=file_name # 自定义用户下载时的默认文件名
    )

方案2:先存到/tmp目录再返回

如果你确实需要先将文件写入实例本地临时目录再返回,可以用以下实现:

import os
from flask import send_file
from google.cloud import storage

@app.route('/download/<file_name>')
def download_file(file_name):
    storage_client = storage.Client.from_service_account_json("ebillaae7f0224519.json")
    bucket = storage_client.get_bucket("bill_storage1")
    blob = bucket.blob(file_name)
    
    if not blob.exists():
        return "文件不存在", 404

    temp_path = os.path.join("/tmp", file_name)
    blob.download_to_filename(temp_path)

    return send_file(
        temp_path,
        mimetype="application/pdf",
        as_attachment=True,
        download_name=file_name
    )

注意事项

  • App Engine的/tmp目录是实例级临时存储,仅当前运行的实例可以访问,实例重启、销毁或扩容时临时文件会丢失,且存储空间上限为实例配置内存的一半,不要存储大文件或作为持久化存储使用。
  • 生产环境建议不要将服务账号密钥文件打包部署到App Engine,你可以给App Engine的默认服务账号授予roles/storage.objectViewer的GCS桶权限,之后直接用storage.Client()初始化即可,不需要传入密钥文件路径,安全性更高。
  • 如果文件允许公开访问,也可以生成GCS的签名URL直接返回给用户,让用户直接从GCS存储桶下载,不需要经过Flask应用转发,能大幅降低应用的负载。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 05:54:02