使用python-telegram-bot开发Telegram Bot遇await表达式字典错误求助
问题:Python-Telegram-Bot异步开发中遭遇"object dict can't be used in 'await' expression"错误
使用python-telegram-bot框架结合asyncio开发Telegram Bot,需求是用户点击"AI"按钮后可向ChatGPT提问并获取回复。处理AI会话消息时,用户发送消息后先检查是否处于AI会话,若是则将消息发送给ChatGPT获取回复,但始终触发错误"object dict can't be used in 'await' expression",已卡在此问题5小时。
相关代码
main.py
from typing import Final from telegram import Update, KeyboardButton, ReplyKeyboardMarkup from telegram.ext import Application, CommandHandler, MessageHandler, filters, ContextTypes from gpt_integration import get_gpt_response TOKEN: Final = 'xxxx' BOT_USERNAME: Final = '@xxxx' users_in_ai_session = {} async def start_command(update: Update, context: ContextTypes.DEFAULT_TYPE): button_list = [ [KeyboardButton("/AI"), KeyboardButton("/price")] ] reply_markup = ReplyKeyboardMarkup( button_list, resize_keyboard=True, one_time_keyboard=True) await update.message.reply_text("Welcome message...", reply_markup=reply_markup) async def search_price_command(update: Update, context: ContextTypes.DEFAULT_TYPE): await update.message.reply_text("Please enter the contract address:") async def AI_command(update: Update, context: ContextTypes.DEFAULT_TYPE): user_id = update.effective_user.id users_in_ai_session[user_id] = True await update.message.reply_text( "You're now chatting with AI. Go ahead, ask me anything!") async def handle_message(update: Update, context: ContextTypes.DEFAULT_TYPE): user_id = update.effective_user.id if users_in_ai_session.get(user_id, False): user_input = update.message.text response = await get_gpt_response(user_input) await update.message.reply_text(response) else: print("Error") async def error(update: Update, context: ContextTypes.DEFAULT_TYPE): print(f'Update {update} caused error {context.error}') if __name__ == '__main__': print('Starting bot') app = Application.builder().token(TOKEN).build() app.add_handler(CommandHandler('start', start_command)) app.add_handler(CommandHandler('AI', AI_command)) app.add_handler(CommandHandler('price', search_price_command)) app.add_handler(MessageHandler(filters.TEXT, handle_message)) app.add_error_handler(error) print('Fetching updates...') app.run_polling()
gpt_integration.py
import httpx async def get_gpt_response(message_text): async with httpx.AsyncClient() as client: response = await client.post( 'https://api.openai.com/v1/completions', headers={ 'Authorization': 'xxxx' }, json={ 'model': 'gpt-3.5-turbo', 'prompt': message_text, 'max_tokens': 50 }, ) data = await response.json() return data['choices'][0]['text'].strip()
已完成的排查步骤
- 确认所有异步函数均正确使用
await关键字 - 检查
get_gpt_response函数是否返回可await对象 - 查阅Python asyncio文档排查
await关键字误用场景
错误原因及解决方法
核心原因
- 直接对字典用await:
gpt_integration.py中data = await response.json()是错误的,httpx的response.json()方法是同步方法,直接返回字典对象,不需要加await,对字典使用await会触发报错。 - 接口与模型不匹配:使用gpt-3.5-turbo模型却调用了
/v1/completions接口,该接口仅适用于text-davinci-003等旧模型,gpt-3.5-turbo需要调用/v1/chat/completions接口,且参数格式不同,会导致接口调用失败。
修复步骤
修正
response.json()调用:去掉await关键字,直接获取字典结果:data = response.json()适配gpt-3.5-turbo的接口与参数:
- 将接口路径改为
https://api.openai.com/v1/chat/completions - 修改请求参数为
messages格式,替换原prompt参数 - 调整返回结果的解析路径,适配chat接口的返回结构
- 补充
Bearer前缀到Authorization头
- 将接口路径改为
修复后的gpt_integration.py完整代码
import httpx async def get_gpt_response(message_text): async with httpx.AsyncClient() as client: response = await client.post( 'https://api.openai.com/v1/chat/completions', headers={ 'Authorization': 'Bearer xxxx' }, json={ 'model': 'gpt-3.5-turbo', 'messages': [{"role": "user", "content": message_text}], 'max_tokens': 50 }, ) # 主动抛出HTTP错误,便于排查接口调用问题 response.raise_for_status() data = response.json() return data['choices'][0]['message']['content'].strip()
内容的提问来源于stack exchange,提问作者Yanyi
相关产品推荐
相关产品推荐

