Telethon приводит к `RuntimeWarning: сопрограмма 'MessageMethods.send_message' никогда не ожидалась` - PullRequest
1 голос
/ 02 апреля 2020

Я пытаюсь запустить этот первый фрагмент кода , предоставленный документацией Telethon. Но после нескольких проблем ( здесь и здесь ) я получил эту модифицированную версию:

import os
import sys
from telethon.sync import TelegramClient, events

# import nest_asyncio
# nest_asyncio.apply()

session_name = "<session_name>"
api_id = <api_id>
api_hash = "<api_hash>"


os.chdir(sys.path[0])

if f"{session_name}.session" in os.listdir():
    os.remove(f"{session_name}.session")

async with TelegramClient(session_name, api_id, api_hash) as client:
   client.send_message('me', 'Hello, myself!')
   print(client.download_profile_photo('me'))

   @client.on(events.NewMessage(pattern='(?i).*Hello'))
   async def handler(event):
      await event.reply('Hey!')

   client.run_until_disconnected()

Однако теперь я получаю следующие предупреждения:

usr/local/lib/python3.7/site-packages/ipykernel_launcher.py:23: RuntimeWarning: coroutine 'MessageMethods.send_message' was never awaited
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
/usr/local/lib/python3.7/site-packages/ipykernel_launcher.py:24: RuntimeWarning: coroutine 'DownloadMethods.download_profile_photo' was never awaited
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
/usr/local/lib/python3.7/site-packages/ipykernel_launcher.py:30: RuntimeWarning: coroutine 'UpdateMethods._run_until_disconnected' was never awaited
RuntimeWarning: Enable tracemalloc to get the object allocation traceback

при запуске кода на Jupyter. Теперь вот мои вопросы:

  • что означают эти предупреждающие сообщения и как мне их адресовать?
  • каков ожидаемый результат этого кода при правильной работе? Должен ли я получить сообщение в Telegram или что-то? Потому что я не получаю никаких сообщений, кроме кода входа.
  • Что означает символ @ в начале строки @client.on...? что эта линия должна делать? С этой строки я не понимаю код. Буду признателен, если вы поможете мне понять это.

Ответы [ 2 ]

1 голос
/ 02 апреля 2020

Просто добавьте await client.send_message('me', 'Hello, myself!'), чтобы устранить эту ошибку, и напечатайте после того, как download_profile_photo выполнит свою работу, загрузит изображение в localhost, поэтому, возможно, вы ничего не видите. Вам следует внимательно прочитать документацию по телетону , а также , как правильно использовать загрузку фотографий

Все вызовы клиента имеют задержку и всегда должны ожидаться, чтобы ваш код не блокируется Вы должны прочитать asyncio tutorial Правильный код:

async with TelegramClient(session_name, api_id, api_hash) as client:
   await client.send_message('me', 'Hello, myself!')
   print(await client.download_profile_photo('me'))

   @client.on(events.NewMessage(pattern='(?i).*Hello'))
   async def handler(event):
      await event.reply('Hey!')

   #await client.run_until_disconnected()

@ является декоратором, и вы должны прочитать PEP, относящийся к декораторам , но в короткие слова, они выполняют функцию перед вами.

В этом случае @client.on(events.NewMessage означает:

Когда появляется новое событие, которое оказывается сообщением, которое соответствует указанному шаблону, обрабатывайте его с помощью эта функция называется handler

1 голос
/ 02 апреля 2020

Jupyter запустит событие asyncio l oop, чтобы вы могли использовать async for / with / await вне async def. Это конфликтует с .sync magi c Telethon, которого следует избегать при использовании Jupyter, I Python или аналогичного.

Для исправления вашего кода:

from telethon import TelegramClient, events
#            ^ note no .sync

session_name = "<session_name>"
api_id = <api_id>
api_hash = "<api_hash>"

async with TelegramClient(session_name, api_id, api_hash) as client:
    await client.send_message('me', 'Hello, myself!')
    # ^ note you need to use `await` in Jupyter
    # we are avoiding the `.sync` magic so it needs to be done by yourself

    print(await client.download_profile_photo('me'))
    #     ^ same here, needs await

    @client.on(events.NewMessage(pattern='(?i).*Hello'))
    async def handler(event):
        await event.reply('Hey!')

    await client.run_until_disconnected()
    # ^ once again needs await

Если Вы хотите, чтобы код выполнялся где угодно (Jupyter, Python shell, обычный запуск), просто обязательно сделайте все внутри async def:

import asyncio

from telethon import TelegramClient, events

session_name = "<session_name>"
api_id = <api_id>
api_hash = "<api_hash>"

async def main():
    async with TelegramClient(session_name, api_id, api_hash) as client:
       await client.send_message('me', 'Hello, myself!')
       print(await client.download_profile_photo('me'))

       @client.on(events.NewMessage(pattern='(?i).*Hello'))
       async def handler(event):
           await event.reply('Hey!')

       await client.run_until_disconnected()

# Only this line changes, the rest will work anywhere.
# Jupyter
await main()

# Otherwise
asyncio.run(main())
...