diff --git a/aiogram/api/client/base.py b/aiogram/api/client/base.py index 22cd5183..85fd529b 100644 --- a/aiogram/api/client/base.py +++ b/aiogram/api/client/base.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import Any, TypeVar +from typing import Any, Optional, TypeVar from ...utils.mixins import ContextInstanceMixin from ...utils.token import extract_bot_id, validate_token @@ -12,13 +12,14 @@ T = TypeVar("T") class BaseBot(ContextInstanceMixin): - def __init__(self, token: str, session: BaseSession = None): + def __init__(self, token: str, session: BaseSession = None, parse_mode: Optional[str] = None): validate_token(token) if session is None: session = AiohttpSession() self.session = session + self.parse_mode = parse_mode self.__token = token @property diff --git a/aiogram/api/methods/answer_inline_query.py b/aiogram/api/methods/answer_inline_query.py index 34f70962..d857016d 100644 --- a/aiogram/api/methods/answer_inline_query.py +++ b/aiogram/api/methods/answer_inline_query.py @@ -38,5 +38,6 @@ class AnswerInlineQuery(TelegramMethod[bool]): def build_request(self) -> Request: data: Dict[str, Any] = self.dict() + self.prepare_parse_mode(data["results"]) return Request(method="answerInlineQuery", data=data) diff --git a/aiogram/api/methods/base.py b/aiogram/api/methods/base.py index ea39de93..31871cf2 100644 --- a/aiogram/api/methods/base.py +++ b/aiogram/api/methods/base.py @@ -65,6 +65,23 @@ class TelegramMethod(abc.ABC, BaseModel, Generic[T]): else: data[name] = value + def prepare_parse_mode(self, root: Any) -> None: + if isinstance(root, list): + for item in root: + self.prepare_parse_mode(item) + return + + if "parse_mode" not in root: + return + + from ..client.bot import Bot + + bot = Bot.get_current(no_error=True) + if bot and bot.parse_mode: + root["parse_mode"] = bot.parse_mode + return + return + async def emit(self, bot: Bot) -> T: return await bot.emit(self) diff --git a/aiogram/api/methods/edit_message_caption.py b/aiogram/api/methods/edit_message_caption.py index 3ffd5450..9e145313 100644 --- a/aiogram/api/methods/edit_message_caption.py +++ b/aiogram/api/methods/edit_message_caption.py @@ -31,5 +31,6 @@ class EditMessageCaption(TelegramMethod[Union[Message, bool]]): def build_request(self) -> Request: data: Dict[str, Any] = self.dict() + self.prepare_parse_mode(data) return Request(method="editMessageCaption", data=data) diff --git a/aiogram/api/methods/edit_message_media.py b/aiogram/api/methods/edit_message_media.py index 560ef3fa..25877314 100644 --- a/aiogram/api/methods/edit_message_media.py +++ b/aiogram/api/methods/edit_message_media.py @@ -33,6 +33,7 @@ class EditMessageMedia(TelegramMethod[Union[Message, bool]]): def build_request(self) -> Request: data: Dict[str, Any] = self.dict() + self.prepare_parse_mode(data["media"]) files: Dict[str, InputFile] = {} self.prepare_media_file(data=data, files=files) diff --git a/aiogram/api/methods/send_media_group.py b/aiogram/api/methods/send_media_group.py index ce713b14..1c25edcd 100644 --- a/aiogram/api/methods/send_media_group.py +++ b/aiogram/api/methods/send_media_group.py @@ -27,8 +27,9 @@ class SendMediaGroup(TelegramMethod[List[Message]]): def build_request(self) -> Request: data: Dict[str, Any] = self.dict() - files: Dict[str, InputFile] = {} + self.prepare_parse_mode(data["media"]) + files: Dict[str, InputFile] = {} self.prepare_input_media(data, files) return Request(method="sendMediaGroup", data=data, files=files) diff --git a/aiogram/api/methods/send_message.py b/aiogram/api/methods/send_message.py index ba30debb..78e2de35 100644 --- a/aiogram/api/methods/send_message.py +++ b/aiogram/api/methods/send_message.py @@ -41,5 +41,6 @@ class SendMessage(TelegramMethod[Message]): def build_request(self) -> Request: data: Dict[str, Any] = self.dict() + self.prepare_parse_mode(data) return Request(method="sendMessage", data=data) diff --git a/docs/api/index.md b/docs/api/index.md index dd67eb7f..26fe7129 100644 --- a/docs/api/index.md +++ b/docs/api/index.md @@ -21,6 +21,15 @@ In this place makes some more differences with official documentations: - timestamps has `datetime.datetime` type instead of `int` - InputFile is used for sending files and is not use `pydantic.BaseModel` as base class -## Client +## Bot instance -... +Bot instance can be created from `aiogram.Bot` (`#!python3 from aiogram import Bot`) + +Constructor specification: + +| Argument | Type | Description | +| --- | --- | --- | +| `token` | `#!python3 str` | Telegram Bot token (Obtained from [@BotFather](https://t.me/BotFather)). | +| `session` | `#!python3 Optional[BaseSession]` | HTTP Client session (For example AiohttpSession). If not specified it will be automatically created. | +| `parse_mode` | `#!python3 Optional[str]` | Default parse mode. If specified it will be propagated into the API methods at runtime. | + diff --git a/tests/test_api/test_methods/test_answer_inline_query.py b/tests/test_api/test_methods/test_answer_inline_query.py index e802a2a8..84c0a05e 100644 --- a/tests/test_api/test_methods/test_answer_inline_query.py +++ b/tests/test_api/test_methods/test_answer_inline_query.py @@ -1,7 +1,8 @@ import pytest +from aiogram import Bot from aiogram.api.methods import AnswerInlineQuery, Request -from aiogram.api.types import InlineQueryResult +from aiogram.api.types import InlineQueryResult, InlineQueryResultPhoto from tests.mocked_bot import MockedBot @@ -27,3 +28,18 @@ class TestAnswerInlineQuery: request: Request = bot.get_request() assert request.method == "answerInlineQuery" assert response == prepare_result.result + + def test_parse_mode(self): + query = AnswerInlineQuery( + inline_query_id="query id", + results=[InlineQueryResultPhoto(id="result id", photo_url="photo", thumb_url="thumb")], + ) + request = query.build_request() + assert request.data["results"][0]["parse_mode"] is None + + token = Bot.set_current(Bot(token="42:TEST", parse_mode="HTML")) + try: + request = query.build_request() + assert request.data["results"][0]["parse_mode"] == "HTML" + finally: + Bot.reset_current(token)