Merge pull request #83 from rominf/dev-2.x

Add aiogram.utils.executor.set_webhook
This commit is contained in:
Alex Root Junior 2018-11-25 18:08:29 +02:00 committed by GitHub
commit 3aeb338d40
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 78 additions and 18 deletions

View file

@ -21,6 +21,7 @@ from ..utils.exceptions import TimeoutWarning
from ..utils.payload import prepare_arg from ..utils.payload import prepare_arg
DEFAULT_WEB_PATH = '/webhook' DEFAULT_WEB_PATH = '/webhook'
DEFAULT_ROUTE_NAME = 'webhook_handler'
BOT_DISPATCHER_KEY = 'BOT_DISPATCHER' BOT_DISPATCHER_KEY = 'BOT_DISPATCHER'
RESPONSE_TIMEOUT = 55 RESPONSE_TIMEOUT = 55
@ -266,16 +267,17 @@ class GoneRequestHandler(web.View):
raise HTTPGone() raise HTTPGone()
def configure_app(dispatcher, app: web.Application, path=DEFAULT_WEB_PATH): def configure_app(dispatcher, app: web.Application, path=DEFAULT_WEB_PATH, route_name=DEFAULT_ROUTE_NAME):
""" """
You can prepare web.Application for working with webhook handler. You can prepare web.Application for working with webhook handler.
:param dispatcher: Dispatcher instance :param dispatcher: Dispatcher instance
:param app: :class:`aiohttp.web.Application` :param app: :class:`aiohttp.web.Application`
:param path: Path to your webhook. :param path: Path to your webhook.
:param route_name: Name of webhook handler route
:return: :return:
""" """
app.router.add_route('*', path, WebhookRequestHandler, name='webhook_handler') app.router.add_route('*', path, WebhookRequestHandler, name=route_name)
app[BOT_DISPATCHER_KEY] = dispatcher app[BOT_DISPATCHER_KEY] = dispatcher

View file

@ -2,12 +2,15 @@ import asyncio
import datetime import datetime
import functools import functools
import secrets import secrets
from typing import Callable, Union, Optional, Any
from warnings import warn from warnings import warn
from aiohttp import web from aiohttp import web
from aiohttp.web_app import Application
from ..bot.api import log from ..bot.api import log
from ..dispatcher.webhook import BOT_DISPATCHER_KEY, WebhookRequestHandler from ..dispatcher.dispatcher import Dispatcher
from ..dispatcher.webhook import BOT_DISPATCHER_KEY, DEFAULT_ROUTE_NAME, WebhookRequestHandler
APP_EXECUTOR_KEY = 'APP_EXECUTOR' APP_EXECUTOR_KEY = 'APP_EXECUTOR'
@ -38,8 +41,37 @@ def start_polling(dispatcher, *, loop=None, skip_updates=False, reset_webhook=Tr
executor.start_polling(reset_webhook=reset_webhook, timeout=timeout, fast=fast) executor.start_polling(reset_webhook=reset_webhook, timeout=timeout, fast=fast)
def set_webhook(dispatcher: Dispatcher, webhook_path: str, *, loop: Optional[asyncio.AbstractEventLoop] = None,
skip_updates: bool = None, on_startup: Optional[Callable] = None,
on_shutdown: Optional[Callable] = None, check_ip: bool = False,
retry_after: Optional[Union[str, int]] = None, route_name: str = DEFAULT_ROUTE_NAME,
web_app: Optional[Application] = None):
"""
Set webhook for bot
:param dispatcher: Dispatcher
:param webhook_path: str
:param loop: Optional[asyncio.AbstractEventLoop] (default: None)
:param skip_updates: bool (default: None)
:param on_startup: Optional[Callable] (default: None)
:param on_shutdown: Optional[Callable] (default: None)
:param check_ip: bool (default: False)
:param retry_after: Optional[Union[str, int]] See https://tools.ietf.org/html/rfc7231#section-7.1.3 (default: None)
:param route_name: str (default: 'webhook_handler')
:param web_app: Optional[Application] (default: None)
:return:
"""
executor = Executor(dispatcher, skip_updates=skip_updates, check_ip=check_ip, retry_after=retry_after,
loop=loop)
_setup_callbacks(executor, on_startup, on_shutdown)
executor.set_webhook(webhook_path, route_name=route_name, web_app=web_app)
return executor
def start_webhook(dispatcher, webhook_path, *, loop=None, skip_updates=None, def start_webhook(dispatcher, webhook_path, *, loop=None, skip_updates=None,
on_startup=None, on_shutdown=None, check_ip=False, retry_after=None, **kwargs): on_startup=None, on_shutdown=None, check_ip=False, retry_after=None, route_name=DEFAULT_ROUTE_NAME,
**kwargs):
""" """
Start bot in webhook mode Start bot in webhook mode
@ -50,14 +82,20 @@ def start_webhook(dispatcher, webhook_path, *, loop=None, skip_updates=None,
:param on_startup: :param on_startup:
:param on_shutdown: :param on_shutdown:
:param check_ip: :param check_ip:
:param route_name:
:param kwargs: :param kwargs:
:return: :return:
""" """
executor = Executor(dispatcher, skip_updates=skip_updates, check_ip=check_ip, retry_after=retry_after, executor = set_webhook(dispatcher=dispatcher,
loop=loop) webhook_path=webhook_path,
_setup_callbacks(executor, on_startup, on_shutdown) loop=loop,
skip_updates=skip_updates,
executor.start_webhook(webhook_path, **kwargs) on_startup=on_startup,
on_shutdown=on_shutdown,
check_ip=check_ip,
retry_after=retry_after,
route_name=route_name)
executor.run_app(**kwargs)
def start(dispatcher, future, *, loop=None, skip_updates=None, def start(dispatcher, future, *, loop=None, skip_updates=None,
@ -181,15 +219,18 @@ class Executor:
# self.loop.set_task_factory(context.task_factory) # self.loop.set_task_factory(context.task_factory)
def _prepare_webhook(self, path=None, handler=WebhookRequestHandler): def _prepare_webhook(self, path=None, handler=WebhookRequestHandler, route_name=DEFAULT_ROUTE_NAME, app=None):
self._check_frozen() self._check_frozen()
self._freeze = True self._freeze = True
# self.loop.set_task_factory(context.task_factory) # self.loop.set_task_factory(context.task_factory)
app = self._web_app if app is not None:
if app is None: self._web_app = app
elif self._web_app is None:
self._web_app = app = web.Application() self._web_app = app = web.Application()
else:
raise RuntimeError("web.Application() is already configured!")
if self.retry_after: if self.retry_after:
app['RETRY_AFTER'] = self.retry_after app['RETRY_AFTER'] = self.retry_after
@ -199,7 +240,7 @@ class Executor:
return return
if path is not None: if path is not None:
app.router.add_route('*', path, handler, name='webhook_handler') app.router.add_route('*', path, handler, name=route_name)
async def _wrap_callback(cb, _): async def _wrap_callback(cb, _):
return await cb(self.dispatcher) return await cb(self.dispatcher)
@ -219,19 +260,36 @@ class Executor:
app[self._identity] = datetime.datetime.now() app[self._identity] = datetime.datetime.now()
app['_check_ip'] = self.check_ip app['_check_ip'] = self.check_ip
def start_webhook(self, webhook_path=None, request_handler=WebhookRequestHandler, **kwargs): def set_webhook(self, webhook_path: Optional[str] = None, request_handler: Any = WebhookRequestHandler,
route_name: str = DEFAULT_ROUTE_NAME, web_app: Optional[Application] = None):
"""
Set webhook for bot
:param webhook_path: Optional[str] (default: None)
:param request_handler: Any (default: WebhookRequestHandler)
:param route_name: str Name of webhook handler route (default: 'webhook_handler')
:param web_app: Optional[Application] (default: None)
:return:
"""
self._prepare_webhook(webhook_path, request_handler, route_name, web_app)
self.loop.run_until_complete(self._startup_webhook())
def run_app(self, **kwargs):
web.run_app(self._web_app, **kwargs)
def start_webhook(self, webhook_path=None, request_handler=WebhookRequestHandler, route_name=DEFAULT_ROUTE_NAME,
**kwargs):
""" """
Start bot in webhook mode Start bot in webhook mode
:param webhook_path: :param webhook_path:
:param request_handler: :param request_handler:
:param route_name: Name of webhook handler route
:param kwargs: :param kwargs:
:return: :return:
""" """
self._prepare_webhook(webhook_path, request_handler) self.set_webhook(webhook_path=webhook_path, request_handler=request_handler, route_name=route_name, **kwargs)
self.loop.run_until_complete(self._startup_webhook()) self.run_app(**kwargs)
web.run_app(self._web_app, **kwargs)
def start_polling(self, reset_webhook=None, timeout=None, fast=True): def start_polling(self, reset_webhook=None, timeout=None, fast=True):
""" """