Как асинхронно обрабатывать handler в aiogram?
У меня есть handler, который получает некоторое аудио и обрабатывает его с помощью chat gpt. Проблема заключается в следующем: если 2 человека одновременно отправляют сообщение на анализ, то сначала обрабатывается запрос первого и лишь затем второго, т. е. по очереди, как это исправить и обрабатывать процессы асинхронно?
Файл с handler:
from aiogram.enums import ParseMode
from aiogram.types import Message, InlineKeyboardMarkup
from aiogram import Router, F
from openai import OpenAI
from bot import users_data, bot
import io
import tempfile
import os
import whisper
from aiogram.types import FSInputFile
from enums.OtherIconsEnum import OtherIconsEnum
from handlers.messages.default.get_details_keyboard import get_details_keyboard
from models.Message import ConversationMessage
from utils.GPTBot import GPTHelper
from utils.get_text_without_marks import get_text_without_marks
from utils.text_to_voice import text_to_voice
model = whisper.load_model("base.en")
router = Router()
import httpx
def create_async_http_client(base_url: str):
return httpx.AsyncClient(
base_url=base_url,
)
@router.message(F.content_type.in_({'text'}))
async def message_default_handle(message: Message):
current_id: int = message.chat.id
current_user = users_data.find_by_id(current_id)
print(current_user.conversation)
if (current_user and current_user.is_connected):
text_photo = FSInputFile("text_message_image.jpg")
await bot.send_photo(chat_id=current_id, photo=text_photo)
@router.message(F.content_type.in_({'voice'}))
async def message_default_handle(message: Message):
gpt = GPTHelper()
current_id: int = message.chat.id
current_user = users_data.find_by_id(current_id)
print(current_user)
waiting_message: Message = await bot.send_message(chat_id=message.chat.id, text=f"{OtherIconsEnum.ROCKET.value} Предложение получено, анализирую... ")
if (current_user):
voice_data_io = io.BytesIO()
await bot.download(message.voice.file_id, destination=voice_data_io)
voice_data_io.seek(0)
with tempfile.NamedTemporaryFile(suffix='.ogg', delete=False) as tmp_file:
tmp_file.write(voice_data_io.read())
tmp_file_name = tmp_file.name
result = model.transcribe(tmp_file_name,language="en", fp16=False)
user_text: str = result["text"]
correct_text: str = gpt.get_correct_version(user_text)
os.remove(tmp_file_name)
new_message: ConversationMessage = ConversationMessage(
text=correct_text,
author_id=current_user.id,
recipient_id=current_user.conversation.get_friend_id(current_user.id)
)
current_user.conversation.create_message(new_message)
await bot.send_message(
chat_id=current_id,
text=f"{OtherIconsEnum.POINTER.value} Вот анализ твоего сообщения: \n" + correct_text,
reply_markup=get_details_keyboard(new_message.id),
parse_mode=ParseMode.HTML
)
await bot.delete_message(chat_id=message.chat.id, message_id=waiting_message.message_id)
# Temporary saving and sending speech message using TTS
with tempfile.NamedTemporaryFile(suffix='.mp3', mode="w+b", delete=False) as tmp_file:
text_bytes: bytes = await text_to_voice(get_text_without_marks(correct_text))
tmp_file.write(text_bytes)
tmp_file.seek(0)
audio = FSInputFile(tmp_file.name)
await bot.send_voice(
chat_id=current_user.conversation.get_friend_id(current_user.id),
voice=audio
)
Работа с openai api:
import httpx
import openai as oi
from openai import OpenAI
class GPTHelper():
def __init__(self):
self.key = ""
proxy_url: str = "http://138.201.21.218:39141"
self.client = OpenAI(api_key=self.key) if proxy_url is None or proxy_url == "" else OpenAI(
http_client=httpx.Client(proxy=proxy_url), api_key=self.key)
correct_version_prompt: str = (
"Hello, you are an english teacher with B2 english level, what you need to do:"
"If I ask you like `make correct this sentence` you doing this:"
"You go through whole a sentence and if you find a mistake in a word or phrase you !!!!wrap it using <s></s> tag, "
"then after a space you should insert correct version of this phrase of the sentence and wrap it using <b></b> tag."
"!!!Here is exapmle how should you do it: "
"I am asking: Make correct this sentence: <<<<Me went too the store yesterday>>>>, and you should return <s>I</s> <b>Me</b> went too the store yesterday."
"Also remember that you should keep register the same exactly and you should save initial sentence point"
"Here is an example how should you do it:"
"I am asking: Make correct this sentence: <<<<But it not good because it was rotten>>>>, and you should return But it <s>not</s> <b>was not</b> good because it was rotter because initially user said that apple was not good"
"If you did not find mistakes at all return Ошибок не найдено, отлично!"
)
improve_feedback_prompt: str = (
"Hello, you are an english teacher with B2 english level, what you need to do:"
"I give you an english message, where mistakes are already wrapped with <s></s> tag, and correct version wrapper with <b></b> tag, you need to ignore incorrect versions and give some advice about improving of speech"
)
explanation_feedback_prompt: str = (
"Hello, you are an english teacher with B2 english level, what you need to do:"
"I give you an english message, where mistakes are already wrapped with <s></s> tag, and correct version wrapper with <b></b> tag, you need to take this two options and after them paste a small explanation about the rule that used there (30-40 words)"
"you explaining mistakes to a russian person, so make sure that you explanation is on russian language"
"!!!Example: <s>Me</s> <b>I</b> do this every day - Неправильное использование местоимения \n Обьяснение: Вместо Me нужно использовать I"
"!!!Do not use english words outside the given sentence"
"!!!REMEMBER you can explain only mistaked with <s></s> tag"
)
def _ask(self, text: str, prompt: str) -> str:
completions = (self.client.chat.completions.create
(
messages = [
{
"role": "system",
"content": prompt
},
{
"role": "user",
"content": text
}
],
stream=True,
max_tokens=420,
top_p=.69,
model="gpt-3.5-turbo",
temperature=0.1
))
answer: str = "".join(ck.choices[0].delta.content or "" for ck in completions)
return answer
def avoid_landmarks(self, text: str) -> str:
pass
def get_correct_version(self, text: str) -> str:
return self._ask(f"Make correct this sentence: {text}", prompt=self.correct_version_prompt)
def get_improve_feedback(self, text: str) -> str:
return self._ask(f"Improve this sentence: {text}", prompt=self.improve_feedback_prompt)
def get_explanation_feedback(self, text: str) -> str:
return self._ask(f"Explain mistakes in this sentence: {text}", prompt=self.explanation_feedback_prompt)