@ -34,61 +34,85 @@ def normalize_mp_name(
return name
_ODATA_BASE = " https://gegevensmagazijn.tweedekamer.nl/OData/v4/2.0 "
_PAGE_SIZE = 250
def fetch_mp_metadata (
db_path : str , odata_url : str = " https://odata.example/FractieZetelPersoon "
db_path : str ,
odata_url : str = f " { _ODATA_BASE } /FractieZetelPersoon " ,
) - > int :
""" Fetch MP party membership and tenure from OData and upsert into DB.
Paginates through all records using $ skip . Uses Fractie . Afkorting as
the party name so it matches the abbreviations used in mp_votes .
Returns the number of records processed ( inserted or updated ) .
"""
expand = " $expand=FractieZetel($expand=Fractie),Persoon "
session = requests . Session ( )
try :
resp = session . get ( odata_url )
resp . raise_for_status ( )
data = resp . json ( )
except Exception as e :
logger . error ( " Failed to fetch MP metadata: %s " , e )
raise
values = data . get ( " value " ) if isinstance ( data , dict ) else None
if values is None :
logger . error ( " Unexpected OData payload; missing ' value ' list " )
return 0
db = MotionDatabase ( db_path )
processed = 0
skip = 0
for item in values :
while True :
url = f " { odata_url } ? { expand } &$top= { _PAGE_SIZE } &$skip= { skip } "
try :
persoon = item . get ( " Persoon " ) or { }
fractiezetel = item . get ( " FractieZetel " ) or { }
fractie = fractiezetel . get ( " Fractie " ) or { }
achternaam = persoon . get ( " Achternaam " )
initialen = persoon . get ( " Initialen " )
tussenvoegsel = persoon . get ( " Tussenvoegsel " )
persoon_id = persoon . get ( " Id " )
party = fractie . get ( " NaamNL " )
van = item . get ( " Van " )
tot_en_met = item . get ( " TotEnMet " )
if not achternaam :
logger . debug ( " Skipping record without achternaam: %s " , item )
continue
mp_name = normalize_mp_name ( achternaam , initialen , tussenvoegsel )
db . upsert_mp_metadata (
mp_name = mp_name ,
party = party ,
van = van ,
tot_en_met = tot_en_met ,
persoon_id = persoon_id ,
)
processed + = 1
except Exception :
logger . exception ( " Error processing OData item: %s " , item )
resp = session . get ( url , timeout = 30 )
resp . raise_for_status ( )
data = resp . json ( )
except Exception as e :
logger . error ( " Failed to fetch MP metadata (skip= %d ): %s " , skip , e )
raise
values = data . get ( " value " ) if isinstance ( data , dict ) else None
if values is None :
logger . error ( " Unexpected OData payload at skip= %d ; missing ' value ' " , skip )
break
if not values :
break # no more pages
for item in values :
try :
if item . get ( " Verwijderd " ) :
continue
persoon = item . get ( " Persoon " ) or { }
fractiezetel = item . get ( " FractieZetel " ) or { }
fractie = fractiezetel . get ( " Fractie " ) or { }
achternaam = persoon . get ( " Achternaam " )
initialen = persoon . get ( " Initialen " )
tussenvoegsel = persoon . get ( " Tussenvoegsel " )
persoon_id = persoon . get ( " Id " )
# Use Afkorting (e.g. "VVD", "GroenLinks-PvdA") to match mp_votes party column
party = fractie . get ( " Afkorting " ) or fractie . get ( " NaamNL " )
van = item . get ( " Van " )
tot_en_met = item . get ( " TotEnMet " )
if not achternaam :
logger . debug ( " Skipping record without achternaam: %s " , item )
continue
mp_name = normalize_mp_name ( achternaam , initialen , tussenvoegsel )
db . upsert_mp_metadata (
mp_name = mp_name ,
party = party ,
van = van ,
tot_en_met = tot_en_met ,
persoon_id = persoon_id ,
)
processed + = 1
except Exception :
logger . exception ( " Error processing OData item: %s " , item )
logger . debug ( " Fetched page skip= %d , got %d records " , skip , len ( values ) )
if len ( values ) < _PAGE_SIZE :
break # last page
skip + = _PAGE_SIZE
logger . info ( " Processed %d MP metadata records " , processed )
return processed