调用Google Vision Rest API遇KeyError: 'responses'异常求助
解决Google Vision API请求后缺失'responses'字段的问题
一、先完善错误捕获与日志记录
首先要解决无法定位问题的核心——没有记录异常响应。修改代码,添加完整的错误处理和日志记录,下次出现问题时就能直接看到API返回的内容:
VISION_API_ENDPOINT = 'https://vision.googleapis.com/v1/images:annotate' def get_response(self, img_bytes): # Payload for text detection request data = { "requests": [{ "image": { "content": base64.b64encode(img_bytes).decode("utf-8") }, "features": [{ "type": "TEXT_DETECTION" }], "imageContext": { "languageHints": ["en"] } }] } try: response = requests.post(VISION_API_ENDPOINT, headers=self.request_headers, json=data) # 主动触发HTTP错误(如4xx/5xx)的异常 response.raise_for_status() response_json = response.json() # 检查响应结构是否符合预期 if 'responses' not in response_json: print(f"异常响应内容: {response_json}") return None return response_json except requests.exceptions.RequestException as e: print(f"请求失败: {str(e)}") if response: print(f"原始响应文本: {response.text}") return None
同时,在调用get_response的地方做容错处理,避免直接访问不存在的字段:
response_json = self.get_response(img_bytes) if not response_json or 'responses' not in response_json or len(response_json['responses']) == 0: # 记录日志或跳过当前请求 print("无法获取有效文本检测结果") else: texts = response_json["responses"][0]
二、排查可能的根源
1. 配额或速率限制触发
短时间内7000次请求很可能触发了API的速率限制或配额上限:
- 登录GCP控制台,进入Vision API -> 配额页面,检查「每分钟请求数」「每日请求数」等指标是否接近或达到上限。部分软性限制可能不会在控制台标记为错误,但会返回异常响应。
- 改用批量请求优化:Vision API单次请求最多支持16张图片,可大幅减少请求次数。示例批量请求Payload:
# 批量处理多张图片的示例payload data = { "requests": [ { "image": {"content": base64.b64encode(img_bytes_1).decode("utf-8")}, "features": [{"type": "TEXT_DETECTION"}], "imageContext": {"languageHints": ["en"]} }, { "image": {"content": base64.b64encode(img_bytes_2).decode("utf-8")}, "features": [{"type": "TEXT_DETECTION"}], "imageContext": {"languageHints": ["en"]} } # 最多添加16个请求项 ] }
2. 认证令牌过期
检查request_headers中的Authorization令牌是否有效。如果令牌过期,API会返回401错误,响应中只有error字段而没有responses。可以添加令牌有效性校验,或者使用服务账号密钥自动刷新令牌。
3. 图像数据异常
动态生成的128×32图像可能出现以下问题:
- 图像字节流为空或损坏(
img_bytes长度为0) - 图像格式不被Vision API支持(比如非标准的PNG/JPG)
尝试复现动态生成逻辑,检查生成的图像是否符合要求。
4. 网络或服务端临时故障
网络波动或GCP服务端临时异常会导致返回非预期响应,添加重试逻辑可以缓解这类问题:
from tenacity import retry, stop_after_attempt, wait_exponential @retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=2, max=10)) def get_response(self, img_bytes): # 原函数内容不变
三、后续排查建议
- 启用GCP的Cloud Logging,查看Vision API的详细请求日志,里面会包含每个请求的状态码、响应内容等信息,比控制台的错误统计更准确。
- 逐步降低请求速率,观察是否还会出现异常,确认是否是速率限制导致。
内容的提问来源于stack exchange,提问作者Ganesh Tata
相关产品推荐
相关产品推荐

