Google Drive API共享配额超限咨询:少量请求为何触发报错?
Google Drive API 触发「Sorry, you have exceeded your sharing quota」但控制台限额未耗尽的问题排查
问题描述
调用Google Drive API时触发报错:Sorry, you have exceeded your sharing quota.,具体情况:
- 5小时内均匀发起235次请求,后期出现30次该报错,后续所有请求均被拦截
- Google Cloud控制台中查看所有API限额,均显示未被耗尽
相关代码
#! /usr/bin/env python # -*- coding: utf-8 -*- import sys, json, base64, time import httplib2 import apiclient.discovery from oauth2client.service_account import ServiceAccountCredentials input_data = json.loads(base64.b64decode(sys.argv[1])) user_mail = input_data['user_mail'] admin_mail = input_data['admin_mail'] donor_spreadsheet_id = input_data['donor_spreadsheet_id'] #donor_spreadsheet_id = '*****' #hided CREDENTIALS_FILE = '*****.json' #hided scope = ['https://www.googleapis.com/auth/spreadsheets', 'https://www.googleapis.com/auth/drive'] credentials = ServiceAccountCredentials.from_json_keyfile_name(CREDENTIALS_FILE, scope) httpAuth = credentials.authorize(httplib2.Http()) driveService = apiclient.discovery.build('drive', 'v3', http=httpAuth) try: new_spreadsheet = driveService.files().copy(fileId=donor_spreadsheet_id).execute() except Exception as e: print('Copy error: ', json.loads(e.content)['error']['errors'][0]['message']) try: shareRes = driveService.permissions().create( fileId = new_spreadsheet['id'], body = {'type': 'user', 'role': 'writer', 'emailAddress': user_mail}, fields = 'id' ).execute() except Exception as e: print('Adding user mail error: ', json.loads(e.content)['error']['errors'][0]['message']) new_url = 'https://docs.google.com/spreadsheets/d/' + new_spreadsheet['id'] + '/' print(new_url)
问题根源分析
分享配额的计算维度不是API请求次数
Google Drive的sharing quota限制的是短时间内向不同用户/群组分享文件的数量,而非API调用次数。即使总请求量仅235次,若每次都是向不同的user_mail分享新文件,很容易触发这个配额——该限制属于Drive本身的共享规则,不会显示在Cloud控制台的API请求限额中。域内共享限制(针对Workspace账号)
如果服务账号属于Google Workspace域,域管理员可能设置了共享频率限制,这类限制同样不会在Cloud控制台的API限额中体现,需要在Workspace Admin控制台的「Drive and Docs」→「共享设置」中查看。缺少错误重试与流量控制
代码未实现指数退避机制,当首次遇到配额警告后,继续发起请求会被快速限制,导致后续所有请求均被拦截;同时缺少请求间隔控制,密集的分享操作容易触发临时限流。代码健壮性不足
若文件复制失败,new_spreadsheet未被赋值,后续的分享操作会抛出NameError,虽然不是本次报错的直接原因,但会导致无效请求增加。
修复建议
1. 检查Drive共享配额
- 普通账号:Google Drive单日最多向约500个不同用户分享文件,短时间内密集分享会触发临时限制,需分散操作时间。
- Workspace账号:登录Workspace Admin控制台,进入「Drive and Docs」→「共享设置」,查看是否有域内共享频率限制。
2. 添加指数退避重试逻辑
对permissions().create操作添加指数退避,避免被快速限制:
from googleapiclient.errors import HttpError import time max_retries = 5 retry_delay = 1 for attempt in range(max_retries): try: shareRes = driveService.permissions().create( fileId=new_spreadsheet['id'], body={'type': 'user', 'role': 'writer', 'emailAddress': user_mail}, fields='id' ).execute() break except HttpError as e: if e.resp.status in [429, 500, 503] and attempt < max_retries - 1: time.sleep(retry_delay) retry_delay *= 2 else: print('Adding user mail error: ', json.loads(e.content)['error']['errors'][0]['message']) break
3. 优化代码健壮性
文件复制失败后直接终止流程,避免无效操作:
try: new_spreadsheet = driveService.files().copy(fileId=donor_spreadsheet_id).execute() except Exception as e: print('Copy error: ', json.loads(e.content)['error']['errors'][0]['message']) sys.exit(1) # 退出程序,避免后续报错
4. 分散请求频率
在每次请求后添加短暂休眠,降低分享操作的密集度:
# 在复制和分享操作后添加休眠 time.sleep(1) # 可根据实际情况调整时长
内容的提问来源于stack exchange,提问作者Роман Лыжов
相关产品推荐
相关产品推荐

