Python SDK for TeleWidget — Telegram Mini App widgets
Project description
tgwidget
Python SDK for TeleWidget — beautiful Telegram Mini App widgets for bots.
Install
pip install tgwidget
Usage
Generate widget URL
from tgwidget import TgWidget
# Date picker
url = TgWidget("your_bot").date(mode="datetime", format="unix-s").url()
# Color picker
url = TgWidget("your_bot").color(format="hex").url()
# Schedule (range — time windows per day)
url = TgWidget("your_bot").schedule().url()
# Schedule (single — fixed time per day)
url = TgWidget("your_bot").schedule(format="single").url()
# With styling
url = (
TgWidget("your_bot")
.date(mode="date")
.style(color_scheme="dark", accent="#FF6600", adopt_tg_palette=True)
.url()
)
Parse results
When a user completes the widget, the result comes back via deep link t.me/your_bot?start=VALUE. Parse the value:
from tgwidget import parse_date, parse_color, parse_schedule
# Date result — returns native datetime.date object
result = parse_date("2025-03-15", mode="date")
# result.date == '2025-03-15'
# result.date_obj == datetime.date(2025, 3, 15)
# Datetime — returns native datetime object
result = parse_date("2025-03-15_14-30", mode="datetime")
# result.datetime_obj == datetime.datetime(2025, 3, 15, 14, 30)
# result.date_obj == datetime.date(2025, 3, 15)
# result.time_obj == datetime.time(14, 30)
# Time — returns native datetime.time
result = parse_date("14-30", mode="time")
# result.time_obj == datetime.time(14, 30)
# Date range with unix timestamps
result = parse_date("1710460800_1718236800", mode="date-range", format="unix-s")
# result.datetime_obj, result.datetime_end_obj — native datetime objects
# Color result
result = parse_color("FF6600", format="hex")
# ColorResult(raw='FF6600', hex='#FF6600')
# Schedule result — range (56-char range format)
result = parse_schedule("09001800090018000000000009001800090018000000000000000000")
# [ScheduleDay(enabled=True, start='09:00', end='18:00',
# start_time=datetime.time(9, 0), end_time=datetime.time(18, 0)), ...]
# Schedule result — single (28-char single format)
result = parse_schedule("1200120099991200120099999999", format="single")
# [ScheduleDay(enabled=True, time_str='12:00', time_obj=datetime.time(12, 0)), ...]
All parsers automatically handle Telegram bot command prefixes — you can pass raw /start payload strings directly:
result = parse_date("/start 2025-03-15", mode="date")
# result.date_obj == datetime.date(2025, 3, 15)
result = parse_color("/start FF6600", format="hex")
# result.hex == '#FF6600'
⚠️
datetime_obj/date_obj/time_objare naive forformat="default". They carry notzinfo— they're the literal digits the picker sent, not an absolute instant. If you need an actual moment in time (e.g. to store and compare againstdatetime.now()elsewhere, like a scheduled-send time), call.timestamp()or.astimezone()on them rather than assuming they're already UTC: for a naivedatetime, Python interprets it as the host process's local timezone (TZenv var / system setting) when doing either conversion. Treating it as UTC instead — e.g.calendar.timegm(dt.timetuple())— silently produces a value shifted by your host's UTC offset. This is standarddatetimebehavior, not something this library adds, but it's an easy trap: pin your process'sTZto whatever zone your users pick dates in, and let naive datetimes flow through.timestamp()/.astimezone()rather than reimplementing the conversion yourself.
format="unix-s"/"unix-ms"sidestep this entirely —datetime_objis already timezone-aware (tzinfo=timezone.utc), since it's derived from an unambiguous timestamp rather than raw digits.
Date options
The .date() method accepts extra keyword arguments for controlling initial state and validation:
# Duration picker: no auto-select, starts at 00:00:00
url = TgWidget("your_bot").date(mode="time-seconds", auto_now=False).url()
# Duration with custom default
url = TgWidget("your_bot").date(mode="time-seconds", auto_now=False, default="01-30-00").url()
# Time picker with allowed range
url = TgWidget("your_bot").date(mode="time", min="09-00", max="18-00").url()
# Range validation in parser
widget = TgWidget("your_bot").date(mode="time-seconds", min="00-00-00", max="23-59-59")
widget.parse("25-00-00") # raises ValueError
| Option | Type | Description |
|---|---|---|
auto_now |
bool |
Auto-select current time on open. Default: True for time/datetime, not set otherwise. |
default |
str |
Default value in widget format (e.g. "01-30-00"). Used when auto_now is False. |
min |
str |
Minimum allowed value. Validated both in frontend and by SDK parser. |
max |
str |
Maximum allowed value. Validated both in frontend and by SDK parser. |
Pattern (informational format string)
Each widget exposes a .pattern property — a human-readable format hint you can show to users:
widget = TgWidget("your_bot").date(mode="datetime")
widget.pattern # "YYYY-MM-DD HH:MM"
widget2 = TgWidget("your_bot").date(mode="date", order="dmy")
widget2.pattern # "DD-MM-YYYY"
widget3 = TgWidget("your_bot").color(format="hex")
widget3.pattern # "#RRGGBB"
# Use in bot messages:
await ctx.reply(f"Введите дату в формате {widget.pattern}")
You can also use the standalone get_pattern(widget, mode, format, order) function directly.
Widget-level parsing with parse()
If you keep a reference to the widget builder, you can call .parse() directly — it automatically uses the configured widget type and options:
widget = TgWidget("your_bot").date(mode="datetime")
url = widget.url()
# Later, when the user completes the widget:
result = widget.parse("/start 2025-03-15_14-30")
# result.datetime_obj == datetime.datetime(2025, 3, 15, 14, 30)
API
TgWidget(bot_username)
Create a widget builder.
.date(mode, format, order, *, auto_now, default, min, max)— Date/time picker.color(format)— Color picker.schedule(format)— Weekly schedule (format:'range'|'single').style(color_scheme, accent, tint, liquid_glass, adapt_tg_theme, adopt_tg_palette)— Styling.url(base_url)— Generate the final URL.payload()— Get the raw payload dict.pattern— Human-readable format string (e.g."YYYY-MM-DD HH:MM").parse(value)— Parse a widget result string (auto-detects parser from widget type)
Parsers
parse_date(value, mode, format, order, *, min, max)→DateResult(raisesValueErrorif outside min/max)parse_color(value, format)→ColorResultparse_schedule(value, format)→list[ScheduleDay]
Result types
DateResult
date,time,date_end,time_end— string representationstimestamp,timestamp_end— raw integer timestamps (unix modes)datetime_obj,datetime_end_obj— nativedatetime.datetime(naive forformat="default",tzinfo=timezone.utcfor unix formats — see warning above)date_obj,date_end_obj— nativedatetime.datetime_obj,time_end_obj— nativedatetime.time
ColorResult
raw— original value stringhex— e.g.'#FF6600'rgb— e.g.(255, 102, 0)hsl— e.g.(24, 100, 50)
ScheduleDay
enabled— whether the day is activestart,end— time strings e.g.'09:00'(range format)start_time,end_time— nativedatetime.time(range format)time_str— single time string e.g.'12:00'(single format)time_obj— nativedatetime.time(single format)
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file tgwidget-0.7.0.tar.gz.
File metadata
- Download URL: tgwidget-0.7.0.tar.gz
- Upload date:
- Size: 8.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fa839c13a8745584b81b2230804d6dc96ebb06601f560d3d355d9619ba4c1024
|
|
| MD5 |
65f8366da91edc40178a1b76eeee084b
|
|
| BLAKE2b-256 |
0f30fcfd9997e1342dc4f2d9aad975851f5c009f2a276b5ddd42e5bd060f5c85
|
File details
Details for the file tgwidget-0.7.0-py3-none-any.whl.
File metadata
- Download URL: tgwidget-0.7.0-py3-none-any.whl
- Upload date:
- Size: 10.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dee81a0ae2f689735beb9c53ac120906933f147277d7155a445b3524a840b078
|
|
| MD5 |
a37d4ba885a192d3a0b151fc429dfff2
|
|
| BLAKE2b-256 |
a0abe2e0f7b91e3c53c28cbddf39b1fcd09e7b257bc4b8fa2a8c94e8f7f409eb
|