mirror of
https://github.com/aiogram/aiogram.git
synced 2025-12-12 18:19:34 +00:00
Add context manager support for bot client (#1468)
* Add context manager support for bot client The bot client now supports the context manager protocol, providing automatic resource management. This enhancement helps to automatically close the session when leaving the context, which cleans up resources better. The documentation and tests have been updated accordingly to illustrate this new feature. Moreover, an example of usage without a dispatcher has been provided to clarify its use in simple cases. * Added changelog
This commit is contained in:
parent
9756dac877
commit
4729978c60
5 changed files with 84 additions and 0 deletions
13
CHANGES/1468.feature.rst
Normal file
13
CHANGES/1468.feature.rst
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
Added context manager interface to Bot instance, from now you can use:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
async with Bot(...) as bot:
|
||||||
|
...
|
||||||
|
|
||||||
|
instead of
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
async with Bot(...).context():
|
||||||
|
...
|
||||||
|
|
@ -5,6 +5,7 @@ import io
|
||||||
import pathlib
|
import pathlib
|
||||||
import warnings
|
import warnings
|
||||||
from contextlib import asynccontextmanager
|
from contextlib import asynccontextmanager
|
||||||
|
from types import TracebackType
|
||||||
from typing import (
|
from typing import (
|
||||||
Any,
|
Any,
|
||||||
AsyncGenerator,
|
AsyncGenerator,
|
||||||
|
|
@ -12,6 +13,7 @@ from typing import (
|
||||||
BinaryIO,
|
BinaryIO,
|
||||||
List,
|
List,
|
||||||
Optional,
|
Optional,
|
||||||
|
Type,
|
||||||
TypeVar,
|
TypeVar,
|
||||||
Union,
|
Union,
|
||||||
cast,
|
cast,
|
||||||
|
|
@ -300,6 +302,17 @@ class Bot:
|
||||||
self.__token = token
|
self.__token = token
|
||||||
self._me: Optional[User] = None
|
self._me: Optional[User] = None
|
||||||
|
|
||||||
|
async def __aenter__(self) -> "Bot":
|
||||||
|
return self
|
||||||
|
|
||||||
|
async def __aexit__(
|
||||||
|
self,
|
||||||
|
exc_type: Optional[Type[BaseException]],
|
||||||
|
exc_value: Optional[BaseException],
|
||||||
|
traceback: Optional[TracebackType],
|
||||||
|
) -> None:
|
||||||
|
await self.session.close()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def parse_mode(self) -> Optional[str]:
|
def parse_mode(self) -> Optional[str]:
|
||||||
warnings.warn(
|
warnings.warn(
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,15 @@ Simple usage
|
||||||
|
|
||||||
.. literalinclude:: ../examples/echo_bot.py
|
.. literalinclude:: ../examples/echo_bot.py
|
||||||
|
|
||||||
|
|
||||||
|
Usage without dispatcher
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
Just only interact with Bot API, without handling events
|
||||||
|
|
||||||
|
.. literalinclude:: ../examples/without_dispatcher.py
|
||||||
|
|
||||||
|
|
||||||
Contents
|
Contents
|
||||||
========
|
========
|
||||||
|
|
||||||
|
|
|
||||||
36
examples/without_dispatcher.py
Normal file
36
examples/without_dispatcher.py
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
import asyncio
|
||||||
|
from argparse import ArgumentParser
|
||||||
|
|
||||||
|
from aiogram import Bot
|
||||||
|
from aiogram.client.default import DefaultBotProperties
|
||||||
|
from aiogram.enums import ParseMode
|
||||||
|
|
||||||
|
|
||||||
|
def create_parser() -> ArgumentParser:
|
||||||
|
parser = ArgumentParser()
|
||||||
|
parser.add_argument("--token", help="Telegram Bot API Token")
|
||||||
|
parser.add_argument("--chat-id", type=int, help="Target chat id")
|
||||||
|
parser.add_argument("--message", "-m", help="Message text to sent", default="Hello, World!")
|
||||||
|
|
||||||
|
return parser
|
||||||
|
|
||||||
|
|
||||||
|
async def main():
|
||||||
|
parser = create_parser()
|
||||||
|
ns = parser.parse_args()
|
||||||
|
|
||||||
|
token = ns.token
|
||||||
|
chat_id = ns.chat_id
|
||||||
|
message = ns.message
|
||||||
|
|
||||||
|
async with Bot(
|
||||||
|
token=token,
|
||||||
|
default=DefaultBotProperties(
|
||||||
|
parse_mode=ParseMode.HTML,
|
||||||
|
),
|
||||||
|
) as bot:
|
||||||
|
await bot.send_message(chat_id=chat_id, text=message)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
asyncio.run(main())
|
||||||
|
|
@ -14,6 +14,7 @@ from aiogram.methods import GetFile, GetMe
|
||||||
from aiogram.types import File, PhotoSize
|
from aiogram.types import File, PhotoSize
|
||||||
from tests.deprecated import check_deprecated
|
from tests.deprecated import check_deprecated
|
||||||
from tests.mocked_bot import MockedBot
|
from tests.mocked_bot import MockedBot
|
||||||
|
from tests.test_api.test_client.test_session.test_base_session import CustomSession
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture()
|
@pytest.fixture()
|
||||||
|
|
@ -42,6 +43,18 @@ class TestBot:
|
||||||
assert isinstance(bot.session, AiohttpSession)
|
assert isinstance(bot.session, AiohttpSession)
|
||||||
assert bot.id == 42
|
assert bot.id == 42
|
||||||
|
|
||||||
|
async def test_bot_context_manager_over_session(self):
|
||||||
|
session = CustomSession()
|
||||||
|
with patch(
|
||||||
|
"tests.test_api.test_client.test_session.test_base_session.CustomSession.close",
|
||||||
|
new_callable=AsyncMock,
|
||||||
|
) as mocked_close:
|
||||||
|
async with Bot(token="42:TEST", session=session) as bot:
|
||||||
|
assert bot.id == 42
|
||||||
|
assert bot.session is session
|
||||||
|
|
||||||
|
mocked_close.assert_awaited_once()
|
||||||
|
|
||||||
def test_init_default(self):
|
def test_init_default(self):
|
||||||
with check_deprecated(
|
with check_deprecated(
|
||||||
max_version="3.7.0",
|
max_version="3.7.0",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue