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

Google App Engine通过/tmp/读取文件报错[Errno 2]无对应文件或目录如何解决?

问题根源

  1. Google App Engine(GAE)的/tmp目录是实例级临时存储,仅在当前实例运行期间有效,部署阶段不会将本地的token_sheets_v4.pickle上传到该路径,自然读取不到文件。
  2. 你配置的app.yaml的handlers规则存在严重错误:把根路径/映射为静态pickle文件,会导致所有根路径请求直接返回文件下载,完全绕开了Flask应用逻辑。
  3. 代码本身存在两处缺陷:
    • pickle_file变量未提前定义,读写路径不一致,一会硬编码/tmp路径一会用未定义变量
    • flow.run_local_server()是桌面端OAuth授权流程,依赖本地浏览器完成授权交互,在GAE服务端环境运行会直接失败,无法完成授权。

解决方案(推荐用方案1,适配服务端部署场景)

方案1:使用服务账号授权

  • 进入Google Cloud控制台「API和服务」-「凭据」页面,创建服务账号,下载JSON格式的密钥文件,命名为service_account.json,和Flask启动文件(main.py)放在同一目录。
  • 打开你要操作的Google Sheet,点击「共享」,输入服务账号的邮箱地址,授予对应查看/编辑权限。
  • 替换Create_Service函数逻辑,改用服务账号授权,无需本地生成pickle文件、无需手动授权:
import os
from google.oauth2 import service_account
from googleapiclient.discovery import build

def Create_Service(api_name, api_version, *scopes):
    SCOPES = [scope for scope in scopes[0]]
    # 读取同目录下的服务账号密钥文件
    creds = service_account.Credentials.from_service_account_file(
        os.path.join(os.path.dirname(__file__), 'service_account.json'), 
        scopes=SCOPES
    )
    try:
        service = build(api_name, api_version, credentials=creds)
        print(f'{api_name} service created successfully')
        return service
    except Exception as e:
        print('Unable to connect.')
        print(e)
        return None
  • 修正app.yaml配置,删除错误的handlers规则,保留基础配置即可:
runtime: python39 # 替换为你实际使用的Python版本
entrypoint: gunicorn -b :$PORT main:app
  • 部署时确保service_account.json在上传文件列表中。

方案2:保留原有OAuth pickle文件的适配方案

如果必须使用原有生成的token_sheets_v4.pickle,按以下步骤调整:

  • 本地完成授权,确保生成的token_sheets_v4.pickle可用,将文件放到Flask应用根目录(和main.py同目录)。
  • 修正代码路径逻辑,不要读写/tmp目录,删除服务端无法运行的授权流程:
def Create_Service(client_secret_file, api_name, api_version, *scopes):
    CLIENT_SECRET_FILE = client_secret_file
    API_SERVICE_NAME = api_name
    API_VERSION = api_version
    SCOPES = [scope for scope in scopes[0]]

    cred = None
    # 统一pickle文件路径,指向应用根目录的文件
    pickle_file = os.path.join(os.path.dirname(__file__), 'token_sheets_v4.pickle')

    if os.path.exists(pickle_file):
        with open(pickle_file, 'rb') as token:
            cred = pickle.load(token)

    # 服务端不需要再走授权流程,本地已经生成可用的cred,删掉下面这段flow相关逻辑
    # if not cred or not cred.valid:
    #     if cred and cred.expired and cred.refresh_token:
    #         cred.refresh(Request())
    #     else:
    #         flow = InstalledAppFlow.from_client_secrets_file(CLIENT_SECRET_FILE, SCOPES)
    #         cred = flow.run_local_server()
    #     with open(pickle_file, 'wb') as token:
    #         pickle.dump(cred, token)

    try:
        service = build(API_SERVICE_NAME, API_VERSION, credentials=cred)
        print(API_SERVICE_NAME, 'service created successfully')
        return service
    except Exception as e:
        print('Unable to connect.')
        print(e)
        return None
  • 同样删除app.yaml中错误的handlers静态文件配置,确保请求正常转发到Flask应用。
  • 部署时将token_sheets_v4.pickle和代码一起上传。注意该方案下令牌过期后需要本地重新生成再部署,维护成本更高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.17 13:27:01