11import json
22from datetime import datetime
33
4- from pydantic import BaseModel , Field
5- from pydantic .class_validators import root_validator
4+ from pydantic import BaseModel , Field , model_validator
65from slugify import slugify
76
87from src .config import Config
@@ -35,7 +34,8 @@ class PretalxAnswer(BaseModel):
3534 submission_id : str | None
3635 speaker_id : str | None
3736
38- @root_validator (pre = True )
37+ @model_validator (mode = "before" )
38+ @classmethod
3939 def extract (cls , values ):
4040 values ["question_text" ] = values ["question" ]["question" ]["en" ]
4141 values ["answer_text" ] = values ["answer" ]
@@ -60,11 +60,12 @@ class PretalxSpeaker(BaseModel):
6060 twitter : str | None = None
6161 mastodon : str | None = None
6262
63- @root_validator (pre = True )
63+ @model_validator (mode = "before" )
64+ @classmethod
6465 def extract (cls , values ):
6566 values ["slug" ] = slugify (values ["name" ])
6667
67- answers = [PretalxAnswer .parse_obj (ans ) for ans in values ["answers" ]]
68+ answers = [PretalxAnswer .model_validate (ans ) for ans in values ["answers" ]]
6869
6970 for answer in answers :
7071 if answer .question_text == SpeakerQuestion .affiliation :
@@ -107,16 +108,16 @@ class PretalxSubmission(BaseModel):
107108 start : datetime | None = None
108109 end : datetime | None = None
109110
110- # TODO: once we have schedule data then we can prefill those in the code
111- # here
111+ # TODO: once we have schedule data then we can prefill those in the code here
112112 talks_in_parallel : list [str ] | None = None
113113 talks_after : list [str ] | None = None
114114 next_talk_code : str | None = None
115115 prev_talk_code : str | None = None
116116
117117 website_url : str | None = None
118118
119- @root_validator (pre = True )
119+ @model_validator (mode = "before" )
120+ @classmethod
120121 def extract (cls , values ):
121122 # # SubmissionType and Track have localised names. For this project we
122123 # # only care about their english versions, so we can extract them here
@@ -132,7 +133,7 @@ def extract(cls, values):
132133
133134 values ["speakers" ] = sorted ([s ["code" ] for s in values ["speakers" ]])
134135
135- answers = [PretalxAnswer .parse_obj (ans ) for ans in values ["answers" ]]
136+ answers = [PretalxAnswer .model_validate (ans ) for ans in values ["answers" ]]
136137
137138 for answer in answers :
138139 # TODO if we need any other questions
@@ -148,6 +149,10 @@ def extract(cls, values):
148149 if answer .question_text == SubmissionQuestion .level :
149150 values ["level" ] = answer .answer_text .lower ()
150151
152+ # Convert duration to string for model validation
153+ if isinstance (values ["duration" ], int ):
154+ values ["duration" ] = str (values ["duration" ])
155+
151156 slug = slugify (values ["title" ])
152157 values ["slug" ] = slug
153158 values ["website_url" ] = f"https://ep2024.europython.eu/session/{ slug } "
@@ -173,11 +178,7 @@ def parse_submissions() -> list[PretalxSubmission]:
173178 """
174179 with open (Config .raw_path / "submissions_latest.json" ) as fd :
175180 js = json .load (fd )
176- subs = []
177- for item in js :
178- sub = PretalxSubmission .parse_obj (item )
179- subs .append (sub )
180-
181+ subs = [PretalxSubmission .model_validate (item ) for item in js ]
181182 return subs
182183
183184
@@ -187,11 +188,7 @@ def parse_speakers() -> list[PretalxSpeaker]:
187188 """
188189 with open (Config .raw_path / "speakers_latest.json" ) as fd :
189190 js = json .load (fd )
190- speakers = []
191- for item in js :
192- speaker = PretalxSpeaker .parse_obj (item )
193- speakers .append (speaker )
194-
191+ speakers = [PretalxSpeaker .model_validate (item ) for item in js ]
195192 return speakers
196193
197194
@@ -217,7 +214,7 @@ def save_publishable_sessions():
217214
218215 publishable = publishable_submissions ()
219216
220- data = {k : v .dict () for k , v in publishable .items ()}
217+ data = {k : v .model_dump () for k , v in publishable .items ()}
221218 with open (path , "w" ) as fd :
222219 json .dump (data , fd , indent = 2 )
223220
@@ -228,16 +225,16 @@ def save_publishable_speakers():
228225 publishable = publishable_submissions ()
229226 speakers = publishable_speakers (publishable .keys ())
230227
231- data = {k : v .dict () for k , v in speakers .items ()}
228+ data = {k : v .model_dump () for k , v in speakers .items ()}
232229 with open (path , "w" ) as fd :
233230 json .dump (data , fd , indent = 2 )
234231
235232
236- assert len (set (s .slug for s in publishable_submissions ().values ())) == len (
237- publishable_submissions ()
238- )
239-
240233if __name__ == "__main__" :
234+ print ("Checking for duplicate slugs..." )
235+ assert len (set (s .slug for s in publishable_submissions ().values ())) == len (
236+ publishable_submissions ()
237+ )
241238 print ("Saving publishable data..." )
242239 save_publishable_sessions ()
243240 save_publishable_speakers ()
0 commit comments