From 50c2f92e8e74d689438771a436e913be5a425916 Mon Sep 17 00:00:00 2001 From: Davte Date: Wed, 12 Oct 2022 14:08:46 +0200 Subject: [PATCH] asyncio get_event_loop method is being deprecated; use new_event_loop / get_running_loop and asyncio.run instead Major version change because it may not be backward-compatible --- davtelepot/__init__.py | 2 +- davtelepot/api.py | 14 ++++++++++---- davtelepot/api_helper.py | 12 +++--------- davtelepot/bot.py | 32 ++++++++++++++++++++------------ davtelepot/utilities.py | 4 +++- 5 files changed, 37 insertions(+), 27 deletions(-) diff --git a/davtelepot/__init__.py b/davtelepot/__init__.py index 353d272..cbedb60 100644 --- a/davtelepot/__init__.py +++ b/davtelepot/__init__.py @@ -11,7 +11,7 @@ __author__ = "Davide Testa" __email__ = "davide@davte.it" __credits__ = ["Marco Origlia", "Nick Lee @Nickoala"] __license__ = "GNU General Public License v3.0" -__version__ = "2.7.6" +__version__ = "2.8.4" __maintainer__ = "Davide Testa" __contact__ = "t.me/davte" diff --git a/davtelepot/api.py b/davtelepot/api.py index 309f9de..ce815dc 100644 --- a/davtelepot/api.py +++ b/davtelepot/api.py @@ -81,8 +81,8 @@ class TelegramBot: All mirrored methods are camelCase. """ + _loop = None - loop = asyncio.get_event_loop() app = aiohttp.web.Application() sessions_timeouts = { 'getUpdates': dict( @@ -100,6 +100,9 @@ class TelegramBot: def __init__(self, token): """Set bot token and store HTTP sessions.""" + if self.loop is None: + self.__class__._loop = asyncio.new_event_loop() + asyncio.set_event_loop(self.loop) self._token = token self.sessions = dict() self._flood_wait = 0 @@ -112,6 +115,11 @@ class TelegramBot: 0: [] } + @property + def loop(self): + """Telegram API bot token.""" + return self.__class__._loop + @property def token(self): """Telegram API bot token.""" @@ -226,16 +234,14 @@ class TelegramBot: if api_method in cls.sessions_timeouts: if api_method not in self.sessions: self.sessions[api_method] = aiohttp.ClientSession( - loop=cls.loop, timeout=aiohttp.ClientTimeout( total=cls.sessions_timeouts[api_method]['timeout'] ) ) session = self.sessions[api_method] - session_must_be_closed = cls.sessions_timeouts[api_method]['close'] + session_must_be_cl osed = cls.sessions_timeouts[api_method]['close'] else: session = aiohttp.ClientSession( - loop=cls.loop, timeout=aiohttp.ClientTimeout(total=None) ) session_must_be_closed = True diff --git a/davtelepot/api_helper.py b/davtelepot/api_helper.py index 423f327..2b48888 100644 --- a/davtelepot/api_helper.py +++ b/davtelepot/api_helper.py @@ -102,18 +102,14 @@ class TelegramApiMethod(object): return parameters -async def print_api_methods(loop=None, - filename=None, +async def print_api_methods(filename=None, print_all=False, output_file=None, input_file=None): """Get information from Telegram bot API web page.""" - if loop is None: - loop = asyncio.get_event_loop() implemented_methods = dir(TelegramBot) if input_file is None or not os.path.isfile(input_file): async with aiohttp.ClientSession( - loop=loop, timeout=aiohttp.ClientTimeout( total=100 ) @@ -267,10 +263,8 @@ def main(): print_all = cli_arguments['all'] output_file = cli_arguments['out'] input_file = cli_arguments['in'] - loop = asyncio.get_event_loop() - loop.run_until_complete( - print_api_methods(loop=loop, - filename=filename, + asyncio.run( + print_api_methods(filename=filename, print_all=print_all, output_file=output_file, input_file=input_file) diff --git a/davtelepot/bot.py b/davtelepot/bot.py index 281847b..e70dd3b 100644 --- a/davtelepot/bot.py +++ b/davtelepot/bot.py @@ -75,6 +75,7 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject): bots = [] _path = '.' runner = None + server = None # TODO: find a way to choose port automatically by default # Setting port to 0 does not work unfortunately local_host = 'localhost' @@ -3105,6 +3106,10 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject): if not session.closed: await session.close() + async def send_one_message(self, *args, **kwargs): + await self.send_message(*args, **kwargs) + await self.close_sessions() + async def set_webhook(self, url=None, certificate=None, max_connections=None, allowed_updates=None): """Set a webhook if token is valid.""" @@ -3429,9 +3434,19 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject): """ logging.info(message) cls.final_state = final_state - cls.loop.stop() + cls._loop.stop() return + @classmethod + async def run_preliminary_tasks(cls): + await asyncio.gather( + *[ + preliminary_task + for bot in cls.bots + for preliminary_task in bot.preliminary_tasks + ] + ) + @classmethod def run(cls, local_host=None, port=None): """Run aiohttp web app and all Bot instances. @@ -3445,29 +3460,22 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject): cls.local_host = local_host if port is not None: cls.port = port + loop = cls._loop try: - cls.loop.run_until_complete( - asyncio.gather( - *[ - preliminary_task - for bot in cls.bots - for preliminary_task in bot.preliminary_tasks - ] - ) - ) + loop.run_until_complete(cls.run_preliminary_tasks()) except Exception as e: logging.error(f"{e}", exc_info=True) for bot in cls.bots: bot.setup() asyncio.ensure_future(cls.start_app()) try: - cls.loop.run_forever() + loop.run_forever() except KeyboardInterrupt: logging.info("Stopped by KeyboardInterrupt") except Exception as e: logging.error(f"{e}", exc_info=True) finally: - cls.loop.run_until_complete(cls.stop_app()) + loop.run_until_complete(cls.stop_app()) return cls.final_state def set_role_class(self, role): diff --git a/davtelepot/utilities.py b/davtelepot/utilities.py index 2af2c66..af71434 100644 --- a/davtelepot/utilities.py +++ b/davtelepot/utilities.py @@ -503,7 +503,9 @@ async def async_wrapper(coroutine, *args1, **kwargs1): ) await my_coroutine(a=1, b=5) - asyncio.get_event_loop().run_until_complete(main()) + loop = asyncio.new_event_loop() + asyncio.set_event_loop(loop) + asyncio.run(main()) ``` """ async def wrapped_coroutine(*args2, bot=None, update=None, user_record=None, **kwargs2):