Skip to main content

plan-my-pycon

PyPI Python CI License: MIT

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):

  1. --config PATH on the CLI
  2. ./plan-my-pycon.toml
  3. [tool.plan-my-pycon] in ./pyproject.toml
  4. ~/.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

  1. Open Google Calendar in a browser.
  2. Settings > Import & export > Import.
  3. Select pycon-au-2026.ics and choose the destination calendar.
  4. 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.

  • --refresh sends a conditional If-Modified-Since request; the server responds 304 Not Modified when nothing has changed, so you only download what actually moved.
  • --offline never touches the network. If a page isn't cached the tool exits cleanly with a message telling you to run without --offline once 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

  1. Bump version in pyproject.toml and add an entry to CHANGELOG.md.

  2. Build the wheel and sdist:

    uv build
    
  3. Upload to PyPI (you'll need an API token — see https://pypi.org/manage/account/token/):

    uv publish
    # or: python -m twine upload dist/*
    
  4. 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)

Source distribution for plan-my-pycon 0.1.0
File Size Uploaded
plan_my_pycon-0.1.0.tar.gz 33.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for plan-my-pycon 0.1.0
File Interpreter ABI Platform
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}

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page