telebot_py.storage¶
Pluggable persistence backends: memory, JSON file, SQLite (FR-009).
telebot_py.storage.base¶
Persistence contract and the key/value adapter it can be built on (T032).
BasePersistence is the python-telegram-bot-shaped contract the kernel and
persistent ConversationHandlers consume (contracts/public-api.md section 7).
KeyValuePersistence implements that whole contract on top of the raw
StorageDriver key/value surface, so new
backends only provide get_raw/set_raw/delete_raw.
- class telebot_py.storage.base.BasePersistence¶
Bases:
ABCContract every persistence backend implements (FR-009).
All methods are awaitable so backends can keep I/O off the event loop.
update_*replaces the stored data wholesale (python-telegram-bot semantics);refresh_*returns a fresh snapshot. PassingNoneas a conversation state deletes that conversation entry.Example
>>> app = Application.builder().token(token).persistence(backend).build()
- async flush() None¶
Flush any buffered state to the underlying storage.
- abstractmethod async get_bot_data() dict[Any, Any]¶
Return the persisted global bot data dict.
- Returns:
The bot data dict; empty when none stored.
- abstractmethod async get_chat_data() dict[int | str, dict[Any, Any]]¶
Return all persisted per-chat data dicts keyed by chat id.
- Returns:
Mapping of chat ids to their data dicts; empty when none stored.
- abstractmethod async get_conversations(name: str) dict[tuple[Any, ...], Any]¶
Return all persisted conversation states for
name.- Parameters:
name – The conversation handler’s persistence name.
- Returns:
Mapping of conversation key tuples to stored states; empty when the name is unknown.
- abstractmethod async get_user_data() dict[int, dict[Any, Any]]¶
Return all persisted per-user data dicts keyed by user id.
- Returns:
Mapping of user ids to their data dicts; empty when none stored.
- async refresh_bot_data() dict[Any, Any]¶
Return a fresh snapshot of the stored global bot data.
- Returns:
The bot data dict.
- async refresh_chat_data() dict[int | str, dict[Any, Any]]¶
Return a fresh snapshot of the stored per-chat data.
- Returns:
Mapping of chat ids to their data dicts.
- async refresh_conversations(name: str) dict[tuple[Any, ...], Any]¶
Return a fresh snapshot of the conversations stored under
name.- Parameters:
name – The conversation handler’s persistence name.
- Returns:
Mapping of conversation key tuples to stored states.
- async refresh_user_data() dict[int, dict[Any, Any]]¶
Return a fresh snapshot of the stored per-user data.
- Returns:
Mapping of user ids to their data dicts.
- async shutdown() None¶
Flush and release backend resources.
- abstractmethod async update_bot_data(bot_data: dict[Any, Any]) None¶
Replace the stored global bot data.
- Parameters:
bot_data – The new bot data dict.
- abstractmethod async update_chat_data(chat_data: dict[int | str, dict[Any, Any]]) None¶
Replace the stored per-chat data wholesale.
- Parameters:
chat_data – The full mapping of chat ids to data dicts.
- abstractmethod async update_conversation(name: str, key: tuple[Any, ...], state: Any) None¶
Persist one conversation state (write-through on every transition).
- Parameters:
name – The conversation handler’s persistence name.
key – The conversation key tuple, e.g.
(chat_id, user_id).state – The new state;
Nonedeletes the entry.
- abstractmethod async update_user_data(user_data: dict[int, dict[Any, Any]]) None¶
Replace the stored per-user data wholesale.
- Parameters:
user_data – The full mapping of user ids to data dicts.
- telebot_py.storage.base.ConversationKey¶
a tuple of chat/user/message ids depending on the handler’s per_chat/per_user/per_message flags.
- Type:
Conversation storage key
alias of
tuple[Any, …]
- class telebot_py.storage.base.KeyValuePersistence(driver: StorageDriver | None = None)¶
Bases:
BasePersistenceAdapter building the full contract on a raw key/value store.
Subclasses override
get_raw(),set_raw(), anddelete_raw()(or inject aStorageDriver) and inherit conversations, chat/user/bot data, and jobs for free.Example
>>> class DictPersistence(KeyValuePersistence): ... async def get_raw(self, key): return self.store.get(key) ... async def set_raw(self, key, value): self.store[key] = value ... async def delete_raw(self, key): self.store.pop(key, None)
- async delete_raw(key: str) None¶
Remove
keyfrom the backing driver; no-op when absent.- Parameters:
key – The storage key to delete.
- Raises:
NotImplementedError – When no driver was injected and the subclass does not override this method.
- async flush() None¶
Flush the backing driver when one was injected.
- async get_bot_data() dict[Any, Any]¶
Return the persisted global bot data dict.
- Returns:
The bot data dict; empty when none stored.
- async get_chat_data() dict[int | str, dict[Any, Any]]¶
Return all persisted per-chat data dicts keyed by chat id.
- Returns:
Mapping of chat ids to their data dicts.
- async get_conversations(name: str) dict[tuple[Any, ...], Any]¶
Return all persisted conversation states for
name.- Parameters:
name – The conversation handler’s persistence name.
- Returns:
Mapping of conversation key tuples to stored states.
- async get_jobs() list[PersistedJob]¶
Return persisted job definitions, skipping corrupt rows.
- Returns:
The list of persisted jobs, possibly empty.
- async get_raw(key: str) str | None¶
Return the raw value for
keyfrom the backing driver.- Parameters:
key – The storage key to look up.
- Returns:
The raw JSON string, or
Nonewhen absent.- Raises:
NotImplementedError – When no driver was injected and the subclass does not override this method.
- async get_user_data() dict[int, dict[Any, Any]]¶
Return all persisted per-user data dicts keyed by user id.
- Returns:
Mapping of user ids to their data dicts.
- async set_jobs(jobs: list[PersistedJob]) None¶
Overwrite the persisted job definitions.
- Parameters:
jobs – The full list of jobs to persist.
- async set_raw(key: str, value: str) None¶
Store
valueunderkeyin the backing driver.- Parameters:
key – The storage key to write.
value – Serialized JSON text to persist.
- Raises:
NotImplementedError – When no driver was injected and the subclass does not override this method.
- async update_bot_data(bot_data: dict[Any, Any]) None¶
Replace the stored global bot data.
- Parameters:
bot_data – The new bot data dict.
- async update_chat_data(chat_data: dict[int | str, dict[Any, Any]]) None¶
Replace the stored per-chat data wholesale.
- Parameters:
chat_data – The full mapping of chat ids to data dicts.
- async update_conversation(name: str, key: tuple[Any, ...], state: Any) None¶
Persist one conversation state;
Nonedeletes the entry.- Parameters:
name – The conversation handler’s persistence name.
key – The conversation key tuple.
state – The new state, or
Noneto delete.
- async update_user_data(user_data: dict[int, dict[Any, Any]]) None¶
Replace the stored per-user data wholesale.
- Parameters:
user_data – The full mapping of user ids to data dicts.
telebot_py.storage.driver¶
Pluggable storage driver interface and persisted value types.
Python parity of packages/node/src/storage/driver.ts: concrete backends
(memory, JSON file, SQLite) expose a raw asynchronous key/value surface that
KeyValuePersistence builds the full
persistence contract on top of.
- class telebot_py.storage.driver.PersistedJob(name: str, next_run: float, interval: float | None = None, rrule: str | dict[str, Any] | None = None, timezone: str | None = None, data: Any = None)¶
Bases:
objectA scheduled job restored from persistence across restarts.
- Variables:
name (str) – Unique name of the job.
next_run (float) – Epoch timestamp (seconds) of the job’s next execution.
interval (float | None) – Optional recurrence interval in seconds.
rrule (str | dict[str, Any] | None) – Optional RFC 5545 RRule string or options mapping.
timezone (str | None) – Optional IANA timezone name the schedule is evaluated in.
data (Any) – Optional serializable payload handed to the job callback.
- data: Any = None¶
- interval: float | None = None¶
- name: str¶
- next_run: float¶
- rrule: str | dict[str, Any] | None = None¶
- timezone: str | None = None¶
- class telebot_py.storage.driver.StorageDriver(*args, **kwargs)¶
Bases:
ProtocolRaw asynchronous key/value store persistence backends plug into.
Mirrors the node
Persistencedriver contract in snake_case: every operation is awaitable so backends can keep I/O off the event loop (worker threads,asyncio.to_thread). Keys are opaque strings; values are serialized JSON text.- async delete_raw(key: str) None¶
Remove
keyfrom the store; no-op when absent.- Parameters:
key – The storage key to delete.
- async flush() None¶
Flush buffered writes to the underlying storage.
- async get_raw(key: str) str | None¶
Return the stored value for
key, orNonewhen absent.- Parameters:
key – The storage key to look up.
- Returns:
The raw JSON string, or
Noneif the key does not exist.
- async set_raw(key: str, value: str) None¶
Store
valueunderkey, overwriting any previous value.- Parameters:
key – The storage key to write.
value – Serialized JSON text to persist.
telebot_py.storage.json¶
JSON file-backed persistence with atomic writes (T033).
- class telebot_py.storage.json.JSONPersistence(file_path: str | Path)¶
Bases:
KeyValuePersistencePersists the whole bot state to a single JSON file.
Every write serializes the full store to a temporary file in the target directory and atomically swaps it in with
os.replace(), so readers never observe a truncated file. All file I/O runs in a worker thread viaasyncio.to_thread()and never blocks the event loop.Example
>>> persistence = JSONPersistence("data/state.json")
- Variables:
file_path – The JSON file backing this persistence instance.
- async delete_raw(key: str) None¶
Remove
keyand rewrite the file atomically; no-op when absent.- Parameters:
key – The storage key to delete.
- async flush() None¶
Write the current store to disk, even when nothing changed.
- async get_raw(key: str) str | None¶
Return the stored value for
key, orNonewhen absent.- Parameters:
key – The storage key to look up.
- Returns:
The raw JSON string, or
Noneif the key does not exist.
- async set_raw(key: str, value: str) None¶
Store
valueunderkeyand rewrite the file atomically.- Parameters:
key – The storage key to write.
value – Serialized JSON text to persist.
telebot_py.storage.memory¶
In-memory persistence backend (T032).
- class telebot_py.storage.memory.MemoryPersistence¶
Bases:
KeyValuePersistenceDefault in-memory persistence; state is lost when the process exits.
Used implicitly when no backend is configured on the builder: data dicts live for the application’s lifetime and conversations start fresh on each run (documented behavior, no crash).
Example
>>> app = Application.builder().token(token).persistence(MemoryPersistence()).build()
- async delete_raw(key: str) None¶
Remove
keyfrom the store; no-op when absent.- Parameters:
key – The storage key to delete.
- async get_raw(key: str) str | None¶
Return the stored value for
key, orNonewhen absent.- Parameters:
key – The storage key to look up.
- Returns:
The raw JSON string, or
Noneif the key does not exist.
- async set_raw(key: str, value: str) None¶
Store
valueunderkey, overwriting any previous value.- Parameters:
key – The storage key to write.
value – Serialized JSON text to persist.
telebot_py.storage.sqlite¶
SQLite-backed persistence on the stdlib sqlite3 module (T034).
A single dedicated worker thread owns the database connection; every operation is submitted through a queue and awaited as a future, so the event loop never blocks and concurrent callers are serialized without corrupting state. The database runs in WAL mode for concurrent readers.
- class telebot_py.storage.sqlite.SQLitePersistence(db_path: str | Path)¶
Bases:
BasePersistenceDurable persistence backed by a SQLite database file.
All access happens on one worker thread (stdlib
sqlite3connections are not safe to share across threads); awaitables handed back to callers resolve when the worker finishes, keeping the event loop free.Example
>>> persistence = SQLitePersistence("data/bot.sqlite3")
- Variables:
db_path – The database file path (or
":memory:").
- async flush() None¶
No-op: every operation commits before resolving.
- async get_bot_data() dict[Any, Any]¶
Return the persisted global bot data dict.
- Returns:
The bot data dict; empty when none stored.
- async get_chat_data() dict[int | str, dict[Any, Any]]¶
Return all persisted per-chat data dicts keyed by chat id.
- Returns:
Mapping of chat ids to their data dicts.
- async get_conversations(name: str) dict[tuple[Any, ...], Any]¶
Return all persisted conversation states for
name.- Parameters:
name – The conversation handler’s persistence name.
- Returns:
Mapping of conversation key tuples to stored states.
- async get_user_data() dict[int, dict[Any, Any]]¶
Return all persisted per-user data dicts keyed by user id.
- Returns:
Mapping of user ids to their data dicts.
- async shutdown() None¶
Stop the worker thread and close the connection; idempotent.
- async update_bot_data(bot_data: dict[Any, Any]) None¶
Replace the stored global bot data.
- Parameters:
bot_data – The new bot data dict.
- async update_chat_data(chat_data: dict[int | str, dict[Any, Any]]) None¶
Replace the stored per-chat data wholesale.
- Parameters:
chat_data – The full mapping of chat ids to data dicts.
- async update_conversation(name: str, key: tuple[Any, ...], state: Any) None¶
Persist one conversation state;
Nonedeletes the entry.- Parameters:
name – The conversation handler’s persistence name.
key – The conversation key tuple.
state – The new state, or
Noneto delete.
- async update_user_data(user_data: dict[int, dict[Any, Any]]) None¶
Replace the stored per-user data wholesale.
- Parameters:
user_data – The full mapping of user ids to data dicts.