From b7a7e207501cec6385c08701b3e1089dfbd840e1 Mon Sep 17 00:00:00 2001 From: Alex Root Junior Date: Sat, 6 Nov 2021 02:14:14 +0200 Subject: [PATCH] Create aiohttp session inside async function --- aiogram/bot/base.py | 24 +++++++++++++++++------- aiogram/utils/executor.py | 3 ++- examples/proxy_and_emojize.py | 2 +- tests/types/test_mixins.py | 2 +- 4 files changed, 21 insertions(+), 10 deletions(-) diff --git a/aiogram/bot/base.py b/aiogram/bot/base.py index 07e44c1c..eb1a9b9e 100644 --- a/aiogram/bot/base.py +++ b/aiogram/bot/base.py @@ -105,7 +105,7 @@ class BaseBot: self.parse_mode = parse_mode - def get_new_session(self) -> aiohttp.ClientSession: + async def get_new_session(self) -> aiohttp.ClientSession: return aiohttp.ClientSession( connector=self._connector_class(**self._connector_init, loop=self._main_loop), loop=self._main_loop, @@ -116,10 +116,17 @@ class BaseBot: def loop(self) -> Optional[asyncio.AbstractEventLoop]: return self._main_loop - @property - def session(self) -> Optional[aiohttp.ClientSession]: + async def get_session(self) -> Optional[aiohttp.ClientSession]: if self._session is None or self._session.closed: - self._session = self.get_new_session() + self._session = await self.get_new_session() + return self._session + + @property + @deprecated( + reason="Client session should be created inside async function, use `await bot.get_session()` instead", + stacklevel=3, + ) + async def session(self) -> Optional[aiohttp.ClientSession]: return self._session @staticmethod @@ -185,7 +192,8 @@ class BaseBot: """ Close all client sessions """ - await self.session.close() + if self._session: + await self._session.close() async def request(self, method: base.String, data: Optional[Dict] = None, @@ -205,7 +213,8 @@ class BaseBot: :rtype: Union[List, Dict] :raise: :obj:`aiogram.exceptions.TelegramApiError` """ - return await api.make_request(self.session, self.server, self.__token, method, data, files, + + return await api.make_request(await self.get_session(), self.server, self.__token, method, data, files, proxy=self.proxy, proxy_auth=self.proxy_auth, timeout=self.timeout, **kwargs) async def download_file(self, file_path: base.String, @@ -233,7 +242,8 @@ class BaseBot: url = self.get_file_url(file_path) dest = destination if isinstance(destination, io.IOBase) else open(destination, 'wb') - async with self.session.get(url, timeout=timeout, proxy=self.proxy, proxy_auth=self.proxy_auth) as response: + session = await self.get_session() + async with session.get(url, timeout=timeout, proxy=self.proxy, proxy_auth=self.proxy_auth) as response: while True: chunk = await response.content.read(chunk_size) if not chunk: diff --git a/aiogram/utils/executor.py b/aiogram/utils/executor.py index c74827b0..9807423f 100644 --- a/aiogram/utils/executor.py +++ b/aiogram/utils/executor.py @@ -365,7 +365,8 @@ class Executor: self.dispatcher.stop_polling() await self.dispatcher.storage.close() await self.dispatcher.storage.wait_closed() - await self.dispatcher.bot.session.close() + session = await self.dispatcher.bot.get_session() + await session.close() async def _startup_polling(self): await self._welcome() diff --git a/examples/proxy_and_emojize.py b/examples/proxy_and_emojize.py index 5ef40608..84ad74a8 100644 --- a/examples/proxy_and_emojize.py +++ b/examples/proxy_and_emojize.py @@ -50,7 +50,7 @@ async def cmd_start(message: types.Message): # This line is formatted to '🌎 *IP:* `YOUR IP`' # Make request through bot's proxy - ip = await fetch(GET_IP_URL, bot.session) + ip = await fetch(GET_IP_URL, await bot.get_session()) content.append(text(':locked_with_key:', bold('IP:'), code(ip), italic('via proxy'))) # This line is formatted to '🔐 *IP:* `YOUR IP` _via proxy_' diff --git a/tests/types/test_mixins.py b/tests/types/test_mixins.py index 4327e8aa..4ee4381a 100644 --- a/tests/types/test_mixins.py +++ b/tests/types/test_mixins.py @@ -18,7 +18,7 @@ async def bot_fixture(): """ Bot fixture """ _bot = Bot(TOKEN) yield _bot - await _bot.session.close() + await (await _bot.get_session()).close() @pytest.fixture