hass-core/homeassistant/components/telegram_bot/polling.py
Jim d2effd8693
Bump python-telegram-bot package to 21.0.1 (#110297)
* Bump python-telegram-bot package version to the latest.

* PySocks is no longer required as python-telegram-bot doesn't use urllib3 anymore.

* Fix moved ParseMode import

* Update filters import to new structure.

* Refactor removed Request objects to HTTPXRequest objects.

* Update to support asyncc functions

* Update timeout to new kwarg

connect_timeout is the most obvious option based on current param description, but this may need changing.

* Compatibility typo.

* Make methods async and use Bot client async natively

* Type needs to be Optional

That's what the source types are from the library
Also handle new possibility of None value

* Add socks support version of the library

* Refactor load_data function

Update to be async friendly
Refactor to use httpx instead of requests.

* Refactor Dispatcher references to Application

This is the newer model of the same class.

* Make more stuff async-friendly.

* Update tests to refactor Dispatcher usage out.

* Remove import and reference directly

* Refactor typing method

* Use async_fire now we have async support

* Fix some over complicate inheritance.

* Add the polling test telegram_text event fired back in.

* Add extra context to comment

* Handler should also be async

* Use underscores instead of camelCase

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

* Renamed kwarg.

* Refactor current timeout param to be read timeout

Reading the old version of the library code I believe this matches the existing functionality best

* Combine unload methods into one listener

* Fix test by stopping HA as part of fixture

* Add new fixture to mock stop_polling call

Use this in all polling tests.

* No longer need to check if application is running

It was to stop a test failing.

* Make sure the updater is started in tests

Mock external call methods
Remove stop_polling mock.

* Use cleaner references to patched methods

* Improve test by letting the library create the Update object

* Mock component tear down methods to be async

* Bump mypy cache version

* Update dependency to install from git

Allows use as a custom component in 2024.3
Allows us to track mypy issue resolution.

* Update manifest and requirements for new python-telegram-bot release.

* Remove pytest filterwarnings entry for old version of python-telegram-bot library.

---------

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2024-03-08 08:56:26 +01:00

63 lines
2.2 KiB
Python

"""Support for Telegram bot using polling."""
import logging
from telegram import Update
from telegram.error import NetworkError, RetryAfter, TelegramError, TimedOut
from telegram.ext import ApplicationBuilder, CallbackContext, TypeHandler
from homeassistant.const import EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP
from . import BaseTelegramBotEntity
_LOGGER = logging.getLogger(__name__)
async def async_setup_platform(hass, bot, config):
"""Set up the Telegram polling platform."""
pollbot = PollBot(hass, bot, config)
hass.bus.async_listen_once(EVENT_HOMEASSISTANT_START, pollbot.start_polling)
hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, pollbot.stop_polling)
return True
async def process_error(update: Update, context: CallbackContext) -> None:
"""Telegram bot error handler."""
try:
if context.error:
raise context.error
except (TimedOut, NetworkError, RetryAfter):
# Long polling timeout or connection problem. Nothing serious.
pass
except TelegramError:
_LOGGER.error('Update "%s" caused error: "%s"', update, context.error)
class PollBot(BaseTelegramBotEntity):
"""Controls the Application object that holds the bot and an updater.
The application is set up to pass telegram updates to `self.handle_update`
"""
def __init__(self, hass, bot, config):
"""Create Application to poll for updates."""
super().__init__(hass, config)
self.bot = bot
self.application = ApplicationBuilder().bot(self.bot).build()
self.application.add_handler(TypeHandler(Update, self.handle_update))
self.application.add_error_handler(process_error)
async def start_polling(self, event=None):
"""Start the polling task."""
_LOGGER.debug("Starting polling")
await self.application.initialize()
await self.application.updater.start_polling()
await self.application.start()
async def stop_polling(self, event=None):
"""Stop the polling task."""
_LOGGER.debug("Stopping polling")
await self.application.updater.stop()
await self.application.stop()
await self.application.shutdown()