Try to use contextvars (partial)

This commit is contained in:
Alex Root Junior 2018-06-23 17:39:24 +03:00
parent c88ee7ed52
commit 8086a120c2
7 changed files with 54 additions and 7 deletions

View file

@ -1,4 +1,7 @@
from __future__ import annotations
import typing
from contextvars import ContextVar
from .base import BaseBot, api
from .. import types
@ -30,6 +33,14 @@ class Bot(BaseBot):
if hasattr(self, '_me'):
delattr(self, '_me')
@classmethod
def current(cls) -> Bot:
"""
Return active bot instance from the current context or None
:return: Bot or None
"""
return bot.get()
async def download_file_by_id(self, file_id: base.String, destination=None,
timeout: base.Integer = 30, chunk_size: base.Integer = 65536,
seek: base.Boolean = True):
@ -1863,3 +1874,6 @@ class Bot(BaseBot):
result = await self.request(api.Methods.GET_GAME_HIGH_SCORES, payload)
return [types.GameHighScore(**gamehighscore) for gamehighscore in result]
bot: ContextVar[Bot] = ContextVar('bot_instance', default=None)

View file

@ -4,7 +4,9 @@ import itertools
import logging
import time
import typing
from contextvars import ContextVar
from aiogram import types
from .filters import CommandsFilter, ContentTypeFilter, ExceptionsFilter, RegexpFilter, \
USER_STATE, generate_default_filters
from .handler import CancelHandler, Handler, SkipHandler
@ -15,7 +17,7 @@ from .webhook import BaseResponse
from ..bot import Bot
from ..types.message import ContentType
from ..utils import context
from ..utils.exceptions import NetworkError, TelegramAPIError, Throttled
from ..utils.exceptions import TelegramAPIError, Throttled
log = logging.getLogger(__name__)
@ -89,6 +91,10 @@ class Dispatcher:
def get(self, key, default=None):
return self.bot.data.get(key, default)
@classmethod
def current(cls):
return dispatcher.get()
async def skip_updates(self):
"""
You can skip old incoming updates from queue.
@ -127,6 +133,8 @@ class Dispatcher:
"""
self.last_update_id = update.update_id
context.set_value(UPDATE_OBJECT, update)
types.Update.set_current(update)
try:
if update.message:
state = await self.storage.get_state(chat=update.message.chat.id,
@ -1054,3 +1062,6 @@ class Dispatcher:
if run_task:
return self.async_task(callback)
return callback
dispatcher: ContextVar[Dispatcher] = ContextVar('dispatcher_instance', default=None)

View file

@ -137,8 +137,8 @@ class TelegramObject(metaclass=MetaTelegramObject):
@property
def bot(self):
from ..dispatcher import ctx
return ctx.get_bot()
from ..bot.bot import Bot
return Bot.current()
def to_python(self) -> typing.Dict:
"""

View file

@ -1,3 +1,5 @@
from __future__ import annotations
import datetime
import functools
import typing
@ -38,7 +40,7 @@ class Message(base.TelegramObject):
forward_from_message_id: base.Integer = fields.Field()
forward_signature: base.String = fields.Field()
forward_date: base.Integer = fields.Field()
reply_to_message: 'Message' = fields.Field(base='Message')
reply_to_message: Message = fields.Field(base='Message')
edit_date: base.Integer = fields.Field()
media_group_id: base.String = fields.Field()
author_signature: base.String = fields.Field()

View file

@ -1,3 +1,7 @@
from __future__ import annotations
from contextvars import ContextVar
from . import base
from . import fields
from .callback_query import CallbackQuery
@ -8,6 +12,8 @@ from .pre_checkout_query import PreCheckoutQuery
from .shipping_query import ShippingQuery
from ..utils import helper
current_update: ContextVar[Update] = ContextVar('current_update_object', default=None)
class Update(base.TelegramObject):
"""
@ -27,6 +33,14 @@ class Update(base.TelegramObject):
shipping_query: ShippingQuery = fields.Field(base=ShippingQuery)
pre_checkout_query: PreCheckoutQuery = fields.Field(base=PreCheckoutQuery)
@classmethod
def current(cls):
return current_update.get()
@classmethod
def set_current(cls, update: Update):
return current_update.set(update)
def __hash__(self):
return self.update_id

View file

@ -102,6 +102,11 @@ class Executor:
self._freeze = False
from aiogram.bot.bot import bot as ctx_bot
from aiogram.dispatcher import dispatcher as ctx_dp
ctx_bot.set(dispatcher.bot)
ctx_dp.set(dispatcher)
@property
def frozen(self):
return self._freeze
@ -198,6 +203,7 @@ class Executor:
for callback in self._on_startup_webhook:
app.on_startup.append(functools.partial(_wrap_callback, callback))
# for callback in self._on_shutdown_webhook:
# app.on_shutdown.append(functools.partial(_wrap_callback, callback))

View file

@ -13,7 +13,7 @@ except ImportError: # pip >= 10.0.0
WORK_DIR = pathlib.Path(__file__).parent
# Check python version
MINIMAL_PY_VERSION = (3, 6)
MINIMAL_PY_VERSION = (3, 7)
if sys.version_info < MINIMAL_PY_VERSION:
raise RuntimeError('aiogram works only with Python {}+'.format('.'.join(map(str, MINIMAL_PY_VERSION))))
@ -65,7 +65,7 @@ setup(
url='https://github.com/aiogram/aiogram',
license='MIT',
author='Alex Root Junior',
requires_python='>=3.6',
requires_python='>=3.7',
author_email='aiogram@illemius.xyz',
description='Is a pretty simple and fully asynchronous library for Telegram Bot API',
long_description=get_description(),
@ -76,7 +76,7 @@ setup(
'Intended Audience :: Developers',
'Intended Audience :: System Administrators',
'License :: OSI Approved :: MIT License',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Topic :: Software Development :: Libraries :: Application Frameworks',
],
install_requires=get_requirements()