Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 9 additions & 8 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ on:
branches:
- ep2024
- ep2025
- ep2026
schedule:
- cron: "*/10 * * * *" # every 10 minutes
- cron: "3-59/10 * * * *"
workflow_dispatch:

jobs:
tests:
name: Run tests
deploy:
name: Deploy to static server
runs-on: ubuntu-latest
timeout-minutes: 10

Expand All @@ -22,21 +23,21 @@ jobs:
- name: Set up Python 3
uses: actions/setup-python@v6
with:
python-version: '3.13'
python-version: '3.14'

- name: Setup uv
uses: astral-sh/setup-uv@v7
uses: astral-sh/setup-uv@v8.1.0

- name: Install dependencies from uv.lock
run: make deps/install
run: uv run make deps/install

- name: Download data
run: uv run make download > /dev/null 2>&1
run: uv run make download EXCLUDE="youtube" > /dev/null 2>&1
env:
PRETALX_TOKEN: ${{ secrets.PRETALX_TOKEN }}

- name: Transform data
run: uv run make transform > /dev/null 2>&1
run: uv run make transform EXCLUDE="youtube" > /dev/null 2>&1

- name: Setup SSH
uses: webfactory/ssh-agent@v0.9.1
Expand Down
6 changes: 3 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,18 @@ repos:
- id: trailing-whitespace

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.14.14
rev: v0.15.13
hooks:
- id: ruff
args: [ --fix ]
- id: ruff-format

- repo: https://github.com/tox-dev/pyproject-fmt
rev: v2.12.1
rev: v2.21.2
hooks:
- id: pyproject-fmt

- repo: https://github.com/abravalheri/validate-pyproject
rev: v0.24.1
rev: v0.25
hooks:
- id: validate-pyproject
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Variables for the project
# =========================
CONFERENCE ?= ep2025
CONFERENCE ?= ep2026
DATA_DIR ?= ./data/public/$(CONFERENCE)/

# Variables for remote host
Expand Down
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# 🎤 programapi

This project powers the **EuroPython 2025** website, Discord bot, and internal bot 🦜 by downloading, transforming, and serving clean, structured JSON files for sessions, speakers, and the schedule, all pulled from Pretalx.
This project powers the **EuroPython 2026** website, Discord bot, and internal bot 🦜 by downloading, transforming, and serving clean, structured JSON files for sessions, speakers, and the schedule, all pulled from Pretalx.

Built for transparency. Designed for reuse. Optimized for EuroPython.

Expand Down Expand Up @@ -87,14 +87,14 @@ PRETALX_TOKEN=your_api_token_here
Hosted at:

```
https://static.europython.eu/programme/ep2025/releases/current
https://static.europython.eu/programme/ep2026/releases/current
```

| Endpoint | Description |
|-----------------------------------------------------------------------------------------------------|-------------------------------|
| [`/speakers.json`](https://static.europython.eu/programme/ep2025/releases/current/speakers.json) | List of confirmed speakers |
| [`/sessions.json`](https://static.europython.eu/programme/ep2025/releases/current/sessions.json) | List of confirmed sessions |
| [`/schedule.json`](https://static.europython.eu/programme/ep2025/releases/current/schedule.json) | Latest conference schedule |
| [`/speakers.json`](https://static.europython.eu/programme/ep2026/releases/current/speakers.json) | List of confirmed speakers |
| [`/sessions.json`](https://static.europython.eu/programme/ep2026/releases/current/sessions.json) | List of confirmed sessions |
| [`/schedule.json`](https://static.europython.eu/programme/ep2026/releases/current/schedule.json) | Latest conference schedule |

---

Expand All @@ -111,4 +111,4 @@ Feel free to open an issue or reach us at [infra@europython.eu](mailto:infra@eur

---

📅 Last updated for: **EuroPython 2025**
📅 Last updated for: **EuroPython 2026**
4 changes: 2 additions & 2 deletions data/examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@
"description": "Slides for the session"
}
],
"room": "South Hall 2A",
"room": "Auditorium Hall (S1)",
"start": "2099-07-10T14:00:00+02:00",
"end": "2099-07-10T15:00:00+02:00",
"website_url": "https://ep2099.europython.eu/session/example-talk",
Expand Down Expand Up @@ -211,6 +211,6 @@

### 🛠 Notes & Logic

- `room` normalization maps `"Main Hall"` sessions to `"Exhibit Hall"` — Poster sessions rejoice!
- `room` normalization maps `"Poster Hall"` sessions to `"Exhibit Hall"` — Poster sessions rejoice!
- All `"Registration & Welcome"` events automatically include **all active rooms**.
- Various `social_*_url` fields handle malformed inputs like `@name`, full URLs, or just `username`.
4 changes: 2 additions & 2 deletions data/examples/europython/sessions.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
"sessions_before": null,
"next_session": null,
"prev_session": null,
"website_url": "https://ep2025.europython.eu/session/this-is-a-test-talk-from-a-test-speaker-about-a-test-topic",
"website_url": "https://ep2026.europython.eu/session/this-is-a-test-talk-from-a-test-speaker-about-a-test-topic",
"youtube_url": "https://youtube.com/watch?v=01234567890"
},
"B8CD4F": {
Expand All @@ -57,7 +57,7 @@
"sessions_before": null,
"next_session": null,
"prev_session": null,
"website_url": "https://ep2025.europython.eu/session/a-talk-with-shorter-title",
"website_url": "https://ep2026.europython.eu/session/a-talk-with-shorter-title",
"youtube_url": "https://youtube.com/watch?v=12345679012"
}
}
2 changes: 1 addition & 1 deletion data/examples/europython/speakers.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@
"bluesky_url": "https://bsky.app/profile/username.bsky.social",
"mastodon_url": null,
"twitter_url": null,
"website_url": "https://ep2025.europython.eu/speaker/a-speaker"
"website_url": "https://ep2026.europython.eu/speaker/a-speaker"
}
}
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "programapi"
version = "2025.4.5"
version = "2026.4.17"
description = "Programme API for EuroPython"
readme = "README.md"
requires-python = ">=3.12"
Expand Down
4 changes: 2 additions & 2 deletions src/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@


class Config:
event = "europython-2025"
event_dir_name = "ep2025"
event = "europython-2026"
event_dir_name = "ep2026"
api_version = "v1"

project_root = Path(__file__).resolve().parents[1]
Expand Down
25 changes: 10 additions & 15 deletions src/misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,21 +32,16 @@ class Room(Enum):
Rooms at the conference venue, this can change year to year
"""

# Tutorial/workshop rooms
club_a = "Club A"
club_b = "Club B"
club_c = "Club C"
club_d = "Club D"
club_e = "Club E"
club_h = "Club H"

# Conference rooms
forum_hall = "Forum Hall"
terrace_2a = "Terrace 2A"
terrace_2b = "Terrace 2B"
north_hall = "North Hall"
south_hall_2a = "South Hall 2A"
south_hall_2b = "South Hall 2B"
auditorium_s1 = "Auditorium Hall (S1)"
theatre_s2 = "Theatre Hall (S2)"
conference_s4 = "Conference Hall Complex (S4)"
chamber_s3a = "Chamber Hall A (S3A)"
chamber_s3b = "Chamber Hall B (S3B)"
conference_s4a = "Conference Hall Complex A (S4A)"
conference_s4b = "Conference Hall Complex B (S4B)"
glass_room_f0 = "Conference room F0 (Glass room)"
multifunctional_1 = "Multifunctional room 1 (2.015/2.016)"
fishbowl_f2 = "Reception Room F2 (Fishbowl)"
exhibit_hall = "Exhibit Hall"


Expand Down
2 changes: 1 addition & 1 deletion src/models/europython.py
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ class EuroPythonSession(BaseModel):
@field_validator("room", mode="before")
@classmethod
def handle_poster_room(cls, value) -> str | None:
if value and "Main Hall" in value:
if value and "Poster Hall" in value:
return "Exhibit Hall"
return value

Expand Down
Loading