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.
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 plan_my_pycon-0.1.0.tar.gz.
File metadata
- Download URL: plan_my_pycon-0.1.0.tar.gz
- Upload date:
- Size: 33.8 kB
- Tags: Source
- Uploaded using 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}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ad272c2cc53af3185c766fb0cd9ce79107d6ce954b7a84565d96ed47a90e2921
|
|
| MD5 |
3f1760028842f7e4c5f786149de0c053
|
|
| BLAKE2b-256 |
eba539f4aa21f04d3627e33ef44828a0797c684876368440ab39d83c7963cd53
|
File details
Details for the file plan_my_pycon-0.1.0-py3-none-any.whl.
File metadata
- Download URL: plan_my_pycon-0.1.0-py3-none-any.whl
- Upload date:
- Size: 39.6 kB
- Tags: Python 3
- Uploaded using 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}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
969efc95b577db6430782950bda30ef185c0607cdd15d8629ff96bf5bab6aa22
|
|
| MD5 |
962412ae70923a6eede3f785b37dacc8
|
|
| BLAKE2b-256 |
ebfaa6eab1039e18d41bc0825d83099d0b2a231b290bb28dfd78c8cdc1a364bd
|