Skip to content

Repository files navigation

kyros

An iCalendar feed of the best events in the SF Bay Area — EDM, concerts, free things to do, and AI talks — refreshed every 6 hours. San Jose first, the rest of the Bay right behind it. One URL — subscribe from any calendar app.

refresh calendar feed python license

Subscribe

Add to Google Calendar  — one tap on Android or desktop. Google Calendar (app or web) opens straight to the "Subscribe" prompt, already filled in.

Or add a raw feed URL manually. Everything lives under https://raw.githubusercontent.com/SiddanthEmani/kyros/main/:

feed what's in it
events.ics everything, tagged [EDM] / [Live] / [AI] / [Free] / [Bay]
feeds/edm.ics electronic — club nights and DJ shows
feeds/music.ics all live music: concerts + EDM
feeds/free.ics free events only
feeds/ai.ics AI talks, demos, hackathons (the original kyros feed)
  • Apple Calendar  File → New Calendar Subscription → paste URL
  • Google Calendar / Android  use the one-tap link above, or on desktop: Other calendars → + → From URL → paste URL
  • Outlook / Fantastical / anything else  Add subscription by URL

kyros (κῦρος): authority, weight, signal over noise.


How it works

Luma ┐
 TM  ├─►  classify  ─►  geo filter  ─►  dedup  ─►  rank  ─►  cap  ─►  5 feeds
Fun. ┘     5 buckets     50mi of SJ    merge      SJ first   per cat    every 6h
  1. Fetch — three sources, each isolated so a dead site can't take down a refresh:
    • Luma — AI talks, demos and hackathons. Scrapes the server-rendered discover HTML and paginates the JSON discover API, falling back through CORS relays when the runner IP is blocked.
    • Ticketmaster — concerts and ticketed shows within 50 miles of downtown San Jose (SAP Center, Shoreline, The Ritz, Fox Oakland, Chase Center). Needs a free API key; skips itself without one.
    • Funcheap — free and cheap events, region by region, South Bay first.
  2. Classify — each event lands in one or more of ai, edm, concert, free, community. Anything that matches nothing is dropped, which is what keeps "Networking Drinks" out of the feed.
  3. Geo — resolved to a Bay city and region by coordinates when a source gives them, else by city and venue names. Outside 50 miles of San Jose is dropped.
  4. Dedup — the same show arrives from more than one source. Matches merge, so one event keeps Ticketmaster's price and another source's genre tags.
  5. Rank & cap — per-category scoring plus a San Jose / South Bay boost, so SJ wins the caps while a strong SF show still makes it. Caps are per category, then a combined cap over the union.
  6. Write — the combined events.ics plus the four category feeds.

If a refresh collapses (blocked IP, changed markup), the run fails loudly and keeps the existing feeds rather than publishing an empty calendar.

The Ticketmaster key (optional)

Concert coverage is much better with one. Grab a free key at developer.ticketmaster.com (5,000 calls/day; a refresh uses ~10) and add it as a repository secret named TICKETMASTER_API_KEY. Without it, that source logs no key, skipping and everything else still builds.

Running it locally

pip install -r requirements-dev.txt

python run.py                      # build the feeds
python run.py --explain            # ...and log the ranked keep-list per category
python run.py --dry-run --explain  # fetch and rank, write nothing
python run.py --offline --explain  # run the whole pipeline off committed fixtures
python -m pytest -q                # offline parser + pipeline tests

Two flags exist for CI: --report PATH appends a markdown run report (per-source counts, drop breakdown, top picks) — the PR check points it at $GITHUB_STEP_SUMMARY — and --require-events N exits non-zero when fewer than N events survive, which is how a silently-dead parser gets caught.

--ics-path puts the combined feed anywhere; the category feeds follow it into the same directory, so a scratch run stays out of the repo:

python run.py --offline --ics-path /tmp/kyros/events.ics

Configuration (config.json)

key default meaning
lookahead_days 30 drop events past this horizon
local_tz "America/Los_Angeles" IANA tz for every schedule check
center SJ, radius_miles: 50 what counts as "around the area"
region_boost south-bay 3.0, peninsula 1.5, sf/east-bay 0.5 the San Jose priority dial; San Jose proper gets +1.0 on top
free_bonus 1.0 score bonus for free events
sources all true turn an individual source off
cities / luma_categories SJ, SF, Oakland, Palo Alto / ["ai"] Luma discover scope
ticketmaster_classifications ["music"] Discovery classifications to query
categories.<name>.cap 8–15 top-N per category
categories.<name>.min_weekday_hour_local 16–17 weekday events must start at/after this hour; weekends always pass
combined_cap 60 cap on the combined feed
prefix_titles true [EDM]-style tags in the combined feed
min_events_floor 5 below this, keep the old feeds and fail the run

Old flat configs still work: min_weekday_hour_local and max_events_per_run are read and mapped onto the new shape.

Files

run.py                         # CLI entry point
kyros/
  config.py  http.py  model.py # config, fetching, the Event record
  geo.py                       # Bay city registry, radius, SJ boost
  classify.py  rank.py         # categories and per-category scoring
  dedup.py  ics.py             # cross-source merge, feed writing
  pipeline.py  report.py       # fetch -> filter -> rank -> write, run report
  sources/                     # luma, ticketmaster, funcheap
tests/                         # offline, fixture-driven
scripts/fetch_fixtures.py      # refresh fixtures when a site changes
config.json                    # user-editable
.github/workflows/
  refresh.yml                  # 6-hourly schedule, commits the feeds
  pr-check.yml                 # every PR commit: tests + a live dry run
events.ics  feeds/*.ics        # output (committed by CI)

Why this exists

It started as one calendar I could open on Sunday night and see every meaningful AI talk in the Bay for the coming weeks. The same filtering turns out to be exactly what the rest of a week needs — which warehouse party is worth the drive, which show at The Ritz is on sale, what's free downtown this weekend — without scrolling five sites that each cover a third of it.

License

MIT — fork it, run it for your city, ship your own feed.

About

A daily-refreshed iCalendar feed of the highest-signal AI events in the San Francisco Bay Area. Ranked by host reputation, filtered for technical depth, skips events that clash with your work day. One URL — subscribe from any calendar app.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages