我决定在 aiogram 上编写一个电报机器人,通过 gradioc_lient api 实现 qwen 2.5 数学神经网络。
问题是,当有 Api 请求时,异步程序被阻塞,机器人停止响应,直到产生结果。
有什么办法可以解决这个问题吗?
import uuid
from aiogram import Router, F
from aiogram.filters import CommandStart, Command
from aiogram.types import Message
from gradio_client import Client, handle_file
start_router = Router()
async def image_hueta(fileName):
client = Client("Qwen/Qwen2-Math-Demo")
result = client.predict(
image=handle_file(fileName),
sketchpad={"background": handle_file(
'https://raw.githubusercontent.com/gradio-app/gradio/main/test/test_files/bus.png'), "layers": [],
"composite": None},
question="доказать равенсво",
api_name="/math_chat_bot"
)
return result
@start_router.message(CommandStart())
async def cmd_start(message: Message):
await message.answer("Хай!!!")
@start_router.message(F.photo)
async def send_photo(message: Message):
local_filename = f"{uuid.uuid4()}.png"
await message.bot.download(file = message.photo[-1].file_id, destination=local_filename)
await message.answer("Ваш запрос обрабатывается...")
result = await image_hueta(local_filename)
await message.answer(f"{result}")
.
您面临的问题的发生是因为
client.predict
函数是同步的,这意味着它在等待响应时会阻止机器人的执行。这就是您的机器人在 API 调用期间变得无响应的原因。
您可以通过使用
asyncio.to_thread
(Python 3.9+) 在单独的线程中运行阻塞 API 调用来解决此问题,这将使机器人在处理长时间运行的任务时保持响应。
更新代码:
import uuid
import asyncio
from aiogram import Router, F
from aiogram.filters import CommandStart
from aiogram.types import Message
from gradio_client import Client, handle_file
start_router = Router()
def image_hueta(fileName):
client = Client("Qwen/Qwen2-Math-Demo")
result = client.predict(
image=handle_file(fileName),
sketchpad={
"background": handle_file(
'https://raw.githubusercontent.com/gradio-app/gradio/main/test/test_files/bus.png'),
"layers": [],
"composite": None
},
question="доказать равенсво",
api_name="/math_chat_bot"
)
return result
@start_router.message(CommandStart())
async def cmd_start(message: Message):
await message.answer("Хай!!!")
@start_router.message(F.photo)
async def send_photo(message: Message):
local_filename = f"{uuid.uuid4()}.png"
await message.photo[-1].download(destination_file=local_filename)
await message.answer("Ваш запрос обрабатывается...")
# Run the blocking function in a separate thread
result = await asyncio.to_thread(image_hueta, local_filename)
await message.answer(f"{result}")
对于 3.9 以下的 Python 版本:
如果您使用的是 Python 3.7 或 3.8,请将
asyncio.to_thread
替换为 loop.run_in_executor
:
@start_router.message(F.photo)
async def send_photo(message: Message):
# ... (same as above)
loop = asyncio.get_event_loop()
result = await loop.run_in_executor(None, image_hueta, local_filename)
await message.answer(f"{result}")
如果您需要任何进一步说明,请告诉我!