Polling updates#
API internals#
- glQiwiApi.core.event_fetching.executor.start_polling(wallet: Union[glQiwiApi.qiwi.clients.wallet.client.QiwiWallet, glQiwiApi.qiwi.clients.wrapper.QiwiWrapper], dispatcher: glQiwiApi.core.event_fetching.dispatcher.BaseDispatcher, *plugins: glQiwiApi.plugins.abc.Pluggable, skip_updates: bool = False, timeout_in_seconds: float = 5, on_startup: Optional[Callable[[Context], Union[None, Awaitable[None]]]] = None, on_shutdown: Optional[Callable[[Context], Union[None, Awaitable[None]]]] = None, loop: Optional[asyncio.events.AbstractEventLoop] = None, context: Optional[Union[Dict[str, Any], glQiwiApi.core.event_fetching.executor.Context]] = None) None [source]#
Setup for long-polling mode. Support only glQiwiApi.types.Transaction as event.
- Parameters
wallet – instance of QiwiWrapper
dispatcher –
skip_updates –
timeout_in_seconds – timeout of polling in seconds, if the timeout is too small, the API can throw an exception
on_startup – function or coroutine, which will be executed on startup
on_shutdown – function or coroutine, which will be executed on shutdown
plugins – List of plugins, that will be executed together with polling. For example builtin TelegramPollingPlugin or other class, that implement Pluggable abc interface, deal with foreign framework/application in the background
loop –
context – context, that could be transmitted to handlers
- async glQiwiApi.core.event_fetching.executor.start_non_blocking_qiwi_api_polling(wallet: Union[glQiwiApi.qiwi.clients.wallet.client.QiwiWallet, glQiwiApi.qiwi.clients.wrapper.QiwiWrapper], dispatcher: glQiwiApi.core.event_fetching.dispatcher.BaseDispatcher, skip_updates: bool = False, timeout_in_seconds: float = 5, on_startup: Optional[Callable[[Context], Union[None, Awaitable[None]]]] = None, on_shutdown: Optional[Callable[[Context], Union[None, Awaitable[None]]]] = None, loop: Optional[asyncio.events.AbstractEventLoop] = None, context: Optional[Union[Dict[str, Any], glQiwiApi.core.event_fetching.executor.Context]] = None) _asyncio.Task [source]#
- glQiwiApi.core.event_fetching.executor.configure_app_for_qiwi_webhooks(wallet: Union[glQiwiApi.qiwi.clients.wallet.client.QiwiWallet, glQiwiApi.qiwi.clients.wrapper.QiwiWrapper], dispatcher: glQiwiApi.core.event_fetching.dispatcher.BaseDispatcher, app: aiohttp.web_app.Application, cfg: glQiwiApi.core.event_fetching.webhooks.config.WebhookConfig) aiohttp.web_app.Application [source]#
- class glQiwiApi.core.event_fetching.executor.BaseExecutor(dispatcher: glQiwiApi.core.event_fetching.dispatcher.BaseDispatcher, *plugins: glQiwiApi.plugins.abc.Pluggable, context: glQiwiApi.core.event_fetching.executor.Context, loop: Optional[asyncio.events.AbstractEventLoop] = None, on_startup: Optional[Callable[[...], Any]] = None, on_shutdown: Optional[Callable[[...], Any]] = None)[source]#
Bases:
abc.ABC
- __init__(dispatcher: glQiwiApi.core.event_fetching.dispatcher.BaseDispatcher, *plugins: glQiwiApi.plugins.abc.Pluggable, context: glQiwiApi.core.event_fetching.executor.Context, loop: Optional[asyncio.events.AbstractEventLoop] = None, on_startup: Optional[Callable[[...], Any]] = None, on_shutdown: Optional[Callable[[...], Any]] = None) None [source]#
- property loop: asyncio.events.AbstractEventLoop#
- class glQiwiApi.core.event_fetching.executor.PollingExecutor(wallet: Union[glQiwiApi.qiwi.clients.wallet.client.QiwiWallet, glQiwiApi.qiwi.clients.wrapper.QiwiWrapper], dispatcher: glQiwiApi.core.event_fetching.dispatcher.BaseDispatcher, *plugins: glQiwiApi.plugins.abc.Pluggable, context: glQiwiApi.core.event_fetching.executor.Context, loop: Optional[asyncio.events.AbstractEventLoop] = None, timeout: Union[float, int] = 5, skip_updates: bool = False, on_startup: Optional[Callable[[Context], Union[None, Awaitable[None]]]] = None, on_shutdown: Optional[Callable[[Context], Union[None, Awaitable[None]]]] = None)[source]#
Bases:
glQiwiApi.core.event_fetching.executor.BaseExecutor
- __init__(wallet: Union[glQiwiApi.qiwi.clients.wallet.client.QiwiWallet, glQiwiApi.qiwi.clients.wrapper.QiwiWrapper], dispatcher: glQiwiApi.core.event_fetching.dispatcher.BaseDispatcher, *plugins: glQiwiApi.plugins.abc.Pluggable, context: glQiwiApi.core.event_fetching.executor.Context, loop: Optional[asyncio.events.AbstractEventLoop] = None, timeout: Union[float, int] = 5, skip_updates: bool = False, on_startup: Optional[Callable[[Context], Union[None, Awaitable[None]]]] = None, on_shutdown: Optional[Callable[[Context], Union[None, Awaitable[None]]]] = None) None [source]#
Guidelines#
This section explains how to properly poll transactions from QIWI API.
You can’t help registering handlers and start polling, so in example above it is shown how to do it rightly. Lets do it with decorators:
️So, we also have to import executor
and pass on our client,
that contains functions start_polling
and start_webhook
.
from glQiwiApi import QiwiWallet
from glQiwiApi.core.event_fetching import executor
from glQiwiApi.core.event_fetching.dispatcher import QiwiDispatcher
from glQiwiApi.core.event_fetching.executor import Context
from glQiwiApi.core.event_fetching.filters import ExceptionFilter
from glQiwiApi.qiwi.clients.wallet.types import Transaction
from glQiwiApi.qiwi.exceptions import QiwiAPIError
qiwi_dp = QiwiDispatcher()
wallet = QiwiWallet(api_access_token='token', phone_number='+phone number')
@qiwi_dp.transaction_handler()
async def handle_transaction(t: Transaction, ctx: Context):
"""Handle transaction here"""
ctx.wallet # this way you can use QiwiWallet instance to avoid global variables
@qiwi_dp.exception_handler(ExceptionFilter(QiwiAPIError))
async def handle_exception(err: QiwiAPIError, ctx: Context):
pass
if __name__ == '__main__':
executor.start_polling(wallet, qiwi_dp)
Events#
Then, you can start polling, but, let’s make it clear which arguments you should pass on to start_polling
function.
You can also specify events like on_shutdown
or on_startup
.
As you can see, in the example we have a function that we pass as an argument to on_startup
.
As you may have guessed, this function will be executed at the beginning of the polling.
from glQiwiApi import QiwiWallet
from glQiwiApi.core.event_fetching import executor
from glQiwiApi.core.event_fetching.dispatcher import QiwiDispatcher
from glQiwiApi.core.event_fetching.executor import Context
from glQiwiApi.qiwi.clients.wallet.types import Transaction
qiwi_dp = QiwiDispatcher()
wallet = QiwiWallet(api_access_token='token', phone_number='+phone number')
@qiwi_dp.transaction_handler()
async def handle_transaction(t: Transaction, ctx: Context):
"""Handle transaction here"""
ctx.wallet # this way you can use QiwiWallet instance to avoid global variables
async def on_startup(ctx: Context):
ctx.wallet # do something here
async def on_shutdown(ctx: Context):
pass
if __name__ == '__main__':
executor.start_polling(wallet, qiwi_dp, on_startup=on_startup, on_shutdown=on_shutdown)
Make aiogram work with glQiwiApi#
Also, you can very easily implement simultaneous polling of updates from both aiogram and QIWI API.
In the example below, we catch all text messages and return the same “Hello” response.
from aiogram import Bot, Dispatcher
from aiogram.types import Message
from glQiwiApi import QiwiWallet
from glQiwiApi.core.event_fetching import executor
from glQiwiApi.core.event_fetching.dispatcher import QiwiDispatcher
from glQiwiApi.core.event_fetching.executor import Context
from glQiwiApi.plugins import AiogramPollingPlugin
from glQiwiApi.qiwi.clients.wallet.types import Transaction
qiwi_dp = QiwiDispatcher()
wallet = QiwiWallet(api_access_token='token', phone_number='+phone number')
dp = Dispatcher(Bot('BOT TOKEN'))
@qiwi_dp.transaction_handler()
async def handle_transaction(t: Transaction, ctx: Context):
"""Handle transaction here"""
ctx.wallet # this way you can use QiwiWallet instance to avoid global variables
@dp.message_handler()
async def handle_message(msg: Message):
await msg.answer(text='Hello world')
if __name__ == '__main__':
executor.start_polling(wallet, qiwi_dp, AiogramPollingPlugin(dp))
Alternatively you can run polling at on_startup
event
from aiogram import Bot, Dispatcher
from aiogram.types import Message
from aiogram.utils import executor
from glQiwiApi import QiwiWallet
from glQiwiApi.core.event_fetching.dispatcher import QiwiDispatcher
from glQiwiApi.core.event_fetching.executor import Context, start_non_blocking_qiwi_api_polling
from glQiwiApi.qiwi.clients.wallet.types import Transaction
qiwi_dp = QiwiDispatcher()
wallet = QiwiWallet(api_access_token='token', phone_number='+phone number')
dp = Dispatcher(Bot('BOT TOKEN'))
@qiwi_dp.transaction_handler()
async def handle_transaction(t: Transaction, ctx: Context):
"""Handle transaction here"""
@dp.message_handler()
async def handle_message(msg: Message):
await msg.answer(text='Hello world')
async def on_startup(dp: Dispatcher):
await start_non_blocking_qiwi_api_polling(wallet, qiwi_dp)
if __name__ == '__main__':
executor.start_polling(dp, on_startup=on_startup)
Example usage without global variables#
import logging
from typing import cast
from aiogram import Bot, Dispatcher, types
from glQiwiApi import QiwiWrapper
from glQiwiApi.core.event_fetching import executor
from glQiwiApi.core.event_fetching.dispatcher import QiwiDispatcher
from glQiwiApi.core.event_fetching.executor import Context
from glQiwiApi.plugins import AiogramPollingPlugin
from glQiwiApi.qiwi.clients.wallet.types import Transaction
api_access_token = 'token'
phone_number = '+phone number'
logger = logging.getLogger(__name__)
async def aiogram_message_handler(msg: types.Message):
await msg.answer(text='Привет😇')
async def qiwi_transaction_handler(update: Transaction, ctx: Context):
print(update)
def on_startup(ctx: Context) -> None:
logger.info('This message logged on startup')
register_handlers(ctx)
def register_handlers(ctx: Context):
ctx['qiwi_dp'].transaction_handler()(qiwi_transaction_handler)
dispatcher = cast(Dispatcher, ctx['dp'])
dispatcher.register_message_handler(aiogram_message_handler)
def run_application() -> None:
logging.basicConfig(level=logging.INFO)
bot = Bot('BOT TOKEN')
dp = Dispatcher(bot)
wallet = QiwiWrapper(api_access_token=api_access_token, phone_number=phone_number)
qiwi_dp = QiwiDispatcher()
executor.start_polling(
wallet,
qiwi_dp,
AiogramPollingPlugin(dp),
on_startup=on_startup,
skip_updates=True,
context={'dp': dp, 'qiwi_dp': qiwi_dp},
)
if __name__ == '__main__':
run_application()