Dev 3.x flat package (#961)

* Move packages

* Added changelog

* Update examples/echo_bot.py

Co-authored-by: Oleg A. <t0rr@mail.ru>

* Rename `handler` -> `handlers`

* Update __init__.py

Co-authored-by: Oleg A. <t0rr@mail.ru>
This commit is contained in:
Alex Root Junior 2022-08-14 01:07:52 +03:00 committed by GitHub
parent 5e7932ca20
commit 4315ecf1a2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
111 changed files with 376 additions and 390 deletions

View file

@ -1,13 +1,13 @@
from aiogram.dispatcher.flags import FlagGenerator
from .client import session
from .client.bot import Bot
from .dispatcher import filters, handler
from .dispatcher.dispatcher import Dispatcher
from .dispatcher.flags.flag import FlagGenerator
from .dispatcher.middlewares.base import BaseMiddleware
from .dispatcher.router import Router
from .utils.magic_filter import MagicFilter
from .utils.text_decorations import html_decoration as _html_decoration
from .utils.text_decorations import markdown_decoration as _markdown_decoration
from .utils.text_decorations import html_decoration as html
from .utils.text_decorations import markdown_decoration as md
try:
import uvloop as _uvloop
@ -17,8 +17,6 @@ except ImportError: # pragma: no cover
pass
F = MagicFilter()
html = _html_decoration
md = _markdown_decoration
flags = FlagGenerator()
__all__ = (
@ -31,8 +29,6 @@ __all__ = (
"Dispatcher",
"Router",
"BaseMiddleware",
"filters",
"handler",
"F",
"html",
"md",

View file

@ -165,6 +165,10 @@ T = TypeVar("T")
class Bot(ContextInstanceMixin["Bot"]):
"""
Bot class
"""
def __init__(
self,
token: str,
@ -172,8 +176,6 @@ class Bot(ContextInstanceMixin["Bot"]):
parse_mode: Optional[str] = None,
) -> None:
"""
Bot class
:param token: Telegram Bot token `Obtained from @BotFather <https://t.me/BotFather>`_
:param session: HTTP Client session (For example AiohttpSession).
If not specified it will be automatically created.

View file

@ -9,16 +9,16 @@ from typing import Any, AsyncGenerator, Dict, List, Optional, Union
from .. import loggers
from ..client.bot import Bot
from ..exceptions import TelegramAPIError, TelegramNetworkError, TelegramServerError
from ..fsm.middleware import FSMContextMiddleware
from ..fsm.storage.base import BaseEventIsolation, BaseStorage
from ..fsm.storage.memory import DisabledEventIsolation, MemoryStorage
from ..fsm.strategy import FSMStrategy
from ..methods import GetUpdates, TelegramMethod
from ..types import Update, User
from ..types.update import UpdateTypeLookupError
from ..utils.backoff import Backoff, BackoffConfig
from .event.bases import UNHANDLED, SkipHandler
from .event.telegram import TelegramEventObserver
from .fsm.middleware import FSMContextMiddleware
from .fsm.storage.base import BaseEventIsolation, BaseStorage
from .fsm.storage.memory import DisabledEventIsolation, MemoryStorage
from .fsm.strategy import FSMStrategy
from .middlewares.error import ErrorsMiddleware
from .middlewares.user_context import UserContextMiddleware
from .router import Router

View file

@ -7,8 +7,8 @@ from typing import Any, Callable, Dict, List, Optional, Tuple
from magic_filter import MagicFilter
from aiogram.dispatcher.flags.getter import extract_flags_from_object
from aiogram.dispatcher.handler.base import BaseHandler
from aiogram.dispatcher.flags import extract_flags_from_object
from aiogram.handlers import BaseHandler
CallbackType = Callable[..., Any]

View file

@ -1,5 +1,6 @@
from __future__ import annotations
import warnings
from inspect import isclass
from itertools import chain
from typing import TYPE_CHECKING, Any, Callable, Dict, Generator, List, Optional, Tuple, Type
@ -7,10 +8,10 @@ from typing import TYPE_CHECKING, Any, Callable, Dict, Generator, List, Optional
from pydantic import ValidationError
from aiogram.dispatcher.middlewares.manager import MiddlewareManager
from aiogram.filters.base import BaseFilter
from ...exceptions import FiltersResolveError
from ...types import TelegramObject
from ..filters.base import BaseFilter
from .bases import REJECTED, UNHANDLED, MiddlewareType, SkipHandler
from .handler import CallbackType, FilterObject, HandlerObject
@ -160,6 +161,15 @@ class TelegramEventObserver:
unresolved_fields=set(full_config.keys()), possible_cases=possible_cases
)
if bound_filters:
warnings.warn(
category=DeprecationWarning,
message="Filters factory deprecated and will be removed in Beta 5. "
"Use filters directly, for example instead of "
"`@router.message(commands=['help']')` "
"use `@router.message(Command(commands=['help'])`",
stacklevel=3,
)
return bound_filters
def register(

View file

@ -1,12 +1,10 @@
from dataclasses import dataclass
from typing import TYPE_CHECKING, Any, Callable, Optional, Union, cast, overload
from typing import TYPE_CHECKING, Any, Callable, Dict, Optional, Union, cast, overload
from magic_filter import AttrDict
from aiogram.dispatcher.flags.getter import extract_flags_from_object
from magic_filter import AttrDict, MagicFilter
if TYPE_CHECKING:
pass
from aiogram.dispatcher.event.handler import HandlerObject
@dataclass(frozen=True)
@ -77,3 +75,53 @@ class FlagGenerator:
if TYPE_CHECKING:
chat_action: _ChatActionFlagProtocol
def extract_flags_from_object(obj: Any) -> Dict[str, Any]:
if not hasattr(obj, "aiogram_flag"):
return {}
return cast(Dict[str, Any], obj.aiogram_flag)
def extract_flags(handler: Union["HandlerObject", Dict[str, Any]]) -> Dict[str, Any]:
"""
Extract flags from handler or middleware context data
:param handler: handler object or data
:return: dictionary with all handler flags
"""
if isinstance(handler, dict) and "handler" in handler:
handler = handler["handler"]
if not hasattr(handler, "flags"):
return {}
return handler.flags # type: ignore
def get_flag(
handler: Union["HandlerObject", Dict[str, Any]],
name: str,
*,
default: Optional[Any] = None,
) -> Any:
"""
Get flag by name
:param handler: handler object or data
:param name: name of the flag
:param default: default value (None)
:return: value of the flag or default
"""
flags = extract_flags(handler)
return flags.get(name, default)
def check_flags(handler: Union["HandlerObject", Dict[str, Any]], magic: MagicFilter) -> Any:
"""
Check flags via magic filter
:param handler: handler object or data
:param magic: instance of the magic
:return: the result of magic filter check
"""
flags = extract_flags(handler)
return magic.resolve(AttrDict(flags))

View file

@ -1,56 +0,0 @@
from typing import TYPE_CHECKING, Any, Dict, Optional, Union, cast
from magic_filter import AttrDict, MagicFilter
if TYPE_CHECKING:
from aiogram.dispatcher.event.handler import HandlerObject
def extract_flags_from_object(obj: Any) -> Dict[str, Any]:
if not hasattr(obj, "aiogram_flag"):
return {}
return cast(Dict[str, Any], obj.aiogram_flag)
def extract_flags(handler: Union["HandlerObject", Dict[str, Any]]) -> Dict[str, Any]:
"""
Extract flags from handler or middleware context data
:param handler: handler object or data
:return: dictionary with all handler flags
"""
if isinstance(handler, dict) and "handler" in handler:
handler = handler["handler"]
if not hasattr(handler, "flags"):
return {}
return handler.flags # type: ignore
def get_flag(
handler: Union["HandlerObject", Dict[str, Any]],
name: str,
*,
default: Optional[Any] = None,
) -> Any:
"""
Get flag by name
:param handler: handler object or data
:param name: name of the flag
:param default: default value (None)
:return: value of the flag or default
"""
flags = extract_flags(handler)
return flags.get(name, default)
def check_flags(handler: Union["HandlerObject", Dict[str, Any]], magic: MagicFilter) -> Any:
"""
Check flags via magic filter
:param handler: handler object or data
:param magic: instance of the magic
:return: the result of magic filter check
"""
flags = extract_flags(handler)
return magic.resolve(AttrDict(flags))

View file

@ -3,12 +3,13 @@ from __future__ import annotations
import warnings
from typing import Any, Dict, Final, Generator, List, Optional, Set, Union
from aiogram.filters import BUILTIN_FILTERS
from ..types import TelegramObject
from ..utils.warnings import CodeHasNoEffect
from .event.bases import REJECTED, UNHANDLED
from .event.event import EventObserver
from .event.telegram import TelegramEventObserver
from .filters import BUILTIN_FILTERS
INTERNAL_UPDATE_TYPES: Final[frozenset[str]] = frozenset({"update", "error"})

View file

@ -16,7 +16,7 @@ from .chat_member_updated import (
RESTRICTED,
ChatMemberUpdatedFilter,
)
from .command import Command, CommandObject
from .command import Command, CommandObject, CommandStart
from .content_types import ContentTypesFilter
from .exception import ExceptionMessageFilter, ExceptionTypeFilter
from .logic import and_f, invert_f, or_f
@ -30,6 +30,7 @@ __all__ = (
"Text",
"Command",
"CommandObject",
"CommandStart",
"ContentTypesFilter",
"ExceptionMessageFilter",
"ExceptionTypeFilter",

View file

@ -3,7 +3,7 @@ from typing import TYPE_CHECKING, Any, Awaitable, Callable, Dict, Union
from pydantic import BaseModel
from aiogram.dispatcher.filters.logic import _LogicFilter
from aiogram.filters.logic import _LogicFilter
class BaseFilter(BaseModel, ABC, _LogicFilter):

View file

@ -9,7 +9,7 @@ from uuid import UUID
from magic_filter import MagicFilter
from pydantic import BaseModel
from aiogram.dispatcher.filters import BaseFilter
from aiogram.filters import BaseFilter
from aiogram.types import CallbackQuery
T = TypeVar("T", bound="CallbackData")

View file

@ -1,6 +1,6 @@
from typing import Any, Dict, Optional, TypeVar, Union
from aiogram.dispatcher.filters import BaseFilter
from aiogram.filters import BaseFilter
from aiogram.types import ChatMember, ChatMemberUpdated
MarkerT = TypeVar("MarkerT", bound="_MemberStatusMarker")

View file

@ -2,16 +2,18 @@ from __future__ import annotations
import re
from dataclasses import dataclass, field, replace
from typing import Any, Dict, Match, Optional, Pattern, Sequence, Tuple, Union, cast
from typing import TYPE_CHECKING, Any, Dict, Match, Optional, Pattern, Sequence, Tuple, Union, cast
from magic_filter import MagicFilter
from pydantic import Field, validator
from aiogram import Bot
from aiogram.dispatcher.filters import BaseFilter
from aiogram.filters import BaseFilter
from aiogram.types import Message
from aiogram.utils.deep_linking import decode_payload
if TYPE_CHECKING:
from aiogram import Bot
CommandPatternType = Union[str, re.Pattern]

View file

@ -2,9 +2,9 @@ from typing import Any, Dict, Optional, Sequence, Union
from pydantic import validator
from aiogram.types import Message
from aiogram.types.message import ContentType
from ...types import Message
from .base import BaseFilter

View file

@ -3,7 +3,7 @@ from typing import Any, Dict, Pattern, Tuple, Type, Union, cast
from pydantic import validator
from aiogram.dispatcher.filters import BaseFilter
from aiogram.filters import BaseFilter
from aiogram.types import TelegramObject

View file

@ -2,7 +2,7 @@ from typing import Any
from magic_filter import AttrDict, MagicFilter
from aiogram.dispatcher.filters import BaseFilter
from aiogram.filters import BaseFilter
from aiogram.types import TelegramObject

View file

@ -3,8 +3,8 @@ from typing import Any, Dict, Optional, Sequence, Type, Union, cast, no_type_che
from pydantic import Field, validator
from aiogram.dispatcher.filters import BaseFilter
from aiogram.dispatcher.fsm.state import State, StatesGroup
from aiogram.filters import BaseFilter
from aiogram.fsm.state import State, StatesGroup
from aiogram.types import TelegramObject
StateType = Union[str, None, State, StatesGroup, Type[StatesGroup]]

View file

@ -2,7 +2,7 @@ from typing import TYPE_CHECKING, Any, Dict, Optional, Sequence, Union
from pydantic import root_validator
from aiogram.dispatcher.filters import BaseFilter
from aiogram.filters import BaseFilter
from aiogram.types import CallbackQuery, InlineQuery, Message, Poll
if TYPE_CHECKING:

View file

@ -1,7 +1,7 @@
from typing import Any, Dict, Optional
from aiogram import Bot
from aiogram.dispatcher.fsm.storage.base import BaseStorage, StateType, StorageKey
from aiogram.fsm.storage.base import BaseStorage, StateType, StorageKey
class FSMContext:

View file

@ -1,15 +1,10 @@
from typing import Any, Awaitable, Callable, Dict, Optional, cast
from aiogram import Bot
from aiogram.dispatcher.fsm.context import FSMContext
from aiogram.dispatcher.fsm.storage.base import (
DEFAULT_DESTINY,
BaseEventIsolation,
BaseStorage,
StorageKey,
)
from aiogram.dispatcher.fsm.strategy import FSMStrategy, apply_strategy
from aiogram.dispatcher.middlewares.base import BaseMiddleware
from aiogram.fsm.context import FSMContext
from aiogram.fsm.storage.base import DEFAULT_DESTINY, BaseEventIsolation, BaseStorage, StorageKey
from aiogram.fsm.strategy import FSMStrategy, apply_strategy
from aiogram.types import TelegramObject

View file

@ -1,7 +1,7 @@
import inspect
from typing import Any, Iterator, Optional, Tuple, Type, no_type_check
from ...types import TelegramObject
from aiogram.types import TelegramObject
class State:

View file

@ -4,7 +4,7 @@ from dataclasses import dataclass
from typing import Any, AsyncGenerator, Dict, Optional, Union
from aiogram import Bot
from aiogram.dispatcher.fsm.state import State
from aiogram.fsm.state import State
StateType = Optional[Union[str, State]]

View file

@ -5,13 +5,8 @@ from dataclasses import dataclass, field
from typing import Any, AsyncGenerator, DefaultDict, Dict, Hashable, Optional
from aiogram import Bot
from aiogram.dispatcher.fsm.state import State
from aiogram.dispatcher.fsm.storage.base import (
BaseEventIsolation,
BaseStorage,
StateType,
StorageKey,
)
from aiogram.fsm.state import State
from aiogram.fsm.storage.base import BaseEventIsolation, BaseStorage, StateType, StorageKey
@dataclass

View file

@ -8,8 +8,8 @@ from redis.asyncio.lock import Lock
from redis.typing import ExpiryT
from aiogram import Bot
from aiogram.dispatcher.fsm.state import State
from aiogram.dispatcher.fsm.storage.base import (
from aiogram.fsm.state import State
from aiogram.fsm.storage.base import (
DEFAULT_DESTINY,
BaseEventIsolation,
BaseStorage,

View file

@ -1,9 +1,13 @@
from __future__ import annotations
from abc import ABC, abstractmethod
from typing import TYPE_CHECKING, Any, Dict, Generic, TypeVar, cast
from aiogram import Bot
from aiogram.types import Update
if TYPE_CHECKING:
from aiogram import Bot
T = TypeVar("T")
@ -24,6 +28,8 @@ class BaseHandler(BaseHandlerMixin[T], ABC):
@property
def bot(self) -> Bot:
from aiogram import Bot
if "bot" in self.data:
return cast(Bot, self.data["bot"])
return Bot.get_current(no_error=False)

View file

@ -1,7 +1,7 @@
from abc import ABC
from typing import Optional
from aiogram.dispatcher.handler import BaseHandler
from aiogram.handlers import BaseHandler
from aiogram.types import CallbackQuery, Message, User

View file

@ -1,6 +1,6 @@
from abc import ABC
from aiogram.dispatcher.handler import BaseHandler
from aiogram.handlers import BaseHandler
from aiogram.types import ChatMemberUpdated, User

View file

@ -1,6 +1,6 @@
from abc import ABC
from aiogram.dispatcher.handler import BaseHandler
from aiogram.handlers import BaseHandler
from aiogram.types import ChosenInlineResult, User

View file

@ -1,6 +1,6 @@
from abc import ABC
from aiogram.dispatcher.handler.base import BaseHandler
from aiogram.handlers.base import BaseHandler
class ErrorHandler(BaseHandler[Exception], ABC):

View file

@ -1,6 +1,6 @@
from abc import ABC
from aiogram.dispatcher.handler import BaseHandler
from aiogram.handlers import BaseHandler
from aiogram.types import InlineQuery, User

View file

@ -1,8 +1,8 @@
from abc import ABC
from typing import Optional, cast
from aiogram.dispatcher.filters import CommandObject
from aiogram.dispatcher.handler.base import BaseHandler, BaseHandlerMixin
from aiogram.filters import CommandObject
from aiogram.handlers.base import BaseHandler, BaseHandlerMixin
from aiogram.types import Chat, Message, User

View file

@ -1,7 +1,7 @@
from abc import ABC
from typing import List
from aiogram.dispatcher.handler import BaseHandler
from aiogram.handlers import BaseHandler
from aiogram.types import Poll, PollOption

View file

@ -1,6 +1,6 @@
from abc import ABC
from aiogram.dispatcher.handler import BaseHandler
from aiogram.handlers import BaseHandler
from aiogram.types import PreCheckoutQuery, User

View file

@ -1,6 +1,6 @@
from abc import ABC
from aiogram.dispatcher.handler import BaseHandler
from aiogram.handlers import BaseHandler
from aiogram.types import ShippingQuery, User

View file

@ -7,7 +7,7 @@ from types import TracebackType
from typing import Any, Awaitable, Callable, Dict, Optional, Type, Union
from aiogram import BaseMiddleware, Bot
from aiogram.dispatcher.flags.getter import get_flag
from aiogram.dispatcher.flags import get_flag
from aiogram.types import Message, TelegramObject
logger = logging.getLogger(__name__)

View file

@ -42,13 +42,17 @@ Decode it back example:
await message.answer(f"Your payload: {payload}")
"""
from __future__ import annotations
import re
from base64 import urlsafe_b64decode, urlsafe_b64encode
from typing import Literal, cast
from typing import TYPE_CHECKING, Literal, cast
from aiogram import Bot
from aiogram.utils.link import create_telegram_link
if TYPE_CHECKING:
from aiogram import Bot
BAD_PATTERN = re.compile(r"[^_A-z0-9-]")

View file

@ -11,7 +11,7 @@ except ImportError: # pragma: no cover
from aiogram import BaseMiddleware, Router
from aiogram.dispatcher.fsm.context import FSMContext
from aiogram.fsm.context import FSMContext
from aiogram.types import TelegramObject, User
from aiogram.utils.i18n.core import I18n

View file

@ -17,7 +17,7 @@ from typing import (
no_type_check,
)
from aiogram.dispatcher.filters.callback_data import CallbackData
from aiogram.filters.callback_data import CallbackData
from aiogram.types import (
CallbackGame,
InlineKeyboardButton,

View file

@ -14,6 +14,8 @@ __all__ = (
"TextDecoration",
"html_decoration",
"markdown_decoration",
"add_surrogates",
"remove_surrogates",
)

View file

@ -117,7 +117,7 @@ def safe_parse_webapp_init_data(
"""
Validate raw WebApp init data and return it as WebAppInitData object
Raise :type:`ValueError` when data is invalid
Raise :obj:`ValueError` when data is invalid
:param token: bot token
:param init_data: data from frontend to be parsed and validated

View file

@ -9,8 +9,8 @@ from aiohttp.typedefs import Handler
from aiohttp.web_middlewares import middleware
from aiogram import Bot, Dispatcher, loggers
from aiogram.dispatcher.webhook.security import IPFilter
from aiogram.methods import TelegramMethod
from aiogram.webhook.security import IPFilter
def setup_application(app: Application, dispatcher: Dispatcher, /, **kwargs: Any) -> None: