pFad - Phone/Frame/Anonymizer/Declutterfier! Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

URL: http://github.com/EuroPython/programapi/commit/5d8bf31bed89652c86d9c4026c02a8479a1132a3

="https://github.githubassets.com/assets/global-d18f184ea1a06a2c.css" /> Migrate to new Pretalx API (#133) · EuroPython/programapi@5d8bf31 · GitHub
Skip to content

Commit 5d8bf31

Browse files
authored
Migrate to new Pretalx API (#133)
* Remove outdated query '?questions=all' * Use '?expand=...' to request nested resources * Deserialization: speaker.avatar -> speaker.avatar_url * Deserialization: Localization 'en' -> 'name.en' * Deserialization: Schedule slots * Deserialization: Don't expect embedded submission.speakers * Deserialization: Handle non-expanded submission.resources Workaround for pretalx/pretalx#2040 * Chore: Fix typing * Include submission resources in session export
1 parent 7731354 commit 5d8bf31

6 files changed

Lines changed: 61 additions & 36 deletions

File tree

data/examples/pretalx/speakers.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"submissions": [
77
"A8CD3F"
88
],
9-
"avatar": "https://pretalx.com/media/avatars/picture.jpg",
9+
"avatar_url": "https://pretalx.com/media/avatars/picture.jpg",
1010
"answers": [
1111
{
1212
"id": 272244,

data/examples/pretalx/submissions.json

Lines changed: 9 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,16 @@
22
{
33
"code": "A8CD3F",
44
"speakers": [
5-
{
6-
"code": "F3DC8A",
7-
"name": "A Speaker",
8-
"biography": "This is a biography of F3D speaker",
9-
"avatar": "https://pretalx.com/media/avatars/picture.jpg",
10-
"email": "f3dc8a@example.com"
11-
},
12-
{
13-
"code": "ZXCVBN",
14-
"name": "ZXC Speaker",
15-
"biography": "This is a biography of ZXC speaker",
16-
"avatar": "https://pretalx.com/media/avatars/picture.jpg",
17-
"email": "zxcvbn@example.com"
18-
}
5+
"F3DC8A",
6+
"ZXCVBN"
197
],
208
"title": "This is a test talk from a test speaker about a test topic.",
219
"submission_type": "Talk (long session)",
2210
"submission_type_id": 3961,
2311
"track": {
24-
"en": "Software Engineering & Architecture"
12+
"name": {
13+
"en": "Software Engineering & Architecture"
14+
}
2515
},
2616
"track_id": 4493,
2717
"state": "confirmed",
@@ -125,19 +115,15 @@
125115
{
126116
"code": "B8CD4F",
127117
"speakers": [
128-
{
129-
"code": "G3DC8A",
130-
"name": "Another Speaker",
131-
"biography": "This is a biography of F3D speaker",
132-
"avatar": "https://pretalx.com/media/avatars/picture.jpg",
133-
"email": "g3dc8a@example.com"
134-
}
118+
"G3DC8A"
135119
],
136120
"title": "A talk with shorter title",
137121
"submission_type": "Talk",
138122
"submission_type_id": 3961,
139123
"track": {
140-
"en": "PyData: LLMs"
124+
"name": {
125+
"en": "PyData: LLMs"
126+
}
141127
},
142128
"track_id": 4493,
143129
"state": "confirmed",

src/download.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,16 @@
2525
}
2626

2727
base_url = f"https://pretalx.com/api/events/{Config.event}/"
28-
schedule_url = base_url + "schedules/latest/"
28+
schedule_url = (
29+
base_url
30+
+ "schedules/latest?expand="
31+
+ "slots,slots.submission,slots.submission.submission_type,slots.submission.track,slots.room"
32+
)
2933

3034
# Build resource list dynamically based on exclusions
3135
resources = [
32-
"submissions?questions=all&state=confirmed",
33-
"speakers?questions=all",
36+
"submissions?state=confirmed&expand=answers.question,submission_type,track,slots.room,resources",
37+
"speakers?expand=answers.question",
3438
]
3539

3640
if "youtube" not in exclude:

src/models/pretalx.py

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class PretalxSlot(BaseModel):
3333
@classmethod
3434
def handle_localized(cls, v) -> str | None:
3535
if isinstance(v, dict):
36-
return v.get("en")
36+
return v["name"].get("en")
3737
return v
3838

3939

@@ -45,7 +45,7 @@ class PretalxSpeaker(BaseModel):
4545
code: str
4646
name: str
4747
biography: str | None = None
48-
avatar: str
48+
avatar_url: str
4949
submissions: list[str]
5050
answers: list[PretalxAnswer]
5151

@@ -77,7 +77,7 @@ class PretalxSubmission(BaseModel):
7777
@classmethod
7878
def handle_localized(cls, v) -> str | None:
7979
if isinstance(v, dict):
80-
return v.get("en")
80+
return v["name"].get("en")
8181
return v
8282

8383
@field_validator("duration", mode="before")
@@ -95,11 +95,18 @@ def handle_resources(cls, v) -> list[dict[str, str]] | None:
9595
@model_validator(mode="before")
9696
@classmethod
9797
def process_values(cls, values) -> dict:
98-
values["speakers"] = sorted([s["code"] for s in values["speakers"]])
98+
# Transform resource information
99+
if raw_resources := values.get("resources"):
100+
resources = [
101+
{"description": res["description"], "resource": res["resource"]}
102+
for res in raw_resources
103+
]
104+
values["resources"] = resources
99105

100106
# Set slot information
101-
if values.get("slot"):
102-
slot = PretalxSlot.model_validate(values["slot"])
107+
if values.get("slots"):
108+
slot = PretalxSlot.model_validate(values["slots"][0])
109+
values["slot"] = slot
103110
values["room"] = slot.room
104111
values["start"] = slot.start
105112
values["end"] = slot.end
@@ -146,3 +153,31 @@ class PretalxSchedule(BaseModel):
146153

147154
slots: list[PretalxSubmission]
148155
breaks: list[PretalxScheduleBreak]
156+
157+
@model_validator(mode="before")
158+
@classmethod
159+
def process_values(cls, values) -> dict:
160+
submission_slots = []
161+
break_slots = []
162+
for slot_dict in values["slots"]:
163+
# extract nested slot fields into slot
164+
slot_object = PretalxSlot.model_validate(slot_dict)
165+
slot_dict["slot"] = slot_object
166+
slot_dict["room"] = slot_object.room
167+
slot_dict["start"] = slot_object.start
168+
slot_dict["end"] = slot_object.end
169+
170+
if slot_dict.get("submission") is None:
171+
break_slots.append(slot_dict)
172+
else:
173+
# merge submission fields into slot
174+
slot_dict.update(slot_dict.get("submission", {}))
175+
176+
# remove resource IDs (not expandable with API, not required for schedule)
177+
slot_dict.pop("resources", None)
178+
179+
submission_slots.append(slot_dict)
180+
181+
values["slots"] = submission_slots
182+
values["breaks"] = break_slots
183+
return values

src/utils/parse.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,12 @@ def publishable_speakers(
3434
js = json.load(fd)
3535
all_speakers = [PretalxSpeaker.model_validate(s) for s in js]
3636

37-
speakers_with_publishable_sessions: list[PretalxSubmission] = []
37+
speakers_with_publishable_sessions: list[PretalxSpeaker] = []
3838
for speaker in all_speakers:
3939
if publishable_sessions := Utils.publishable_sessions_of_speaker(
4040
speaker, publishable_sessions_keys
4141
):
42-
speaker.submissions = publishable_sessions
42+
speaker.submissions = sorted(publishable_sessions)
4343
speakers_with_publishable_sessions.append(speaker)
4444

4545
publishable_speakers_by_code = {

src/utils/transform.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ def pretalx_speakers_to_europython_speakers(
8383
code=speaker.code,
8484
name=speaker.name,
8585
biography=speaker.biography,
86-
avatar=speaker.avatar,
86+
avatar=speaker.avatar_url,
8787
slug=speaker_code_to_slug[speaker.code],
8888
answers=speaker.answers,
8989
submissions=speaker.submissions,

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad © 2024 Your Company Name. All rights reserved.





Check this box to remove all script contents from the fetched content.



Check this box to remove all images from the fetched content.


Check this box to remove all CSS styles from the fetched content.


Check this box to keep images inefficiently compressed and original size.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy