FastAPI应用出现KeyError: 'response_data'问题求助
FastAPI应用抛出KeyError: 'response_data'异常排查与修复
报错栈
Traceback (most recent call last): File "C:\Users\abu aisha\Documents\whatsappPhotoEditor\venv\lib\site-packages\starlette\middleware\errors.py", line 162, in __call__ await self.app(scope, receive, _send) File "C:\Users\abu aisha\Documents\whatsappPhotoEditor\venv\lib\site-packages\starlette\middleware\exceptions.py", line 79, in __call__ raise exc File "C:\Users\abu aisha\Documents\whatsappPhotoEditor\venv\lib\site-packages\starlette\middleware\exceptions.py", line 68, in __call__ await self.app(scope, receive, sender) File "C:\Users\abu aisha\Documents\whatsappPhotoEditor\venv\lib\site-packages\fastapi\middleware\asyncexitstack.py", line 21, in __call__ raise e File "C:\Users\abu aisha\Documents\whatsappPhotoEditor\venv\lib\site-packages\fastapi\middleware\asyncexitstack.py", line 18, in __call__ await self.app(scope, receive, send) File "C:\Users\abu aisha\Documents\whatsappPhotoEditor\venv\lib\site-packages\starlette\routing.py", line 718, in __call__ await route.handle(scope, receive, send) File "C:\Users\abu aisha\Documents\whatsappPhotoEditor\venv\lib\site-packages\starlette\routing.py", line 276, in handle await self.app(scope, receive, send) File "C:\Users\abu aisha\Documents\whatsappPhotoEditor\venv\lib\site-packages\starlette\routing.py", line 66, in app response = await func(request) File "C:\Users\abu aisha\Documents\whatsappPhotoEditor\venv\lib\site-packages\fastapi\routing.py", line 237, in app raw_response = await run_endpoint_function( File "C:\Users\abu aisha\Documents\whatsappPhotoEditor\venv\lib\site-packages\fastapi\routing.py", line 163, in run_endpoint_function return await dependant.call(**values) File "C:\Users\abu aisha\Documents\whatsappPhotoEditor\main.py", line 63, in reply image_url = image_response.json()["response_data"]["result"]["output"][0] KeyError: 'response_data'
应用核心代码(main.py)
from fastapi import FastAPI, Form, File, UploadFile import requests from utils import send_message from dotenv import load_dotenv import os import json load_dotenv() app = FastAPI(debug=True) api_key = os.getenv("MONSTER_API_KEY") bearer_token = os.getenv("BEARER_TOKEN") whatsapp_number = os.getenv("TO_NUMBER") @app.post("/message") async def reply(file: UploadFile = File(...), prompt: str = Form(...)): file.filename = "image.jpg" contents = await file.read() with open(f"{file.filename}", "wb") as f: f.write(contents) url = "https://api.monsterapi.ai/apis/add-task" payload = { "model": "pix2pix", "data": { "prompt": prompt, "negprompt": "", "steps": 50, "guidance_scale": 12.5, "init_image_url": file.filename, "image_guidance_scale": 1.5 } } headers = { 'x-api-key': api_key, 'Authorization': bearer_token, 'Content-Type': 'application/json' } response = requests.post(url, headers=headers, json=payload) response.raise_for_status() process_id = response.json()["process_id"] response_url = "https://api.monsterapi.ai/apis/task-status" response_payload = { "process_id": process_id } response_headers = { 'x-api-key': api_key, 'Authorization': bearer_token, 'Content-Type': 'application/json' } image_response = requests.request("POST", response_url, headers=response_headers, data=response_payload) image_url = image_response.json()["response_data"]["result"]["output"][0] send_message(whatsapp_number, image_url) return ""
相关API返回示例
- 提交任务接口返回:
{'message': 'Request accepted successfully', 'process_id': 'eee2c49e-083a-11ee-b335-99c647f2e5d3'}
- 任务完成时状态接口返回:
{'message': 'Request processed successfully', 'response_data': {'process_id': 'eee2c49e-083a-11ee-b335-99c647f2e5d3', 'status': 'COMPLETED', 'result': {'output': ['https://processed-model-result.s3.us-east-2.amazonaws.com/eee2c49e-083a-11ee-b335-99c647f2e5d3_0.png']}, 'credit_used': 4, 'overage': 0}}
send_message工具函数代码
import logging from dotenv import load_dotenv import os from twilio.rest import Client load_dotenv() account_sid = os.getenv("TWILIO_ACCOUNT_SID") auth_token = os.getenv("TWILIO_AUTH_TOKEN") client = Client(account_sid, auth_token) twilio_number = os.getenv('TWILIO_NUMBER') # 日志配置 logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) # Twilio WhatsApp消息发送逻辑 def send_message(to_number, media): try: message = client.messages.create( from_=f"whatsapp:{twilio_number}", to=f"whatsapp:{to_number}", media_url=[media] ) logger.info(f"消息已发送至 {to_number}: {message.media_url}") except Exception as e: logger.error(f"发送消息至 {to_number} 失败: {e}")
问题原因
- 异步任务未完成:图片处理是异步任务,提交后立即查询状态,此时任务可能还在处理中,返回的响应里没有
response_data字段,直接访问会触发KeyError。 - 请求参数格式错误:查询任务状态时用
data=response_payload传递参数,接口无法正确解析JSON格式的process_id,导致返回异常响应。
修复方案
1. 修正任务状态接口请求方式
将查询任务状态的请求改为用json参数传递payload,确保接口正确解析参数:
# 替换原image_response请求代码 image_response = requests.post(response_url, headers=response_headers, json=response_payload) image_response.raise_for_status() # 新增:检查请求是否成功
2. 添加轮询等待任务完成
增加轮询逻辑,直到任务状态变为COMPLETED再获取图片链接:
import time # 获取process_id后添加轮询逻辑 max_retries = 30 # 最多等待30次 retry_interval = 2 # 每2秒查询一次 for _ in range(max_retries): image_response = requests.post(response_url, headers=response_headers, json={"process_id": process_id}) image_response.raise_for_status() result_data = image_response.json() # 检查是否存在response_data且任务完成 response_data = result_data.get("response_data") if response_data and response_data["status"] == "COMPLETED": image_url = response_data["result"]["output"][0] send_message(whatsapp_number, image_url) return {"status": "success", "image_url": image_url} # 任务未完成,继续等待 time.sleep(retry_interval) # 超时处理 raise Exception("任务处理超时,请稍后重试")
3. 增加字段访问容错
对JSON字段访问添加容错处理,避免意外KeyError:
response_data = result_data.get("response_data") if not response_data: continue # 无数据则继续轮询 status = response_data.get("status") if status != "COMPLETED": continue image_url = response_data.get("result", {}).get("output", [])[0] if not image_url: raise Exception("未获取到处理后的图片链接")
完整修复后的接口代码
from fastapi import FastAPI, Form, File, UploadFile import requests from utils import send_message from dotenv import load_dotenv import os import json import time load_dotenv() app = FastAPI(debug=True) api_key = os.getenv("MONSTER_API_KEY") bearer_token = os.getenv("BEARER_TOKEN") whatsapp_number = os.getenv("TO_NUMBER") @app.post("/message") async def reply(file: UploadFile = File(...), prompt: str = Form(...)): file.filename = "image.jpg" contents = await file.read() with open(f"{file.filename}", "wb") as f: f.write(contents) url = "https://api.monsterapi.ai/apis/add-task" payload = { "model": "pix2pix", "data": { "prompt": prompt, "negprompt": "", "steps": 50, "guidance_scale": 12.5, "init_image_url": file.filename, "image_guidance_scale": 1.5 } } headers = { 'x-api-key': api_key, 'Authorization': bearer_token, 'Content-Type': 'application/json' } response = requests.post(url, headers=headers, json=payload) response.raise_for_status() process_id = response.json()["process_id"] response_url = "https://api.monsterapi.ai/apis/task-status" response_headers = { 'x-api-key': api_key, 'Authorization': bearer_token, 'Content-Type': 'application/json' } max_retries = 30 retry_interval = 2 for _ in range(max_retries): image_response = requests.post(response_url, headers=response_headers, json={"process_id": process_id}) image_response.raise_for_status() result_data = image_response.json() response_data = result_data.get("response_data") if not response_data: time.sleep(retry_interval) continue if response_data["status"] == "COMPLETED": image_url = response_data["result"]["output"][0] send_message(whatsapp_number, image_url) return {"status": "success", "image_url": image_url} time.sleep(retry_interval) raise Exception("任务处理超时,请稍后重试")
内容的提问来源于stack exchange,提问作者Ridwan Adejumo Suleiman
相关产品推荐
相关产品推荐

