Releases: smoxy/telegram-menu-builder
Releases · smoxy/telegram-menu-builder
Release list
v0.4.0
telegram-menu-builder v0.4.0
This release makes menus usable outside a python-telegram-bot Application, adds an atomic
multi-operator claim primitive, and ships first-class test helpers — the high-leverage set
from real downstream feedback.
Added
- Application-free, budget-enforced menus.
MenuBuilder.to_markup()(synchronous →
telegram.InlineKeyboardMarkup) andMenuBuilder.to_raw()(synchronous → a plain Telegram Bot API
dict{"inline_keyboard": [[...]]}, built directly from items so it can be consumed without
python-telegram-bot) build a menu with no event loop, no storage, and no worker thread. Every
button is encoded inline; any item that would otherwise spill to storage raisesEncodingError
(usebuild_async()for those).assert_inline()is a cheap pre-flight, and the new
MenuBuilder(on_oversize="spill" | "error")policy makesbuild_async()fail loudly instead of
silently spilling. Backed by a new synchronousCallbackEncoder.encode_inline(). - Atomic claim / idempotency for multi-operator workflows. A new atomic set-if-absent primitive
StorageBackend.add(key, data, ttl=None) -> bool(non-atomic default onBaseStorageso existing
custom backends keep working; concurrency-safe overrides forMemoryStorage,RedisStoragevia
SET … NX, andSQLAlchemyStoragevia a single transaction that frees expired rows then INSERTs
no-op-on-conflict). On top of it,MenuRouter.claim(key, user_id, *, ttl=3600),who_claimed(key),
andrelease(key)provide a single-winner guarantee — verified end-to-end against live
PostgreSQL 16, Redis 7, and Valkey 8 (concurrent claimers → exactly one wins). - Testing helpers — new
telegram_menu_builder.testingmodule (standard-libraryunittest.mock
only; imported as a submodule).simulate_tap(router, callback_data, ...)and
tap(router, handler, /, **params)drive aMenuRouterwith no live Telegram and return a
TapResult(answered,answer_text,edited_text,handler_error);assert_inline(target)
verifies aMenuBuilder/InlineKeyboardMarkup/ raw dict contains only inlineI:/IC:callback
buttons (noS:/P:storage references).
Full changelog: v0.3.0...v0.4.0
v0.3.0
telegram-menu-builder v0.3.0
Two built-in storage backends land in this release — SQL (SQLAlchemy 2.0 async) and
Redis/Valkey — both verified end-to-end against live servers.
Added
- Redis / Valkey backend —
RedisStorageonredis-py, with first-class Valkey support
(RESP-compatible: point aredis://URL at either server, or pass a duck-typedvalkey-py
client). Native server-side TTL, namespaced keys, owns-vs-borrows client lifecycle, SCAN-based
clear/keys(neverFLUSHDB), and a lazy[redis]import. Verified end-to-end against live
Redis 7.4.9 and Valkey 8.1.8 (fakerediscovers the default test run). Valkey is the
recommended option. Install:pip install "telegram-menu-builder[redis]". - SQL backend —
SQLAlchemyStoragefor PostgreSQL/Supabase, MySQL/MariaDB, and SQLite via
SQLAlchemy 2.0 (async); new optional extras[postgres]and[mysql]; explicit schema management
viacreate_schema()/drop_schema(). Verified end-to-end against live PostgreSQL 16 and
MariaDB 12.3.2 (suite gated byTMB_TEST_POSTGRES_URL/TMB_TEST_MYSQL_URL).
Changed
- The
[sql]extra now pinssqlalchemy[asyncio]>=2.0.30,<3.0. - Documentation refreshed across the storage, installation, dependency-audit, and development
guides (per-DB driver matrix incl. the pure-Pythonaiomysqlalternative toasyncmy, UTC
expires_athandling, portableget_stats, Docker-based integration testing). Corrected the
documentedpython-telegram-botrange to>=20.0,<22.8.
Full changelog: v0.2.0...v0.3.0
v0.2.0
telegram-menu-builder 0.2.0
This release fixes a critical correctness bug in async usage, hardens the
dependency posture, and adds a full documentation site, CI, and project tooling.
🐛 Fixed
- Critical: callback data is no longer lost when a menu is built inside a running
event loop.add_item()previously discarded the handler and parameters in async
contexts (the normal Telegram-bot case), producing buttons with emptycallback_data.
Encoding is now deferred tobuild_async()so every item is encoded correctly. MenuBuilder.build()now works when called inside a running event loop (it runs the
async build on a short-lived worker thread) instead of raisingRuntimeError. In async
code, preferawait build_async().add_submenu()no longer stores the non-serializable submenu builder in callback params;
only a JSON-safe_submenu_idis stored, with the builder kept in an internal registry
accessible via the newget_submenu().__version__is now single-sourced from package metadata (was hard-coded and drifted).- Hardened the deterministic dedup hash with
hashlib.md5(..., usedforsecurity=False).
✨ Added
- Exported the exception hierarchy (
MenuBuilderError,EncodingError,DecodingError,
StorageError,ValidationError) from the package root, plusMenuBuilder.get_submenu(). - MkDocs Material documentation site (API reference, guides, security and
dependency/CVE audit, Python-compatibility analysis). - Tests for the router, storage backends, type validators, and package metadata
(coverage ~62% → ~90%). - CI workflow (ruff, black, mypy, pyright, pytest, pip-audit) on every push/PR, plus a
docs-deploy workflow;SECURITY.md, Dependabot, and issue/PR templates.
🔧 Changed
- Raised the pydantic floor to
>=2.4to exclude CVE-2024-3772 (ReDoS in pydantic
email validation, fixed in 2.4.0). The library does not use email validation, so it was
never exploitable here — this is defense-in-depth. StorageStrategynow subclassesenum.StrEnum; refactored navigation buttons and
MenuRouter.route()(no behavior change).
Full changelog: https://github.com/smoxy/telegram-menu-builder/blob/v0.2.0/CHANGELOG.md
Release v0.1.1
[0.1.1] - 2025-11-08
Added
- Comprehensive guide for using MenuBuilder with ConversationHandler
- New example
conversation_handler_menu.pydemonstrating properper_messageconfiguration - Documentation file
docs/conversation_handler_guide.mdwith best practices - Support for python-telegram-bot up to version 22.5
Changed
- Updated dependency range:
python-telegram-bot>=20.0,<22.6(was<22.0) - Clarified ConversationHandler integration requirements in documentation
Fixed
- Documented solution for
CallbackQueryHandlerin fallbacks not working withper_message=False - Added warning about PTBUserWarning when using incompatible handler types with
per_message=True
Release v0.1.0
fix: resolve linting errors - merge startswith calls, move imports to…