Polars Scheduler
A Polars plugin for easily scheduling recurring events with constraints.
Installation
pip install polars-scheduler[polars]
On older CPUs run:
pip install polars-scheduler[polars-lts-cpu]
Features
- Powerful Constraint System: Schedule events with constraints like "≥6h apart", "≥1h before food", or "≥2h after medicine"
- Time Windows: Define preferred time windows for events (e.g., breakfast at "08:00", or dinner between "18:00-20:00")
- Optimization Strategies: Choose between "earliest" (soonest possible scheduling) or "latest" (just-in-time)
- Smart Distribution: Automatically distributes multiple daily instances across different time windows
- Mixed Integer Linear Programming: Uses MILP solver to find optimal schedules that satisfy all constraints
Usage
The plugin adds a scheduler namespace to Polars DataFrames with methods for registering events and constraints.
Here is a full demo showing how to:
- create a schedule
- add events with constraints
- generate both an "earliest" and a "latest" schedule
import polars as pl
import polars_scheduler # noqa: F401
# Create a new empty schedule
schedule = pl.DataFrame().scheduler.new()
# Add simple meal and medication schedule
schedule = schedule.scheduler.add(
event="breakfast",
category="meal",
unit="serving",
frequency="1x daily",
windows=["08:00"],
)
schedule = schedule.scheduler.add(
event="lunch",
category="meal",
unit="serving",
frequency="1x daily",
windows=["12:00-13:00"],
)
schedule = schedule.scheduler.add(
event="dinner",
category="meal",
unit="serving",
frequency="1x daily",
windows=["18:00-20:00"],
)
schedule = schedule.scheduler.add(
event="vitamin",
category="supplement",
unit="pill",
frequency="1x daily",
constraints=["≥1h after meal"],
)
schedule = schedule.scheduler.add(
event="antibiotic",
category="medication",
unit="pill",
frequency="2x daily",
constraints=["≥6h apart", "≥1h before food"],
)
schedule = schedule.scheduler.add(
event="probiotic",
category="supplement",
unit="capsule",
frequency="1x daily",
constraints=["≥2h after antibiotic"],
)
schedule = schedule.scheduler.add(
event="protein shake",
category="supplement",
unit="gram",
amount=30,
frequency="1x daily",
constraints=[],
windows=["08:00", "17:00-19:00"],
note="mix with 300ml water",
)
schedule = schedule.scheduler.add(
event="ginger",
category="supplement",
unit="shot",
frequency="1x daily",
constraints=["≥1h before breakfast"],
)
schedule = schedule.scheduler.add(
event="gym",
category="exercise",
unit="session",
frequency="3x weekly",
)
# Print the original schedule
print("--- Schedule Constraints ---")
print(schedule)
# Generate an optimized schedule (Earliest)
result = schedule.scheduler.schedule(
strategy="earliest",
day_start="07:00",
day_end="22:00",
)
print("\n--- Optimized Schedule (Earliest) ---")
print(result.select(["entity_name", "instance", "time_hhmm", "Category"]))
# Generate an optimized schedule (Latest)
result_latest = schedule.scheduler.schedule(
strategy="latest",
day_start="07:00",
day_end="22:00",
)
print("\n--- Latest Schedule ---")
print(result_latest.select(["entity_name", "instance", "time_hhmm", "Category"]))
Example output:
--- Schedule Constraints ---
shape: (9, 9)
┌────────────┬────────────┬─────────┬────────┬───┬───────────┬────────────┬────────────┬───────────┐
│ Event ┆ Category ┆ Unit ┆ Amount ┆ … ┆ Frequency ┆ Constraint ┆ Windows ┆ Note │
│ --- ┆ --- ┆ --- ┆ --- ┆ ┆ --- ┆ s ┆ --- ┆ --- │
│ str ┆ str ┆ str ┆ f64 ┆ ┆ str ┆ list[str] ┆ list[str] ┆ str │
╞════════════╪════════════╪═════════╪════════╪═══╪═══════════╪════════════╪════════════╪═══════════╡
│ breakfast ┆ meal ┆ serving ┆ null ┆ … ┆ 1x daily ┆ [] ┆ ["08:00"] ┆ null │
│ lunch ┆ meal ┆ serving ┆ null ┆ … ┆ 1x daily ┆ [] ┆ ["12:00-13 │ null │
│ ┆ ┆ ┆ ┆ ┆ ┆ ┆ :00"] ┆ │
│ dinner ┆ meal ┆ serving ┆ null ┆ … ┆ 1x daily ┆ [] ┆ ["18:00-20 │ null │
│ ┆ ┆ ┆ ┆ ┆ ┆ ┆ :00"] ┆ │
│ vitamin ┆ supplement ┆ pill ┆ null ┆ … ┆ 1x daily ┆ ["≥1h ┆ [] ┆ null │
│ ┆ ┆ ┆ ┆ ┆ ┆ after ┆ ┆ │
│ ┆ ┆ ┆ ┆ ┆ ┆ meal"] ┆ ┆ │
│ antibiotic ┆ medication ┆ pill ┆ null ┆ … ┆ 2x daily ┆ ["≥6h ┆ [] ┆ null │
│ ┆ ┆ ┆ ┆ ┆ ┆ apart", ┆ ┆ │
│ ┆ ┆ ┆ ┆ ┆ ┆ "≥1h ┆ ┆ │
│ ┆ ┆ ┆ ┆ ┆ ┆ before foo ┆ ┆ │
│ probiotic ┆ supplement ┆ capsule ┆ null ┆ … ┆ 1x daily ┆ ["≥2h ┆ [] ┆ null │
│ ┆ ┆ ┆ ┆ ┆ ┆ after anti ┆ ┆ │
│ ┆ ┆ ┆ ┆ ┆ ┆ biotic"] ┆ ┆ │
│ protein ┆ supplement ┆ gram ┆ 30.0 ┆ … ┆ 1x daily ┆ [] ┆ ["08:00", ┆ mix with │
│ shake ┆ ┆ ┆ ┆ ┆ ┆ ┆ "17:00-19: ┆ 300ml │
│ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 00"] ┆ water │
│ ginger ┆ supplement ┆ shot ┆ null ┆ … ┆ 1x daily ┆ ["≥1h ┆ [] ┆ null │
│ ┆ ┆ ┆ ┆ ┆ ┆ before bre ┆ ┆ │
│ ┆ ┆ ┆ ┆ ┆ ┆ akfast"] ┆ ┆ │
│ gym ┆ exercise ┆ session ┆ null ┆ … ┆ 3x weekly ┆ [] ┆ [] ┆ null │
└────────────┴────────────┴─────────┴────────┴───┴───────────┴────────────┴────────────┴───────────┘
--- Optimized Schedule (Earliest) ---
shape: (12, 4)
┌───────────────┬──────────┬───────────┬────────────┐
│ entity_name ┆ instance ┆ time_hhmm ┆ Category │
│ --- ┆ --- ┆ --- ┆ --- │
│ str ┆ i32 ┆ str ┆ str │
╞═══════════════╪══════════╪═══════════╪════════════╡
│ lunch ┆ 1 ┆ 07:00 ┆ meal │
│ probiotic ┆ 1 ┆ 07:00 ┆ supplement │
│ gym ┆ 2 ┆ 07:00 ┆ exercise │
│ dinner ┆ 1 ┆ 07:00 ┆ meal │
│ antibiotic ┆ 1 ┆ 07:00 ┆ medication │
│ … ┆ … ┆ … ┆ … │
│ vitamin ┆ 1 ┆ 07:00 ┆ supplement │
│ protein shake ┆ 1 ┆ 07:00 ┆ supplement │
│ breakfast ┆ 1 ┆ 07:00 ┆ meal │
│ gym ┆ 3 ┆ 07:00 ┆ exercise │
│ antibiotic ┆ 2 ┆ 13:00 ┆ medication │
└───────────────┴──────────┴───────────┴────────────┘
--- Latest Schedule ---
shape: (12, 4)
┌───────────────┬──────────┬───────────┬────────────┐
│ entity_name ┆ instance ┆ time_hhmm ┆ Category │
│ --- ┆ --- ┆ --- ┆ --- │
│ str ┆ i32 ┆ str ┆ str │
╞═══════════════╪══════════╪═══════════╪════════════╡
│ antibiotic ┆ 1 ┆ 16:00 ┆ medication │
│ lunch ┆ 1 ┆ 22:00 ┆ meal │
│ vitamin ┆ 1 ┆ 22:00 ┆ supplement │
│ protein shake ┆ 1 ┆ 22:00 ┆ supplement │
│ dinner ┆ 1 ┆ 22:00 ┆ meal │
│ … ┆ … ┆ … ┆ … │
│ gym ┆ 1 ┆ 22:00 ┆ exercise │
│ breakfast ┆ 1 ┆ 22:00 ┆ meal │
│ antibiotic ┆ 2 ┆ 22:00 ┆ medication │
│ probiotic ┆ 1 ┆ 22:00 ┆ supplement │
│ ginger ┆ 1 ┆ 22:00 ┆ supplement │
└───────────────┴──────────┴───────────┴────────────┘
Constraint Types
The scheduler supports several constraint types:
- Apart constraint:
"≥6h apart"- Ensures that multiple instances of the same entity are scheduled at least 6 hours apart - Before constraint:
"≥1h before food"- Ensures that an entity is scheduled at least 1 hour before any entity in the "food" category - After constraint:
"≥2h after medication"- Ensures that an entity is scheduled at least 2 hours after any entity in the "medication" category
When both "before" and "after" constraints are specified for the same entity-category pair, they are combined as an "OR" constraint using a big-M formulation, not an "AND" constraint (which would often be impossible to satisfy).
Window Specifications
Windows can be specified in two formats:
- Anchor:
"08:00"- A specific time point - Range:
"18:00-20:00"- A time range
When multiple instances of the same entity need to be scheduled, the solver will try to distribute them across different windows.
Optimization Strategies
- Earliest: Places events as early as possible while satisfying all constraints
- Latest: Places events as late as possible while satisfying all constraints
Standalone CLI Tool
The project also includes a standalone command-line tool for scheduling:
cd scheduler-cli
cargo run -- --strategy earliest --start=07:00 --end=22:00
Development
To build the project:
-
Build the core library:
cd scheduler-core cargo build
-
Build the CLI tool:
cd scheduler-cli cargo build
-
Build the Python bindings:
cd polars-scheduler-py maturin develop
License
MIT License
Metadata
Release files for polars-scheduler 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| polars_scheduler-0.2.0.tar.gz | 54.3 kB | Details |
Built distributions (wheels)
Total release size: 39.1 MB
Release files / polars_scheduler-0.2.0.tar.gz
| Download URL | polars_scheduler-0.2.0.tar.gz |
|---|---|
| Size | 54.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
dcdcd74bab65920e3eda43b26a2026d4f8cbbff66fa86eea37f5e0bc1a4ab0f7
|
|
BLAKE2b-256 checksum How to use checksums |
e8973b2473aacc943f05a111f83e68a6bd42cce371dce5289b65e7deb21fd63d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
pdm/2.22.4 CPython/3.11.11 Linux/6.8.0-51-generic
|
Release files / polars_scheduler-0.2.0-cp38-abi3-win_amd64.whl
| Download URL | polars_scheduler-0.2.0-cp38-abi3-win_amd64.whl |
|---|---|
| Size | 3.5 MB |
| Tags | CPython 3.8 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
5b4e45a497c17d160a47da485e45d0a874faaaa9ad4f8b0388da6c81552d67b8
|
|
BLAKE2b-256 checksum How to use checksums |
0a9a630d2c4aa55730f6fc1264a8c9f70902382f88f2d57f3eb08d7e73ba8fac
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
pdm/2.22.4 CPython/3.11.11 Linux/6.8.0-51-generic
|
Release files / polars_scheduler-0.2.0-cp38-abi3-win32.whl
| Download URL | polars_scheduler-0.2.0-cp38-abi3-win32.whl |
|---|---|
| Size | 3.4 MB |
| Tags | CPython 3.8 Windows x86-32 abi3 |
|
SHA-256 checksum How to use checksums |
1af508749aacb90442be4a4bbdfa2cf5da4164337792384cd64bf27ace79d6f9
|
|
BLAKE2b-256 checksum How to use checksums |
4c9836b9aaf91ed90d3255b96fb781d502c0ba855faadee9f803932f40fe19c6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
pdm/2.22.4 CPython/3.11.11 Linux/6.8.0-51-generic
|
Release files / polars_scheduler-0.2.0-cp38-abi3-manylinux_2_34_ppc64le.whl
| Download URL | polars_scheduler-0.2.0-cp38-abi3-manylinux_2_34_ppc64le.whl |
|---|---|
| Size | 4.0 MB |
| Tags | CPython 3.8 Linux glibc 2.34+ PowerPC 64-le abi3 |
|
SHA-256 checksum How to use checksums |
af0e6da8486c591a61b0b9e9fe9089d58f22248fdf7e620cb4e071b30d5fdd1d
|
|
BLAKE2b-256 checksum How to use checksums |
f205bc0377312fef08fca7ca3b29b0ef9f63aa9500f5f33636426ae3dab9f090
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
pdm/2.22.4 CPython/3.11.11 Linux/6.8.0-51-generic
|
Release files / polars_scheduler-0.2.0-cp38-abi3-manylinux_2_28_i686.whl
| Download URL | polars_scheduler-0.2.0-cp38-abi3-manylinux_2_28_i686.whl |
|---|---|
| Size | 4.0 MB |
| Tags | CPython 3.8 Linux glibc 2.28+ x86-32 abi3 |
|
SHA-256 checksum How to use checksums |
cbc575e68f1ea2cfc8584cae7a31414af264df8adc1198643fc4f5c2b25d7af5
|
|
BLAKE2b-256 checksum How to use checksums |
7fb4e760ef9601fc6c27eec3c759b48c86179a74e84ef9193ab2aa575aa5d1da
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
pdm/2.22.4 CPython/3.11.11 Linux/6.8.0-51-generic
|
Release files / polars_scheduler-0.2.0-cp38-abi3-manylinux_2_28_aarch64.whl
| Download URL | polars_scheduler-0.2.0-cp38-abi3-manylinux_2_28_aarch64.whl |
|---|---|
| Size | 3.3 MB |
| Tags | CPython 3.8 Linux glibc 2.28+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
19bfb5a1d53e18c7abe48de5e36c3bd0db6d10b387ab2d3bb703633dc2bd09d6
|
|
BLAKE2b-256 checksum How to use checksums |
3608d573b27866900e075621daddb287b0ed14be5bfec58b5849c90d026c2abc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
pdm/2.22.4 CPython/3.11.11 Linux/6.8.0-51-generic
|
Release files / polars_scheduler-0.2.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | polars_scheduler-0.2.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 3.9 MB |
| Tags | CPython 3.8 Linux glibc 2.17+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
6d9d663e62cb252823d6cc7aaa84e1c795b4befacdb58eefe840365ebcfe59c2
|
|
BLAKE2b-256 checksum How to use checksums |
1018d277e33aa376704ca0f0702f78447ea8269e3d4f4d0f5c51530009e42a2d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
pdm/2.22.4 CPython/3.11.11 Linux/6.8.0-51-generic
|
Release files / polars_scheduler-0.2.0-cp38-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl
| Download URL | polars_scheduler-0.2.0-cp38-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl |
|---|---|
| Size | 6.5 MB |
| Tags | CPython 3.8 Linux glibc 2.17+ IBM System/390x abi3 |
|
SHA-256 checksum How to use checksums |
3f6a1b0994462e7aeafd3898d9e6f7b0bc29b64ba95d21aff91e6691fd4db3b1
|
|
BLAKE2b-256 checksum How to use checksums |
91cea8011a2b988588bc3d1a4f9c753d75d25656440a6beabd0a0c1b96185a4a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
pdm/2.22.4 CPython/3.11.11 Linux/6.8.0-51-generic
|
Release files / polars_scheduler-0.2.0-cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
| Download URL | polars_scheduler-0.2.0-cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl |
|---|---|
| Size | 3.9 MB |
| Tags | CPython 3.8 Linux glibc 2.17+ ARMv7l abi3 |
|
SHA-256 checksum How to use checksums |
313ce46d9b41a24935e64471eda472c38728a5ab49ae1573d7f9d57f3fc96306
|
|
BLAKE2b-256 checksum How to use checksums |
601ef698abaddd24d92917cff0c30adf82f3eb681cfc8fea4d64a713e7536b06
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
pdm/2.22.4 CPython/3.11.11 Linux/6.8.0-51-generic
|
Release files / polars_scheduler-0.2.0-cp38-abi3-macosx_11_0_arm64.whl
| Download URL | polars_scheduler-0.2.0-cp38-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 3.0 MB |
| Tags | CPython 3.8 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
02abc8ca2c42cfb11a1022490af85810e6065926eafd2ea26605d5faeec14a32
|
|
BLAKE2b-256 checksum How to use checksums |
d100a5d26ce7df2f54618a5c73ec6285bdba74f486ad411aa1f4b72b4b897c2b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
pdm/2.22.4 CPython/3.11.11 Linux/6.8.0-51-generic
|
Release files / polars_scheduler-0.2.0-cp38-abi3-macosx_10_12_x86_64.whl
| Download URL | polars_scheduler-0.2.0-cp38-abi3-macosx_10_12_x86_64.whl |
|---|---|
| Size | 3.6 MB |
| Tags | CPython 3.8 abi3 macOS 10.12+ x86-64 |
|
SHA-256 checksum How to use checksums |
fc8e1746d0928c4c25d421c4466b5a3c435a00f5a42dee28f1cb99adbf61bd27
|
|
BLAKE2b-256 checksum How to use checksums |
c03c9c05f568b553905e13b2fa4f443bc782a76caea860be5eb064726fadd7da
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
pdm/2.22.4 CPython/3.11.11 Linux/6.8.0-51-generic
|