plan-my-pycon
An interactive planner for PyCon AU 2026 (Brisbane, 26–30 August 2026). It scrapes the official schedule at https://2026.pycon.org.au/schedule/, fetches every session's abstract and presenter bio, walks you through each parallel-talk slot with a checkbox picker, and exports your picks as an ICS (Google Calendar), JSON, Markdown or HTML file.
Supports all five days:
- Wednesday — pre-conference workshops
- Thursday / Friday / Saturday — main conference (default)
- Sunday — development sprints
Install
Requires Python 3.11+. Pick whichever tool you already have:
With uvx (recommended — one-shot, no install)
uvx plan-my-pycon
With pipx (installed globally, isolated)
pipx install plan-my-pycon
plan-my-pycon --version
Later:
pipx upgrade plan-my-pycon
With pip
python -m pip install --user plan-my-pycon
From source (for development)
git clone https://github.com/mitchell-tesch/plan-my-pycon.git
cd plan-my-pycon
uv sync
uv run plan-my-pycon
Usage
Run the interactive planner (defaults to Thursday, Friday, Saturday):
plan-my-pycon # slot-by-slot picker
plan-my-pycon --tui # full-screen Textual TUI (all days at once)
For each timeslot with parallel talks you'll see a checkbox picker with a
progress hint (Slot 4/12) and per-track colour coding. Arrow keys navigate,
space toggles, enter confirms. Any items you selected on a previous
run — or that match filter flags — are pre-checked. Plenary sessions and
breaks are included automatically.
Full-screen TUI (--tui)
--tui launches a full-screen Textual
app with:
- One tab per day, showing every timeslot and every parallel talk as a checkbox tinted by track colour.
- Ctrl+F to focus the filter box; type to highlight matching talks (title, presenter, track, and abstract text are searched).
- Ctrl+A to check every currently-highlighted talk in one go.
- S to save & exit, Q to quit without saving.
- Hover a talk to see its abstract as a tooltip.
Review mode (--review)
The tool saves a fingerprint of the schedule alongside your picks. Re-run
with --review after the organisers update the schedule and only the slots
whose contents changed are shown — everything else is left untouched.
plan-my-pycon --review
Whenever a change is detected (even without --review) you'll see a red
panel summarising what moved:
! Schedule changed since last run
Thursday 10:45 (+3 new, -1 removed)
Friday 14:40 (2 edited)
Configuration file
Pin your preferred defaults so you don't have to retype flags. Any of these locations is picked up automatically (first match wins):
--config PATHon the CLI./plan-my-pycon.toml[tool.plan-my-pycon]in./pyproject.toml~/.config/plan-my-pycon/config.toml
Or set PLAN_MY_PYCON_CONFIG=/path/to/config.toml.
Example plan-my-pycon.toml:
days = ["thursday", "friday", "saturday"]
format = "ics"
output = "pycon.ics"
selection = "pycon-picks.json"
reminders = ["10m", "1h"]
tui = true
[filters]
tracks = ["Data & AI"]
exclude_tracks = ["Platform Engineering"]
presenters = ["Fong-Jones"]
search = ["RAG|LLM"]
# All colours are hex strings. Any field you omit keeps its dark default.
[theme]
background = "#1A1B26" # screen background
surface = "#24283B" # timeslot cards
surface_alt = "#1E202E" # filter bar
text = "#C0CAF5" # primary text
text_muted = "#6B7280" # meta text (room, presenter)
violet = "#9D7CFF" # primary accent — parallel slots, focused input
emerald = "#34D399" # secondary accent — plenary borders, input outline
coral = "#F87171" # break labels
gold = "#FBBF24" # highlight
match_bg = "#1F3B34" # background for checkboxes matching the filter
header_bg = "#3B2E85" # dark violet header bar
header_text = "#F5F1E8" # header/footer text
footer_bg = "#0F1017" # bottom bar
Explicit CLI flags always override the config file.
TUI theme
The full-screen --tui uses a dark palette by
default, chosen so it contrasts well on any terminal and doesn't clash with
the site-palette track colours (Data & AI gold, Platform Engineering
coral, and so on). Every colour is themable via the [theme] table above —
tweak any field, leave the rest for the defaults. Text/background pairs are
checked for WCAG AA contrast (≥ 4.5:1 for body text, ≥ 3:1 for track labels)
in the test suite.
If you like a light background, set background = "#F5F1E8", surface =
"#ffffff", text = "#282828" (etc.) and you're back to the original site
palette.
Import into Google Calendar
- Open Google Calendar in a browser.
- Settings > Import & export > Import.
- Select
pycon-au-2026.icsand choose the destination calendar. - Click Import.
All events use the Australia/Brisbane timezone (AEST, UTC+10, no DST).
Filters — pre-select matching talks
Pre-check anything you already know you want by combining any of:
plan-my-pycon --track "Data & AI" # only that track
plan-my-pycon --exclude-track "Platform Engineering"
plan-my-pycon --presenter "Fong-Jones|Ryan" # regex over names
plan-my-pycon --search "RAG|LLM|OpenTelemetry" # title/presenter/track/abstract
Flags are repeatable and are AND-combined. Matching talks are pre-checked in
the interactive picker; combine with --non-interactive for a hands-off run.
Export formats
plan-my-pycon -f ics # default — Google/Apple/Outlook calendars
plan-my-pycon -f json # machine-readable
plan-my-pycon -f markdown # paste into Notion, GitHub, Obsidian
plan-my-pycon -f html # standalone printable page
Other useful flags
plan-my-pycon --list # pretty-print the whole schedule
plan-my-pycon --days wednesday sunday # plan workshops or sprints
plan-my-pycon --tui # full-screen TUI
plan-my-pycon --edit # re-open the picker even if saved picks exist
plan-my-pycon --review # only revisit changed slots
plan-my-pycon --non-interactive # rebuild export from saved picks
plan-my-pycon --refresh # conditional re-fetch (If-Modified-Since)
plan-my-pycon --offline # network-free run from cache
plan-my-pycon --reminder 10m # add VALARM alarms (repeatable)
plan-my-pycon --no-abstracts # skip detail-page fetches (faster)
plan-my-pycon --no-color # plain output
plan-my-pycon --config my.toml # explicit config file
plan-my-pycon --version # show version
plan-my-pycon -o me.md -s me.json # custom output paths
Smart re-runs
If you've already saved a selection and the schedule hasn't changed, subsequent
runs skip the picker and just re-export. Handy for "give me a fresh ICS after
tweaking --reminder":
plan-my-pycon --reminder 15m --reminder 1h # re-export with new alarms
plan-my-pycon --edit # explicitly re-open the picker
plan-my-pycon --review # only revisit slots the organisers changed
Conflict detection
After you save your selection the tool prints a red table of any overlapping choices, so you can spot slots where you've kept two talks as backups. The overlapping events remain in the export — a common workflow is to keep 2–3 options per slot and choose on the day.
Reminders (VALARM)
Add ICS alarms so your calendar app pings you before every talk:
plan-my-pycon --reminder 10m # 10 minutes before
plan-my-pycon --reminder 5m --reminder 1h # two reminders per event
plan-my-pycon --reminder 1h30m # 1 hour 30 minutes
Durations accept any combination of <int>h, <int>m, and <int>s. A bare
integer (--reminder 5) is treated as minutes. Reminders are skipped on
break events. Set them permanently in plan-my-pycon.toml:
reminders = ["10m", "1h"]
Offline mode
Fetched pages live under ~/.cache/plan-my-pycon/ (override with the
PLAN_MY_PYCON_CACHE env var). At the start of every run the tool prints the
age of each cached day (Thursday schedule: cached (2h old)) so you know
whether to --refresh.
--refreshsends a conditionalIf-Modified-Sincerequest; the server responds304 Not Modifiedwhen nothing has changed, so you only download what actually moved.--offlinenever touches the network. If a page isn't cached the tool exits cleanly with a message telling you to run without--offlineonce to populate the cache. Handy on planes, in trains, or on conference wifi.
plan-my-pycon --offline # re-plan without network
plan-my-pycon --refresh # re-validate cache, download only diffs
Project layout
src/plan_my_pycon/scraper.py— day + session-detail scraping, disk cache, retrying HTTP session.src/plan_my_pycon/filters.py— track / presenter / search filters.src/plan_my_pycon/planner.py— Rich + questionary interactive picker.src/plan_my_pycon/tui.py— Textual full-screen TUI (--tui).src/plan_my_pycon/snapshot.py— schedule fingerprinting for--review.src/plan_my_pycon/conflicts.py— overlap detection.src/plan_my_pycon/exporters.py— ICS / JSON / Markdown / HTML export.src/plan_my_pycon/ics.py— RFC 5545 ICS with Brisbane timezone.src/plan_my_pycon/config.py— TOML config loading.src/plan_my_pycon/__init__.py— CLI entrypoint.
Releasing (maintainers)
Local quality checks
Before pushing a change, run the same checks CI runs:
uv sync --group dev
uv run ruff format --check src tests
uv run ruff check src tests
uv run mypy
uv run pytest
uv build
Or all-in-one:
uv sync --group dev && uv run ruff check src tests && uv run mypy && uv run pytest && uv build
CI (.github/workflows/ci.yml) runs the same on every push/PR to main,
with pytest across Python 3.11, 3.12, and 3.13.
Test fixtures
Tests never hit the network. Sample HTML for two conference days
(day-thursday.html, day-sunday.html) and three session detail pages live
under tests/fixtures/ and are copied into a temp cache
directory by the fixture_cache fixture in
tests/conftest.py. To refresh them:
plan-my-pycon --refresh --days thursday sunday --list
cp ~/.cache/plan-my-pycon/day-{thursday,sunday}.html tests/fixtures/
cp ~/.cache/plan-my-pycon/session-{NDWRBS,3FQZVE,VHXDSA}.html tests/fixtures/
Cutting a release
-
Bump
versioninpyproject.tomland add an entry toCHANGELOG.md. -
Build the wheel and sdist:
uv build -
Upload to PyPI (you'll need an API token — see https://pypi.org/manage/account/token/):
uv publish # or: python -m twine upload dist/*
-
Tag the release:
git tag v0.1.0 -m "v0.1.0" git push --tags
License
MIT — see LICENSE.
Changelog
See CHANGELOG.md.
Metadata
Release files for plan-my-pycon 0.1.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 | |
|---|---|---|---|
| plan_my_pycon-0.1.0.tar.gz | 33.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| plan_my_pycon-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 73.4 kB
Release files / plan_my_pycon-0.1.0.tar.gz
| Download URL | plan_my_pycon-0.1.0.tar.gz |
|---|---|
| Size | 33.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ad272c2cc53af3185c766fb0cd9ce79107d6ce954b7a84565d96ed47a90e2921
|
|
BLAKE2b-256 checksum How to use checksums |
eba539f4aa21f04d3627e33ef44828a0797c684876368440ab39d83c7963cd53
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.0 {"installer":{"name":"uv","version":"0.12.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / plan_my_pycon-0.1.0-py3-none-any.whl
| Download URL | plan_my_pycon-0.1.0-py3-none-any.whl |
|---|---|
| Size | 39.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
969efc95b577db6430782950bda30ef185c0607cdd15d8629ff96bf5bab6aa22
|
|
BLAKE2b-256 checksum How to use checksums |
ebfaa6eab1039e18d41bc0825d83099d0b2a231b290bb28dfd78c8cdc1a364bd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.0 {"installer":{"name":"uv","version":"0.12.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|