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.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

plan_my_pycon-0.1.0.tar.gz (33.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

plan_my_pycon-0.1.0-py3-none-any.whl (39.6 kB view details)

Uploaded Python 3

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

Hashes for plan_my_pycon-0.1.0.tar.gz
Algorithm Hash digest
SHA256 ad272c2cc53af3185c766fb0cd9ce79107d6ce954b7a84565d96ed47a90e2921
MD5 3f1760028842f7e4c5f786149de0c053
BLAKE2b-256 eba539f4aa21f04d3627e33ef44828a0797c684876368440ab39d83c7963cd53

See more details on using hashes here.

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

Hashes for plan_my_pycon-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 969efc95b577db6430782950bda30ef185c0607cdd15d8629ff96bf5bab6aa22
MD5 962412ae70923a6eede3f785b37dacc8
BLAKE2b-256 ebfaa6eab1039e18d41bc0825d83099d0b2a231b290bb28dfd78c8cdc1a364bd

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page