telebot_py.scheduler¶
Scheduler: JobQueue with in-house RRule (US3, FR-008).
Wired into the kernel by T043: ApplicationBuilder.job_queue() attaches a
queue to Application; initialize() starts it once the bot is ready,
stop()/shutdown() stop it, and every dispatched context exposes it
as context.job_queue.
telebot_py.scheduler.job¶
A single scheduled job managed by the JobQueue (T042).
- class telebot_py.scheduler.job.Job(*, name: str, callback: Callable[[Job[Data]], Awaitable[None] | None], queue: JobQueue, clock: Clock, sleep: SleepFn, kind: _Kind, next_t: datetime, data: Data | None = None, interval: timedelta | None = None, daily_time: time | None = None, daily_days: tuple[int, ...] = (), rrule: RRule | None = None)¶
Bases:
Generic[Data]A scheduled task: one-shot, repeating, daily, or RRule-driven.
Created through the
run_*methods ofJobQueue, never directly.Example
>>> job = queue.run_once(send_reminder, 60.0, data={"chat_id": 1}) >>> job.cancel() # idempotent
- Variables:
name – Identifier of the job; auto-generated when not supplied.
data – Optional payload delivered to the callback as
job.data.next_t – When the job fires next (updated after every fire).
- cancel() None¶
Cancel the job and detach it from its queue.
Idempotent: a second call is a harmless no-op. A cancelled job never fires again, even if it was merely pending (not yet started).
- property cancelled: bool¶
True once the job stops firing, whether by cancel() or completion.
- telebot_py.scheduler.job.JobCallback¶
sync or async callables receiving the fired job.
Job payloads are read from
job.datainside the callback. Callbacks keep the Job-only signature even with the kernel wiring (T043); reach the Bot client by capturingcontext.bot(orapplication.bot) in a closure.- Type:
Signature of job callbacks
alias of
Callable[[Job[Data]],Awaitable[None] |None]
telebot_py.scheduler.queue¶
Async timer-loop job queue (T042).
Parity with the run_once/run_repeating/run_daily/run_custom
surface from contracts/public-api.md section 6. The kernel wiring (T043)
attaches one queue per application via ApplicationBuilder.job_queue()
and drives JobQueue.start() / JobQueue.stop() with the
initialize()/stop() lifecycle.
- class telebot_py.scheduler.queue.JobQueue(*, clock: Callable[[], datetime] | None = None, sleep: Callable[[float], Awaitable[None]] | None = None)¶
Bases:
objectManages background one-shot and recurring jobs on the event loop.
Jobs scheduled while the queue is stopped wait for
start(); jobs scheduled while it is running start immediately.stop()cancels every job. Timekeeping is injectable for deterministic tests:clocksupplies “now” andsleepreplacesasyncio.sleep.Example
>>> queue = JobQueue() >>> queue.start() >>> job = queue.run_once(callback, 60.0, data={"chat_id": 1}) >>> job.cancel() >>> queue.stop()
- get_jobs_by_name(name: str) list[Job[Any]]¶
Find all active jobs with the given name.
- Parameters:
name – Job identifier to look up.
- Returns:
Matching jobs (empty list when none).
- jobs() list[Job[Any]]¶
All jobs currently managed, in scheduling order.
- Returns:
A snapshot list; mutating it does not affect the queue.
- run_custom(rrule: RRule, callback: Callable[[Job[Data]], Awaitable[None] | None], *, data: Data | None = None, name: str | None = None) Job[Data]¶
Schedule a job following an RFC 5545 recurrence rule.
The job fires at every future occurrence of
rruleand finishes (marking itself cancelled and leaving the queue) once the rule is exhausted.- Parameters:
rrule – The recurrence engine driving the schedule.
callback – Sync or async callable invoked with the fired job.
data – Optional payload delivered as
job.data.name – Optional identifier; auto-generated when omitted.
- Returns:
The scheduled job.
- Raises:
ValueError – If the rule yields no future occurrence.
- run_daily(callback: Callable[[Job[Data]], Awaitable[None] | None], time: time, *, days: tuple[int, ...] = (0, 1, 2, 3, 4, 5, 6), data: Data | None = None, name: str | None = None) Job[Data]¶
Schedule a job firing every day at a wall-clock time.
- Parameters:
callback – Sync or async callable invoked with the fired job.
time – Time of day to fire at.
days – Allowed weekdays as
datetime.weekday()values (Monday=0); defaults to every day.data – Optional payload delivered as
job.data.name – Optional identifier; auto-generated when omitted.
- Returns:
The scheduled job.
- Raises:
ValueError – If
daysis empty.
- run_once(callback: Callable[[Job[Data]], Awaitable[None] | None], when: float | datetime, *, data: Data | None = None, name: str | None = None) Job[Data]¶
Schedule a one-off job.
- Parameters:
callback – Sync or async callable invoked with the fired job.
when – Delay in seconds, or an absolute datetime (naive values are treated as UTC).
data – Optional payload delivered as
job.data.name – Optional identifier; auto-generated when omitted.
- Returns:
The scheduled job.
- Raises:
TypeError – If
whenis neither a number nor a datetime.
- run_repeating(callback: Callable[[Job[Data]], Awaitable[None] | None], interval: float, *, first: float | datetime | None = None, data: Data | None = None, name: str | None = None) Job[Data]¶
Schedule a job repeating at a fixed interval.
- Parameters:
callback – Sync or async callable invoked with the fired job.
interval – Seconds between successive fires; must be positive.
first – Delay or absolute datetime of the first fire; defaults to one
interval.data – Optional payload delivered as
job.data.name – Optional identifier; auto-generated when omitted.
- Returns:
The scheduled job.
- Raises:
ValueError – If
intervalis not positive.TypeError – If
firstis neither a number nor a datetime.
- property running: bool¶
Whether the queue’s timer loop is active.
- start() None¶
Activate the queue, arming every pending job’s timer.
- Must be called from inside a running event loop. Raises:
ApplicationError: If the queue is already running.
- stop() None¶
Stop the queue and cancel every job it manages.
- Raises:
ApplicationError – If the queue is not running.
telebot_py.scheduler.rrule.rule¶
In-house RFC 5545 recurrence rule engine (T041).
Logic ported field for field from packages/go/pkg/scheduler/rrule/rrule.go;
the Go implementation is the source of truth for the semantics, including the
iteration safety cap and Go-style calendar normalization for month/year
arithmetic (overflowing days roll into the following month, they are not
clamped).
- class telebot_py.scheduler.rrule.rule.RRule(options: RRuleOptions)¶
Bases:
objectCalculates recurring timestamps based on RFC 5545 recurrence options.
Example
>>> rule = RRule(RRuleOptions(freq=Frequency.DAILY, interval=2, dtstart=start)) >>> next_run = rule.after(datetime.now(timezone.utc), inclusive=False)
- Variables:
options – The normalized options this engine was constructed with.
- after(after: datetime, inclusive: bool = False) datetime | None¶
Find the next occurrence strictly after (or inclusive of) a time.
- Parameters:
after – The reference time to search past.
inclusive – When True, an occurrence exactly at
aftercounts.
- Returns:
The next occurrence, or None when
countis exhausted, the rule ends beforeafter(peruntil), or the safety cap of 10,000 iterations is hit (e.g. an unknown frequency that never advances).
- between(after: datetime, before: datetime, inclusive: bool = False) list[datetime]¶
Return occurrences between two times.
- Parameters:
after – Lower bound of the window.
before – Upper bound of the window; an occurrence exactly at
beforeis included.inclusive – When True, an occurrence exactly at
afteris included.
- Returns:
All occurrences inside the window, in chronological order.
telebot_py.scheduler.rrule.types¶
Value types for the in-house RFC 5545 recurrence rule engine.
Field-for-field port of packages/go/pkg/scheduler/rrule/types.go; the Go
implementation is the source of truth for the semantics (FR-008).
- class telebot_py.scheduler.rrule.types.Frequency(*values)¶
Bases:
IntEnumRecurrence frequency of an
RRuleOptionsrule.Attributes mirror the Go
rrule.Frequencyconstants, whose values are plain ints;RRuleOptions.freqis therefore typedintso unknown values can be constructed and hit the engine’s safety cap exactly like Go.- DAILY = 3¶
- HOURLY = 2¶
- MINUTELY = 1¶
- MONTHLY = 5¶
- SECONDLY = 0¶
- WEEKLY = 4¶
- YEARLY = 6¶
- class telebot_py.scheduler.rrule.types.RRuleOptions(freq: int, interval: int = 1, dtstart: datetime | None = None, until: datetime | None = None, count: int = 0, by_hour: tuple[int, ...] = (), by_minute: tuple[int, ...] = (), by_second: tuple[int, ...] = ())¶
Bases:
objectParameters for an RFC 5545 recurrence rule.
Mirrors Go’s
rrule.Optionsfield for field.by_hour,by_minute, andby_secondare carried for parity with the Go type but the Go engine (and therefore this port) does not expand them when computing occurrences; they are reserved for a future release.- Variables:
freq (int) – Recurrence frequency; one of the
Frequencyvalues.interval (int) – Gap between occurrences in units of
freq; values below 1 are normalized to 1 at engine construction.dtstart (datetime.datetime | None) – First occurrence of the rule; defaults to “now” when omitted.
until (datetime.datetime | None) – Inclusive upper bound; occurrences after it are not returned.
count (int) – Maximum number of occurrences (including
dtstart);0means unlimited.by_hour (tuple[int, ...]) – Reserved; unused by the engine (Go parity).
by_minute (tuple[int, ...]) – Reserved; unused by the engine (Go parity).
by_second (tuple[int, ...]) – Reserved; unused by the engine (Go parity).
Example
>>> options = RRuleOptions( ... freq=Frequency.DAILY, ... interval=2, ... dtstart=datetime(2026, 1, 1, 12, tzinfo=timezone.utc), ... )
- by_hour: tuple[int, ...]¶
- by_minute: tuple[int, ...]¶
- by_second: tuple[int, ...]¶
- count: int¶
- dtstart: datetime | None¶
- freq: int¶
- interval: int¶
- until: datetime | None¶