Find the best time to leave: track real drive times via the Google Routes API and report the optimal departure window
Project description
Commute Optimizer
Tracks the real drive time between two places by polling the Google Routes API over a week, then tells you the best time to leave — with far tighter resolution than the wide ranges Google Maps shows.
No dependencies beyond Python 3.9+.
pip install commute-optimizer
That gives you the commute command used below. Running from a source
checkout works too — substitute python -m commute for commute.
All data files (config.json, .env, commute.db, the reports, logs) live
in the directory you run commute from, so each tracking project can have its
own folder.
Example output
The report
commute report writes a self-contained report.html: one section
per direction, a chart of median commute vs. departure time (one line per
weekday), and tables ranking the best departure slot inside each rush window —
including how many minutes it saves over the worst slot.
(Generated from synthetic demo data — regenerate with
python docs/_gen_example.py.)
The terminal
Preflight check before a long run:
> commute check
[ok] config: '1600 Amphitheatre Parkway, Mountain View, CA' -> '1 Market St, San Francisco, CA'
[ok] API key found (AIzaSy...XXXX)
[ok] database writable at C:\...\commute-optimizer\commute.db (0 existing samples)
[ok] live route -> 43.6 min now (free-flow 46.3 min, 58.5 km)
[ok] live route <- 43.1 min now (free-flow 46.5 min, 58.9 km)
[ok] estimated API usage: ~938/day, ~6566/week (free tier ~10,000/month)
All checks passed - ready for a long run.
Polling with the auto-stop timer:
> commute poll -d 7d
Polling '1600 Amphitheatre Parkway, Mountain View, CA' <-> '1 Market St, San Francisco, CA'
Rush interval 1 min, off-peak 10 min. Ctrl+C to stop.
Will stop automatically at 2026-07-12 22:59 and generate the report.
[Sun 22:59:28] -> 43.6 min (free-flow 46.3 min)
[Sun 22:59:28] <- 43.1 min (free-flow 46.5 min)
...
And when the report runs, it also prints the summary:
1600 Amphitheatre Parkway, Mountain View, CA -> 1 Market St, San Francisco, CA
window 07:00-10:00:
Monday leave 09:45-10:00 (~28.7 min; worst 51.3 min, saves 22.6)
Tuesday leave 09:45-10:00 (~29.4 min; worst 51.5 min, saves 22.1)
...
Setup
-
Get a Google Maps Platform API key with the Routes API enabled (Google Cloud console → APIs & Services → enable "Routes API" → create an API key).
-
In the folder where you want the data to live, write the example config and edit your addresses:
commute init -
Put your API key in a
.envfile in the same folder:GOOGLE_MAPS_API_KEY=your-key-here
Usage
Before a long run, verify everything works (config, API key, database, one live API call per direction, and a quota estimate for your poll schedule):
commute check
Start polling. With -d it stops automatically after the given duration and
generates the report; without it, it runs until Ctrl+C:
commute poll -d 7d # a full week, then auto-report
commute poll # open-ended
Durations accept d/h/m and combinations: 7d, 24h, 90m, 1d12h.
Add --no-report to skip the automatic report at the end.
Generate the report any time mid-run (opens report.html in your browser;
--no-open to skip that):
commute report
Or watch the run continuously: this regenerates report.html and a
day-by-day report (report-daily.html — one curve per calendar date plus a
coverage table, so you can see the data filling in before the week is done).
Run it in a second terminal alongside poll; refresh the browser to see
updates:
commute watch # updates every 15 minutes
commute watch -i 5m # or your own interval
To preview the report without waiting a week, seed a synthetic week of two-direction data (refuses to run if the DB already has samples). In an empty folder:
commute init
commute demo
commute report
Surviving sleep and reboots
Instead of running poll in a terminal, register it with the OS so it stays
alive for the whole run (run this from your data folder — that's where the
scheduled poller will work):
commute schedule install -d 7d # poll for a week, survive anything
commute schedule status # is the task/poller alive?
commute schedule remove # stop and unregister
This relaunches the poller every 5 minutes (a lock file makes that a no-op while one is already running) and resumes after a reboot once you log in. The stop time is stored as an absolute timestamp, so it survives reboots too; when it's reached, the report is generated as usual.
Per platform:
- Windows — a Task Scheduler task; it can also wake the machine from
sleep to poll. Output goes to
poll.log(no console window). - Linux — a systemd user service + timer (
commute-poll). Logs go tojournalctl --user -u commute-poll. Runs from login onward; for before-login polling runloginctl enable-linger $USER. Linux can't wake itself from sleep for this; a missed tick fires right after wake. - macOS — a launchd LaunchAgent (
com.commute-optimizer.poll) logging topoll.log. macOS won't wake for it either — to poll with the lid closed, plug in and runcaffeinate -s.
Don't run schedule install while a manually-started poll from an older
version is still running — stop that one first, or you'll get duplicate
samples.
If you skip all this and the machine sleeps mid-run, collected data is still
safe in commute.db — the report's Coverage section will show exactly which
stretches were missed.
Config
{
"origin": "home address",
"destination": "work address",
"travel_mode": "DRIVE",
"track_both_directions": true,
"poll": {
"active_window": ["00:00", "23:59"],
"rush_windows": [["07:00", "10:00"], ["16:00", "19:00"]],
"rush_interval_min": 1,
"offpeak_interval_min": 10
}
}
track_both_directions— when true (the default), every tick samples both origin→destination and the reverse, so one run covers your morning and evening commutes.active_window— only poll inside this local-time range (set e.g.["06:00", "20:00"]to skip the night entirely).rush_windows— during these windows the poller samples everyrush_interval_minminutes; otherwise everyoffpeak_interval_minminutes. The report ranks departure times within these windows (otherwise 3 a.m. always wins).
Cost
The Routes API (traffic-aware) has ~10,000 free calls/month. The default
adaptive schedule makes roughly 470 calls/day per direction — ~6,600/week with
both directions on, still inside the free tier but without room for a second
full week in the same month. Set track_both_directions to false or trim
active_window to halve it. Run commute check to see the estimate
for your exact schedule.
Samples land in commute.db (SQLite). Transient API failures (network blips,
rate limits, 5xx) are retried with backoff (5s/15s/45s) before being recorded
as an error row; permanent failures like a bad key fail fast without retries.
The report ends each direction with a Coverage section flagging any
stretch where sampling stopped (sleep, reboot, repeated errors) despite the
schedule expecting data — so you know which medians to trust.
Known limitations (v1)
- Multi-week data blends together. The report groups by weekday, so two
Mondays from different weeks merge into one median curve. Intended use is a
single week per
commute.db; delete or rename the DB between runs. - Wake-from-sleep is Windows-only. On Linux/macOS the scheduled poller resumes right after wake but can't wake the machine itself.
- No automated tests. The pieces are small and hand-verified, but there's no test suite yet.
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 commute_optimizer-1.1.0.tar.gz.
File metadata
- Download URL: commute_optimizer-1.1.0.tar.gz
- Upload date:
- Size: 25.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e48a66716f45c0f75868b5fe349e3d0e0abd1774695c10618d94f2673dee9f4c
|
|
| MD5 |
dcac641123d7d8ab86ea8714548e2f58
|
|
| BLAKE2b-256 |
89a1f63c7b0f458eb60d79ad320049429bcb49faa82e275c71ffd273801878e2
|
Provenance
The following attestation bundles were made for commute_optimizer-1.1.0.tar.gz:
Publisher:
publish.yml on bkahan/commute-optimizer
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
commute_optimizer-1.1.0.tar.gz -
Subject digest:
e48a66716f45c0f75868b5fe349e3d0e0abd1774695c10618d94f2673dee9f4c - Sigstore transparency entry: 2085836453
- Sigstore integration time:
-
Permalink:
bkahan/commute-optimizer@a4475c9cfc95903fda43ed588dde4316cb27ebfe -
Branch / Tag:
refs/tags/v1.1.0 - Owner: https://github.com/bkahan
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@a4475c9cfc95903fda43ed588dde4316cb27ebfe -
Trigger Event:
push
-
Statement type:
File details
Details for the file commute_optimizer-1.1.0-py3-none-any.whl.
File metadata
- Download URL: commute_optimizer-1.1.0-py3-none-any.whl
- Upload date:
- Size: 26.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
020022f27bf614b3340b6fb96a5362752034ab22ebff1c410b386d1400ded4ed
|
|
| MD5 |
19289dde68c11ced47096b0887c6ccac
|
|
| BLAKE2b-256 |
b86a6fe4e4ba5ac3b38ef3dbb823ce1fdb8f648006716aef1072590f0668a876
|
Provenance
The following attestation bundles were made for commute_optimizer-1.1.0-py3-none-any.whl:
Publisher:
publish.yml on bkahan/commute-optimizer
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
commute_optimizer-1.1.0-py3-none-any.whl -
Subject digest:
020022f27bf614b3340b6fb96a5362752034ab22ebff1c410b386d1400ded4ed - Sigstore transparency entry: 2085836529
- Sigstore integration time:
-
Permalink:
bkahan/commute-optimizer@a4475c9cfc95903fda43ed588dde4316cb27ebfe -
Branch / Tag:
refs/tags/v1.1.0 - Owner: https://github.com/bkahan
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@a4475c9cfc95903fda43ed588dde4316cb27ebfe -
Trigger Event:
push
-
Statement type: