异步Python程序被阻塞

问题描述 投票:0回答:1

我决定在 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}")

                  .
python python-asyncio aiogram gradio
1个回答
0
投票

您面临的问题的发生是因为

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

如果您需要任何进一步说明,请告诉我!

© www.soinside.com 2019 - 2024. All rights reserved.