Cloud Run应用调用Google Drive API获取文件列表返回空值问题
Cloud Run部署应用调用Google Drive API返回空列表问题
问题详情
我正在用Python调用Google Drive API列出文件内容,应用部署在GCP Cloud Run上。封装的GDriveHelper类如下:
class GDriveHelper: def __init__(self, credentials=None) -> None: if credentials: self.service = build("drive", "v3", credentials=credentials) else: self.service = build("drive", "v3") def list_files(self): results = ( self.service.files() .list( pageSize=1000, fields="nextPageToken, files(id, name, mimeType, size, modifiedTime)", ) .execute() ) items = results.get("files", []) return items
本地环境下,使用以下代码能正常获取文件列表(所用服务账号密钥与Cloud Run部署的服务账号一致,client_email为cloud-build@primary-care-378721.iam.gserviceaccount.com):
scope = ["https://www.googleapis.com/auth/drive"] service_account_json_key = "secret.json" credentials = service_account.Credentials.from_service_account_file( filename=service_account_json_key, scopes=scope ) gdrive_helper = GDriveHelper(credentials=credentials) files = gdrive_helper.list_files()
但在Cloud Run应用中调用以下代码时,返回空列表:
gdrive_helper = GDriveHelper() files = gdrive_helper.list_files()
问题原因
- 凭据权限范围差异:本地显式使用服务账号密钥初始化凭据,并指定了
https://www.googleapis.com/auth/drive权限范围,能正常访问授权的Drive资源;而Cloud Run中直接调用build("drive", "v3")时,使用的默认应用凭据不会自动带上Drive的完整权限范围,导致API调用没有足够权限获取文件列表。 - 无权限返回逻辑:Drive API在无权限访问目标资源时,不会返回权限错误,而是直接返回空列表,这也是导致问题不易定位的原因。
解决方案
方法1:显式获取带权限范围的默认凭据
修改Cloud Run中的调用代码,主动获取包含Drive权限的默认凭据:
from google.auth import default scope = ["https://www.googleapis.com/auth/drive"] # 获取带指定权限范围的应用默认凭据 credentials, _ = default(scopes=scope) gdrive_helper = GDriveHelper(credentials=credentials) files = gdrive_helper.list_files()
方法2:优化GDriveHelper类的初始化逻辑
在GDriveHelper中添加自动获取带权限范围凭据的逻辑,无需每次调用都手动处理:
from google.auth import default from googleapiclient.discovery import build class GDriveHelper: def __init__(self, credentials=None, scopes=None) -> None: if credentials: self.service = build("drive", "v3", credentials=credentials) else: # 默认使用Drive全权限范围,可通过参数自定义 target_scopes = scopes or ["https://www.googleapis.com/auth/drive"] credentials, _ = default(scopes=target_scopes) self.service = build("drive", "v3", credentials=credentials) def list_files(self): results = ( self.service.files() .list( pageSize=1000, fields="nextPageToken, files(id, name, mimeType, size, modifiedTime)", ) .execute() ) items = results.get("files", []) return items
额外验证步骤
- 确认目标Drive文件/文件夹已共享给服务账号
cloud-build@primary-care-378721.iam.gserviceaccount.com,权限至少设置为「查看者」; - 在GCP控制台中确认已启用Google Drive API(API库中搜索Drive API并启用)。
内容的提问来源于stack exchange,提问作者p.magalhaes
相关产品推荐
相关产品推荐

