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

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}")

问题原因

  1. 异步任务未完成:图片处理是异步任务,提交后立即查询状态,此时任务可能还在处理中,返回的响应里没有response_data字段,直接访问会触发KeyError。
  2. 请求参数格式错误:查询任务状态时用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 10:18:14