add more tests (#19)

This commit is contained in:
Dmitry Afanasyev
2023-09-29 13:54:57 +03:00
committed by GitHub
parent 7cfda281f7
commit 90ec8ccec1
15 changed files with 263 additions and 76 deletions

View File

@@ -8,7 +8,7 @@ from typing import Any
from fastapi import Request, Response
from loguru import logger
from telegram import Update
from telegram import Bot, Update
from telegram.ext import Application
from settings.config import AppSettings
@@ -19,9 +19,8 @@ class BotApplication:
self,
settings: AppSettings,
handlers: list[Any],
application: Application | None = None, # type: ignore[type-arg]
) -> None:
self.application: Application = application or ( # type: ignore
self.application: Application = ( # type: ignore[type-arg]
Application.builder().token(token=settings.TELEGRAM_API_TOKEN).build()
)
self.handlers = handlers
@@ -29,6 +28,10 @@ class BotApplication:
self.start_with_webhook = settings.START_WITH_WEBHOOK
self._add_handlers()
@property
def bot(self) -> Bot:
return self.application.bot
async def set_webhook(self) -> None:
_, webhook_info = await asyncio.gather(self.application.initialize(), self.application.bot.get_webhook_info())
if not webhook_info.url:

View File

@@ -10,13 +10,13 @@ from loguru import logger
from telegram import InlineKeyboardMarkup, Update
from telegram.ext import ContextTypes
from constants import CHAT_GPT_BASE_URL, BotEntryPoints
from constants import CHAT_GPT_BASE_URI, BotEntryPoints
from core.keyboards import main_keyboard
from core.utils import SpeechToTextService
from settings.config import settings
async def main_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
async def main_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> str:
"""Send message on `/start`."""
if not update.message:
return BotEntryPoints.end
@@ -29,7 +29,7 @@ async def about_me(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
if not update.effective_message:
return None
await update.effective_message.reply_text(
'Автор бота: *Дмитрий Афанасьев*\n\nTg nickname: *Balshtg*', parse_mode='MarkdownV2'
"Автор бота: *Дмитрий Афанасьев*\n\nTg nickname: *Balshtg*", parse_mode="MarkdownV2"
)
@@ -40,7 +40,7 @@ async def about_bot(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"Бот использует бесплатную модель Chat-GPT3.5 для ответов на вопросы. "
"Принимает запросы на разных языках. \n\nБот так же умеет переводить голосовые сообщения в текст. "
"Просто пришлите голосовуху и получите поток сознания без запятых в виде текста",
parse_mode='Markdown',
parse_mode="Markdown",
)
@@ -88,12 +88,12 @@ async def ask_question(update: Update, context: ContextTypes.DEFAULT_TYPE) -> No
}
transport = AsyncHTTPTransport(retries=3)
async with AsyncClient(transport=transport, timeout=50) as client:
async with AsyncClient(base_url=settings.GPT_BASE_HOST, transport=transport, timeout=50) as client:
try:
response = await client.post(CHAT_GPT_BASE_URL, json=chat_gpt_request, timeout=50)
response = await client.post(CHAT_GPT_BASE_URI, json=chat_gpt_request, timeout=50)
status = response.status_code
if status != httpx.codes.OK:
logger.info(f'got response status: {status} from chat api', data=chat_gpt_request)
logger.info(f"got response status: {status} from chat api", data=chat_gpt_request)
await update.message.reply_text(
"Что-то пошло не так, попробуйте еще раз или обратитесь к администратору"
)
@@ -117,7 +117,7 @@ async def voice_recognize(update: Update, context: ContextTypes.DEFAULT_TYPE) ->
with tempfile.NamedTemporaryFile(delete=False) as tmpfile:
tmpfile.write(sound_bytes)
logger.info('file has been saved', filename=tmpfile.name)
logger.info("file has been saved", filename=tmpfile.name)
speech_to_text_service = SpeechToTextService(filename=tmpfile.name)

View File

@@ -39,16 +39,16 @@ bot_event_handlers.add_handler(
entry_points=[CommandHandler("start", main_command)],
states={
BotEntryPoints.start_routes: [
CallbackQueryHandler(about_me, pattern="^" + str(BotStagesEnum.about_me) + "$"),
CallbackQueryHandler(website, pattern="^" + str(BotStagesEnum.website) + "$"),
CallbackQueryHandler(help_command, pattern="^" + str(BotStagesEnum.help) + "$"),
CallbackQueryHandler(about_bot, pattern="^" + str(BotStagesEnum.about_bot) + "$"),
CallbackQueryHandler(about_me, pattern="^" + BotStagesEnum.about_me + "$"),
CallbackQueryHandler(website, pattern="^" + BotStagesEnum.website + "$"),
CallbackQueryHandler(help_command, pattern="^" + BotStagesEnum.help + "$"),
CallbackQueryHandler(about_bot, pattern="^" + BotStagesEnum.about_bot + "$"),
],
},
fallbacks=[CommandHandler("start", main_command)],
)
)
bot_event_handlers.add_handler(CallbackQueryHandler(about_me, pattern="^" + str(BotStagesEnum.about_me) + "$"))
bot_event_handlers.add_handler(CallbackQueryHandler(website, pattern="^" + str(BotStagesEnum.website) + "$"))
bot_event_handlers.add_handler(CallbackQueryHandler(help_command, pattern="^" + str(BotStagesEnum.help) + "$"))
bot_event_handlers.add_handler(CallbackQueryHandler(about_bot, pattern="^" + str(BotStagesEnum.about_bot) + "$"))
bot_event_handlers.add_handler(CallbackQueryHandler(about_me, pattern="^" + BotStagesEnum.about_me + "$"))
bot_event_handlers.add_handler(CallbackQueryHandler(website, pattern="^" + BotStagesEnum.website + "$"))
bot_event_handlers.add_handler(CallbackQueryHandler(help_command, pattern="^" + BotStagesEnum.help + "$"))
bot_event_handlers.add_handler(CallbackQueryHandler(about_bot, pattern="^" + BotStagesEnum.about_bot + "$"))

View File

@@ -2,13 +2,13 @@ from telegram import InlineKeyboardButton
from constants import BotStagesEnum
main_keyboard = [
[
main_keyboard = (
(
InlineKeyboardButton("Обо мне", callback_data=str(BotStagesEnum.about_me)),
InlineKeyboardButton("Веб версия", callback_data=str(BotStagesEnum.website)),
],
[
),
(
InlineKeyboardButton("Помощь", callback_data=str(BotStagesEnum.help)),
InlineKeyboardButton("О боте", callback_data=str(BotStagesEnum.about_bot)),
],
]
),
)

View File

@@ -31,7 +31,7 @@ class InterceptHandler(logging.Handler):
logger.opt(depth=depth, exception=record.exc_info).log(
level,
record.getMessage().replace(settings.TELEGRAM_API_TOKEN, "TELEGRAM_API_TOKEN".center(24, '*')),
record.getMessage().replace(settings.TELEGRAM_API_TOKEN, "TELEGRAM_API_TOKEN".center(24, "*")),
)

View File

@@ -55,7 +55,7 @@ class SpeechToTextService:
self._convert_audio_to_text()
def _convert_audio_to_text(self) -> None:
wav_filename = f'{self.filename}.wav'
wav_filename = f"{self.filename}.wav"
speech = AudioSegment.from_wav(wav_filename)
speech_duration = len(speech)
@@ -82,8 +82,8 @@ class SpeechToTextService:
logger.error("error temps files not deleted", error=error, filenames=[self.filename, self.filename])
def _convert_file_to_wav(self) -> None:
new_filename = self.filename + '.wav'
cmd = ['ffmpeg', '-loglevel', 'quiet', '-i', self.filename, '-vn', new_filename]
new_filename = self.filename + ".wav"
cmd = ["ffmpeg", "-loglevel", "quiet", "-i", self.filename, "-vn", new_filename]
try:
subprocess.run(args=cmd) # noqa: S603
logger.info("file has been converted to wav", filename=new_filename)
@@ -96,7 +96,7 @@ class SpeechToTextService:
with AudioFile(tmp_filename) as source:
audio_text = self.recognizer.listen(source)
try:
text = self.recognizer.recognize_google(audio_text, language='ru-RU')
text = self.recognizer.recognize_google(audio_text, language="ru-RU")
os.remove(tmp_filename)
return text
except SpeechRecognizerError as error: