telebot_py.plugins

Plugin system: hooks, ordering, namespaced state, and i18n (US3).

telebot_py.plugins.i18n

Built-in internationalization plugin (T045).

Parity with packages/node/src/plugins/i18n.ts: per-update locale resolution (stored preference in context.user_data, then the sender’s Telegram language_code, then the default locale), missing-key fallback to the default locale table and finally the key itself, and {placeholder} interpolation. The per-user preference lives in user_data and therefore rides on persistence automatically.

class telebot_py.plugins.i18n.I18nPlugin(*, default_locale: str, locales: Mapping[str, Mapping[str, str]], locale_key: str = '_telebot_locale', name: str = 'telebot-plugin-i18n')

Bases: Plugin

Internationalization plugin: locale tables plus per-user preference.

The kernel integration pass can attach a session per update via session_for(); bot handlers translate through the session’s I18nSession.t().

Example

>>> plugin = I18nPlugin(
...     default_locale="en",
...     locales={"en": {"hello": "Hello, {name}!"}},
... )
>>> session = plugin.session_for(context)
>>> await context.bot.send_message(chat_id, session.t("hello", {"name": "Nam"}))
Variables:
  • default_locale – Locale used when the user’s preferred locale has no translation table.

  • locales – Translation tables keyed by locale code, then message key.

  • locale_key – Key inside context.user_data storing the preference.

depends_on: Sequence[str] = ()
session_for(context: CallbackContext) → I18nSession

Resolve the locale for an update and open a translation session.

Resolution order (node parity): stored preference in user_data, then the sender’s language_code, then default_locale; a preferred locale without a translation table falls back to the default.

Parameters:

context – The callback context of the current update.

Returns:

A session bound to the resolved locale.

translate(locale: str, key: str, params: Mapping[str, str | int] | None = None) → str

Translate a key for an explicit locale.

Parameters:
  • locale – Locale code to look up first.

  • key – Message key in the translation tables.

  • params – Optional placeholder values.

Returns:

The translated string; falls back to the default locale’s table, then to the key itself, with placeholders interpolated.

class telebot_py.plugins.i18n.I18nSession(plugin: I18nPlugin, context: CallbackContext, locale: str)

Bases: object

Per-update translation session for one resolved locale.

Created by I18nPlugin.session_for(); not constructed directly.

Variables:

locale – The locale code resolved for the current update.

set_locale(locale: str) → None

Persist the user’s locale preference for all future updates.

Writes into context.user_data; when the update carries no user data this is a harmless no-op (node parity).

Parameters:

locale – Locale code to use from now on.

t(key: str, params: Mapping[str, str | int] | None = None) → str

Translate a message key for this session’s locale.

Falls back to the default locale’s table, then to the key itself. {placeholder} tokens are replaced from params.

Parameters:
  • key – Message key in the translation tables.

  • params – Optional placeholder values.

Returns:

The translated, interpolated string.

Example

>>> session.t("hello", {"name": "Nam"})
'Xin chào, Nam!'

telebot_py.plugins.manager

Plugin registration, ordering, dispatch, and removal (T044).

Backs the future Application.add_plugin / Application.remove_plugin surface (contracts/public-api.md section 8). Hook order is resolved from the plugins’ order argument and depends_on graph; cycles raise the typed PluginOrderingError (data-model.md section 7).

exception telebot_py.plugins.manager.PluginError

Bases: TelebotError

Base class for plugin system failures.

class telebot_py.plugins.manager.PluginManager

Bases: object

Owns plugin lifecycle: ordered dispatch, namespaced state, removal.

Standalone by design; the kernel integration pass owns one manager per application and calls dispatch_response() / dispatch_error() around handler dispatch.

Example

>>> manager = PluginManager()
>>> manager.add_plugin(I18nPlugin(default_locale="en", locales=locales))
>>> result = await manager.dispatch_response(context, response)
add_plugin(plugin: Plugin, *, order: int = 0) → None

Register a plugin and install every registrant whose deps are met.

Plugins whose depends_on names are not all installed yet stay pending and are flushed automatically by later add_plugin calls.

Parameters:
  • plugin – The plugin to register.

  • order – Relative hook position; lower values hook first, ties fall back to registration order.

Raises:
  • ValueError – If a plugin with the same name is already registered.

  • PluginOrderingError – If the dependency graph now contains a cycle (the registration is rolled back).

async dispatch_error(context: CallbackContext, error: Exception) → None

Notify every installed error hook of a failure, in hook order.

This is the seam the kernel integration calls when a handler (or an error handler) raises.

Parameters:
  • context – The callback context of the failed update.

  • error – The exception that was raised.

async dispatch_response(context: CallbackContext, response: T) → T

Run every installed response hook over response in hook order.

Each hook’s return value feeds the next hook; the final value is returned. This is the seam the kernel integration calls around handler results.

Parameters:
  • context – The callback context of the update being processed.

  • response – The pipeline result to transform.

Returns:

The transformed response.

has(name: str) → bool

Whether a plugin with the given name is currently installed.

Parameters:

name – Plugin name to look up.

Returns:

True when installed; pending (unsatisfied dependencies) plugins do not count.

property plugins: list[Plugin]

Installed plugins in hook order (resolved on every access).

Returns:

A fresh list; mutating it does not affect the manager.

remove_plugin(name: str) → None

Uninstall a plugin; its hooks stop firing before the next update.

The name can be reused afterwards and its namespaced state is dropped.

Parameters:

name – Name of the registered plugin to remove.

Raises:

ValueError – If no plugin with that name is registered.

state(name: str) → dict[str, Any]

Mutable namespaced state for one plugin, created on first access.

Parameters:

name – Plugin name owning the state.

Returns:

The plugin’s state dict; distinct plugins never see each other’s state.

exception telebot_py.plugins.manager.PluginOrderingError

Bases: PluginError

The plugins’ depends_on declarations form a dependency cycle.

telebot_py.plugins.plugin

Plugin contract for telebot_py (T044, contracts/public-api.md section 8).

A plugin hooks into the update pipeline through optional async response and error hooks. The kernel wiring (T043) calls PluginManager.dispatch_response() around every successful handler result and PluginManager.dispatch_error() after the error handlers ran; nothing here imports the kernel at runtime.

class telebot_py.plugins.plugin.Plugin

Bases: ABC

A named, self-contained bundle of bot behavior.

Subclasses set name (and optionally depends_on) and override whichever hooks they need; un-overridden hooks are inert.

Example

>>> class LoggingPlugin(Plugin):
...     name = "logging"
...     async def on_response(self, context, response):
...         print("handled", context.update.update_id)
...         return response
Variables:
  • name (str) – Unique identifier of the plugin. Registering two plugins with the same name raises ValueError.

  • depends_on (collections.abc.Sequence[str]) – Names of plugins that must hook before this one; a cycle raises PluginOrderingError at registration.

depends_on: Sequence[str] = ()
name: str
async on_error(context: CallbackContext, error: Exception) → None

Observe a handler failure after the error handlers ran.

Called in declared hook order. The default implementation does nothing.

Parameters:
  • context – The callback context of the failed update; the raised exception is also available as context.error.

  • error – The exception the handler raised.

async on_response(context: CallbackContext, response: object) → object

Process a handler pipeline result before it is finalized.

Called in declared hook order; the returned value is handed to the next plugin’s hook. The default implementation passes the response through unchanged.

Parameters:
  • context – The callback context of the update being processed.

  • response – The current pipeline result.

Returns:

The (possibly transformed) response.