Langzame API requests BAG en opvragen historie

Beste Geoforum lezers,

Ik ben bezig met alle verblijfobjecten binnen een bepaalde geomterie uit te vragen middels de BAG API die beschikbaar is.
Nu lukt dit allemaal in de code die ik heb geschreven, echter de code is niet bepaald snel, zelfs niet voor kleine geometrie met zon 90 objecten. Daarnaast vroeg ik mij ook af of je niet alleen de huidige geldende data van de verblijfobjecten kan uitvragen, maar ook gelijk alle geschiedenis. Ik weet dat je een parameter kunt meegeven die de data uitvraagt die geldig was op een specifieke datum, echter ik wil dat er juist niet wordt gefiltered op de geldigheidsdatum en alle records terug komen van een verblijfsobject ook die niet meer geldend zijn.
De code die ik gebruik:

url_verblijf = ‘https://bag.basisregistraties.overheid.nl/api/v1/verblijfsobjecten

headers = {
'X-Api-Key': 'X',
'Accept': 'application/hal+json',
'Accept-Crs': 'epsg:4258',
"Content-Type": "application/json"
}

df_ibis = read_or_write_data('IBIS_Bedrijventerreinnen', 'r')
#List of all industrial areas

#Tracks down industrial areas in the IBIS database which don't include a Polygon and therefore are deleted from our data
#Currently those areas are: 'DE STATIE (TOL-MORRES)', 'GIDEON NOORD', 'NOORDERKIJL I', 'HEULWEG'
wrong_names = df_ibis.loc[df_ibis['Geometrie'].isnull()]['Plannaam'].to_list()
if terrein in wrong_names:
    return []
#generate POST request query to retrieve all verblijfobjecten inside of a bedrijventerrein Polygon/MultiPolygon
query = geometrie_query(terrein, df_ibis)
#convert to json for POST request
json_data = json.dumps(query)
page = 1
end = 1
#Retrieve the data from the API
response = r.post(url_verblijf, data = json_data, headers=headers, params = {'page': page})
#Convert the response (a string) to a dictionary
verblijfobjecten = eval(response.content.decode('utf8').replace('null', "'null'").replace('false', 'False').replace('true', 'True'))
#Create dictionary to write the final results to.
results = {'id' : [], 'typeLabel' : [], 'straat' : [], 'huisnummer' : [], 'huisletter' : [], 'huisnummertoevoeging' : [], 'postcode' : [], 'woonplaats' : [], 'begin' : [], 'eind' : [], 'oppervlakte' : []}
while page <= end:
    #if there is no next page this is the final iuteration in the loop that needs to be executed
    if verblijfobjecten['_links']['next']['href'] == 'null':
        end = page - 1
    print(page)
    # print(verblijfobjecten['_links'])
    #Retrieve the oppervlakte from verblijfsobjecten and request the postcode from the URL provided in the verblijfobjecten request
    for v_object in verblijfobjecten['_embedded']['verblijfsobjecten']:
        #Verblijfsobjecten
        results['oppervlakte'].append(v_object['oppervlakte'])
        results['id'].append(v_object['identificatiecode'])
        doel = ''
        for functie in v_object['gebruiksdoel']:
            doel = doel + functie + ' | '
        results['typeLabel'].append(doel[:-3])
        results['begin'].append(v_object['_embedded']['geldigVoorkomen']['beginGeldigheid'])
        results['eind'].append(v_object['_embedded']['geldigVoorkomen']['eindGeldigheid'])
        #Nummeraanduidingen
        nummeraanduiding = r.get(v_object['_links']['hoofdadres']['href'], headers=headers)
        nummeraanduiding = eval(nummeraanduiding.content.decode('utf8').replace('null', "'null'").replace('false', 'False').replace('true', 'True'))
        results['postcode'].append(nummeraanduiding['postcode'])
        results['huisnummer'].append(nummeraanduiding['huisnummer'])
        results['huisletter'].append(nummeraanduiding['huisletter'])
        results['huisnummertoevoeging'].append(nummeraanduiding['huisnummertoevoeging'])
        #Openbareruimtes
        openbareruimte = r.get(nummeraanduiding['_links']['bijbehorendeOpenbareRuimte']['href'], headers=headers)
        openbareruimte = eval(openbareruimte.content.decode('utf8').replace('null', "'null'").replace('false', 'False').replace('true', 'True'))
        results['straat'].append(openbareruimte['naam'])
        #Woonplaatsen
        woonplaats = r.get(openbareruimte['_links']['bijbehorendeWoonplaats']['href'], headers=headers)
        woonplaats = eval(woonplaats.content.decode('utf8').replace('null', "'null'").replace('false', 'False').replace('true', 'True'))
        results['woonplaats'].append(woonplaats['naam'])
    page += 1
    end += 1
    #retrieve next page of data.
    verblijfobjecten = r.post(url_verblijf, data = json_data, headers=headers, params = {'page': page})
    verblijfobjecten = eval(verblijfobjecten.content.decode('utf8').replace('null', "'null'").replace('false', 'False').replace('true', 'True'))
results = pd.DataFrame(results)

Met vriendelijke groet,

Chris Hoekmeijer

Hallo Chris,

Het opvragen van de geschiedenis van een verblijfsobject kan niet in 1x, je zult dan per verblijfsobject alle voorkomen op moeten vragen. Dat kan op de volgende manier: https://bag.basisregistraties.overheid.nl/api/v1/verblijfsobjecten/0003010000125988/voorkomens

Wat betreft de snelheid van de code: om je hier beter met te kunnen helpen hebben we meer informatie nodig hoe lang je queries nu duren en wat de precieze queries (inclusief geometrie waar van toepassing) die je stuurt zijn.

Hoi Jasper,

Sorry voor de late reactie. Dank voor het antwoordt het is inderdaad gelukt via voorkomens de geschiedenis op te kunnen vragen per verblijfsobject. Om wat meer informatie te geven wat ik precies probeer te doen: Ik haal de geometrie van alle bedrijfsterreinen op in Nederland via IBIS (https://www.ibis-bedrijventerreinen.nl/) en sla dit op als .csv bestand. Daarna probeer ik per bedrijven terrein alle verblijfsobjecten op te halen via de BAG API. Bijvoorbeeld voor het terrein Hoogvliet, daar worden 95 objecten opgehaald die vandaag de dag geldig zijn. Dit duurt ongeveer 90 seconden. Nu is dit een relatief klein bedrijventerrein, en je kunt je voorstellen als we dit script gebruiken om alle panden uit te vragen die op alle bedrijventerreinen in Nederland liggen, dat het nog wel is vrij lang kan gaan duren voordat alles is opgehaald.
Hopelijk helpt deze informatie.

Groet,

Chris

Je doet een POST request om de verblijfsobjecten op te vragen, en dan per verblijfsobject nog een GET request voor nummeraanduiding, woonplaats, en openbare ruimte.

Om 95 verblijfsobjecten op te halen met de standaard pageSize van 20, doe je dus 5 POST requests + 3 x 95 GET requests; een totaal van 290 requests. Als je dat allemaal serieel doet, vind ik 90 seconden helemaal niet zo traag.

Als je je script sneller wil maken, zou je de loop over de verblijfsobjecten kunnen paralleliseren.