我正在尝试使用本地 API 服务器发送大文件。但是当文件上传时,我收到错误
aiogram.exceptions.TelegramNetworkError: HTTP Client says - Request timeout error.
import asyncio
import logging
import sys
import json
from aiogram import Bot, Dispatcher, html
from aiogram.client.default import DefaultBotProperties
from aiogram.client import telegram
from aiogram.enums import ParseMode
from aiogram.filters import CommandStart
from aiogram.types import Message, BufferedInputFile, InputFile, FSInputFile, URLInputFile
from aiogram.client.session.aiohttp import AiohttpSession
with open('secrets.json', 'r') as f:
secrets=json.loads(f.read())
token = secrets['token']
session = AiohttpSession(
api=telegram.TelegramAPIServer.from_base('http://127.0.0.1:4200')
)
dp = Dispatcher()
@dp.message()
async def echo_handler(message: Message) -> None:
"""
Handler will forward receive a message back to the sender
By default, message handler will handle all message types (like a text, photo, sticker etc.)
"""
with open("./storage/Background Main.mov", 'rb') as f:
inputFile=FSInputFile("./storage/Background Main.mov")
await message.answer('sending test')
await message.answer_document(inputFile)
async def main() -> None:
bot = Bot(token=token, default=DefaultBotProperties(parse_mode=ParseMode.HTML), session=session)
await dp.start_polling(bot, polling_timeout=90)
if __name__ == "__main__":
logging.basicConfig(level=logging.INFO, stream=sys.stdout)
asyncio.run(main())
我编写了这个小程序来尝试在 aoigram 库上重现错误。最初我使用 Telebot。所以,我只是想发送一个 1.5GB 的文件。当我的程序尝试发送文件时,似乎首先将文件复制到本地服务器,然后本地服务器开始上传到电报服务器。我看到此时的网络负载(我有 200mbit/s 带宽)。但 30-60 秒后,错误发生,但是,即使程序崩溃后,文件也会上传到 Telegram 并以消息形式到达。 python中的完整错误代码是:
INFO:aiogram.event:Update id=871987320 is not handled. Duration 60500 ms by bot id=8178713988
ERROR:aiogram.event:Cause exception while process update id=871987320 by bot id=8178713988
TelegramNetworkError: HTTP Client says - Request timeout error
Traceback (most recent call last):
File "g:\Python\TelegramProject\venv\Lib\site-packages\aiogram\client\session\aiohttp.py", line 181, in make_request
async with session.post(
File "g:\Python\TelegramProject\venv\Lib\site-packages\aiohttp\client.py", line 1353, in __aenter__
self._resp = await self._coro
^^^^^^^^^^^^^^^^
File "g:\Python\TelegramProject\venv\Lib\site-packages\aiohttp\client.py", line 684, in _request
await resp.start(conn)
File "g:\Python\TelegramProject\venv\Lib\site-packages\aiohttp\client_reqrep.py", line 994, in start
with self._timer:
File "g:\Python\TelegramProject\venv\Lib\site-packages\aiohttp\helpers.py", line 713, in __exit__
raise asyncio.TimeoutError from None
TimeoutError
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "g:\Python\TelegramProject\venv\Lib\site-packages\aiogram\dispatcher\dispatcher.py", line 309, in _process_update
response = await self.feed_update(bot, update, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "g:\Python\TelegramProject\venv\Lib\site-packages\aiogram\dispatcher\dispatcher.py", line 158, in feed_update
response = await self.update.wrap_outer_middleware(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "g:\Python\TelegramProject\venv\Lib\site-packages\aiogram\dispatcher\middlewares\error.py", line 25, in __call__
return await handler(event, data)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "g:\Python\TelegramProject\venv\Lib\site-packages\aiogram\dispatcher\middlewares\user_context.py", line 56, in __call__
return await handler(event, data)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "g:\Python\TelegramProject\venv\Lib\site-packages\aiogram\fsm\middleware.py", line 42, in __call__
return await handler(event, data)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "g:\Python\TelegramProject\venv\Lib\site-packages\aiogram\dispatcher\event\telegram.py", line 121, in trigger
return await wrapped_inner(event, kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "g:\Python\TelegramProject\venv\Lib\site-packages\aiogram\dispatcher\event\handler.py", line 43, in call
return await wrapped()
^^^^^^^^^^^^^^^
File "g:\Python\TelegramProject\venv\Lib\site-packages\aiogram\dispatcher\dispatcher.py", line 276, in _listen_update
return await self.propagate_event(update_type=update_type, event=event, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "g:\Python\TelegramProject\venv\Lib\site-packages\aiogram\dispatcher\router.py", line 146, in propagate_event
return await observer.wrap_outer_middleware(_wrapped, event=event, data=kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "g:\Python\TelegramProject\venv\Lib\site-packages\aiogram\dispatcher\router.py", line 141, in _wrapped
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "g:\Python\TelegramProject\venv\Lib\site-packages\aiogram\dispatcher\router.py", line 166, in _propagate_event
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "g:\Python\TelegramProject\venv\Lib\site-packages\aiogram\dispatcher\event\telegram.py", line 121, in trigger
return await wrapped_inner(event, kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "g:\Python\TelegramProject\venv\Lib\site-packages\aiogram\dispatcher\event\handler.py", line 43, in call
return await wrapped()
^^^^^^^^^^^^^^^
File "G:\Python\TelegramProject\timeout_test.py", line 54, in echo_handler
await message.answer_document(inputFile)
File "g:\Python\TelegramProject\venv\Lib\site-packages\aiogram\methods\base.py", line 84, in emit
return await bot(self)
^^^^^^^^^^^^^^^
File "g:\Python\TelegramProject\venv\Lib\site-packages\aiogram\client\bot.py", line 488, in __call__
return await self.session(self, method, timeout=request_timeout)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "g:\Python\TelegramProject\venv\Lib\site-packages\aiogram\client\session\base.py", line 254, in __call__
return cast(TelegramType, await middleware(bot, method))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "g:\Python\TelegramProject\venv\Lib\site-packages\aiogram\client\session\aiohttp.py", line 186, in make_request
raise TelegramNetworkError(method=method, message="Request timeout error")
aiogram.exceptions.TelegramNetworkError: HTTP Client says - Request timeout error
我使用的是Win10, https://github.com/tdlib/telegram-bot-api 命令行参数是“telegram-bot-api.exe - -api-id=ID --api-hash="HASH" --local -p 4200 -s 4201 -c 100 --max-webhook-connections=250 -l log.txt -v 2"
我尝试过手动向本地服务器发送请求,它回复了我。也就是说,服务器还活着。如果我设置 -v 2,那么您可以在日志中看到这一点。如果我设置为 3,那么日志文件太大,并且很难理解某些内容。 日志
遇到的问题是由于 aiogram 库中的默认请求超时导致的。当尝试上传大文件时,该过程需要比默认超时时间更长的时间,从而导致
aiogram.exceptions.TelegramNetworkError: HTTP Client says - Request timeout error
错误。
好消息是,尽管出现错误,文件上传实际上仍在后台继续进行,并最终成功完成。这是因为 Telegram API 在处理文件上传方面是异步的。
为了解决此问题,需要增加 aiogram 库使用的请求超时时间。可以通过以下两种方式之一实现此目的:
1. 在发送文件请求期间设置
request_timeout
参数:
await message.answer_document(inputFile, request_timeout=120) # 将超时设置为 120 秒
此方法仅为此特定请求设置超时。
2. 全局更改
AiohttpSession
的默认超时:
session = AiohttpSession(
api=telegram.TelegramAPIServer.from_base('http://127.0.0.1:4200'),
timeout=aiohttp.ClientTimeout(total=120) # 将默认超时设置为 120 秒
)
此方法将更改所有使用此
session
对象的请求的默认超时。
建议:
- 对于上传大文件,建议使用第二种方法全局增加超时时间。
- 选择一个合适的超时值,该值应大于上传文件所需的最长时间。
- 可以通过监控文件上传速度和估计上传完成时间来确定合适的超时值。
其他建议:
- 检查的网络连接,确保其稳定且具有足够的带宽来处理大文件上传。
-
考虑使用 Telegram Bot API 的
sendDocument
方法,该方法允许分块上传大文件。这可以通过在上传过程中提供更好的可靠性和进度指示来帮助防止超时错误。
通过应用这些更改,应该能够解决
TelegramNetworkError
并成功上传大文件,而不会遇到超时问题。