Как можно решить проблему aiogram.exceptions.TelegramNetworkError: HTTP Client says — ClientOSError: [Errno 2] Can not write request body for?

Как отправить аудиофайл через бота без проблем с зависанием и ошибкой "Can not write request body for" в терминале?
  • 5 ноября 2023 г. 17:59
Ответы на вопрос 4
Проблема "Can not write request body for" возникает, когда размер файла, который вы пытаетесь отправить через Telegram-бота с использованием библиотеки aiogram, превышает максимальный допустимый размер запроса. По умолчанию этот размер ограничен 50 МБ.

Чтобы решить эту проблему, вы можете использовать разделениеаудиофайла на части и отправку их по одной части за раз. Это поможет снизить общий размер запроса и избежать ошибки "Can not write request body for".

Вот пример кода, который демонстрирует это:

```python
from aiogram import Bot, types
from aiogram.utils import exceptions

async def send_audio(bot: Bot, chat_id: int, audio_path: str) -> str:
    MAX_CHUNK_SIZE = 5242880  # 5 МБ

    try:
        with open(audio_path, 'rb') as file:
            file_size = file.seek(0, 2)

            chunks = []
            file.seek(0)
            while file.tell() < file_size:
                chunk = file.read(MAX_CHUNK_SIZE)
                chunks.append(chunk)

            media = types.InputFile(audio_path)

            for index, chunk in enumerate(chunks, start=1):
                audio_part = types.InputFile(BytesIO(chunk))

                if index == 1:  # отправляем первую часть с метаданными
                    await bot.send_audio(chat_id, audio_part, supports_streaming=True, duration=10)
                else:  # отправляем последующие части без метаданных
                    await bot.send_audio(chat_id, audio_part)

                audio_part.close()

        return "Аудиофайл успешно отправлен!"
    
    except exceptions.TelegramAPIError as e:
        return f"Ошибка Telegram API: {e}"
    
    except IOError as e:
        return f"Ошибка ввода-вывода: {e}"
    
    except Exception as e:
        return f"Неизвестная ошибка: {e}"
```

В этом примере мы считываем аудиофайл по частям, каждая из которых имеет максимально допустимый размер запроса для Telegram API (5 МБ). Затем мы отправляем каждую часть с помощью метода `bot.send_audio()` бота.

Обратите внимание, что в примере я использовал `Bot.send_audio()`, чтобы отправить файл, но вы также можете использовать `types.InputFile()` напрямую при выполнении запроса. Просто убедитесь, что правильно установили флаги поддержки потоковой передачи и указали длительность аудиофайла, если они являются обязательными.

Код также обрабатывает различные типы исключений, которые могут возникнуть во время отправки файла, чтобы предотвратить зависание и предоставить информативные сообщения об ошибках.
Приведем яркий пример решения данной задачи, который оказывается очень простым
Напомню, что path должен быть заранее сформированной строкой, иначе в среде разработки PyCharm возникает ошибка. Вот код решения на Python с использованием callback_query для отправки определенного файла пользователю: 

```
@inline_router_kb.callback_query(F.data == 'send_file')
async def send_answer_file(call: types.CallbackQuery, bot: Bot):
    name_file = see_name_file(call.from_user.id)
    path = r'docs/' + name_file[1] + '.csv'
    
    media_group = [InputMediaDocument(type='document',
                                      media=FSInputFile(path=path),
                                      caption='Расчеты')]

    await bot.send_media_group(chat_id=call.from_user.id,
                               media=media_group)
    update_state_buy_0(call.from_user.id)
```
После исполнения этого кода, ожидается, что файл будет отправлен пользователю
Использование имен файла напрямую вызывает ошибку в PyCharm, поэтому рекомендуется использовать переменную path в виде заранее формированной строки.
Похожие вопросы