BGT download via API python

Ik probeer via een API request de data van de BGT binnen te halen via de endpoint beschreven in deze server:
https://api.pdok.nl/lv/bgt/download/v1_0/ui/

Het opzetten van de post request verloopt goed echter krijg ik bij de get request de status code:

{
	"_links": {
		"self": {
			"href": "/lv/bgt/download/v1_0/full/custom/ccaba172-fa89-4e96-5582-74123a803036/status"
		}
	},
	"progress": 0,
	"status": "PENDING"
}

Hierbij geeft het dus aan dat de download nog niet gereed is terwijl de server wel lijkt te werken.
Als ik namelijk handmatig een gebied probeer te downloaden gaat dat goed en als ik die download link van de handmatige methode in de GET-request doe, wordt het bestand ook gedownload. Weet iemand wat er hier mogelijk fout gaat?

1 like

Dank voor de melding, we zijn er naar aan het kijken.

1 like

Als ik naar de link: https://api.pdok.nl/lv/bgt/download/v1_0/full/custom/ccaba172-fa89-4e96-5582-74123a803036/status ga staat de download inmiddels op COMPLETED, deze url is bedoeld om te pollen (dus hooguit om de paar seconden te bevragen tot deze van PENDING overgaat naar COMPLETED) . En om dus te controleren of de download klaar is.

Nu de download op COMPLETED staat is er een download url te vinden in dat zelfde bericht:
https://api.pdok.nl/lv/bgt/download/v1_0/extract/606a9b93-2199-4e00-be0c-1fab674e25a7/extract.zip

Dat bestand is dan ook te downloaden.

Ik hoor het graag als bovenstaande niet helemaal je vraag beantwoord.

1 like

Bij mij lijkt het wel alsof de download alleen maar op pending blijft staan.

De code die ik gebruik is:
url=“https://api.pdok.nl/lv/bgt/download/v1_0/full/custom”

settings={
“featuretypes”: [
“bak”,
“begroeidterreindeel”,
“bord”,
“buurt”,
“functioneelgebied”,
“gebouwinstallatie”,
“installatie”,
“kast”,
“kunstwerkdeel”,
“mast”,
“onbegroeidterreindeel”,
“ondersteunendwaterdeel”,
“ondersteunendwegdeel”,
“ongeclassificeerdobject”,
“overbruggingsdeel”,
“overigbouwwerk”,
“overigescheiding”,
“paal”,
“pand”,
“plaatsbepalingspunt”,
“sensor”,
“spoor”,
“stadsdeel”,
“straatmeubilair”,
“tunneldeel”,
“vegetatieobject”,
“waterdeel”,
“waterinrichtingselement”,
“waterschap”,
“wegdeel”,
“weginrichtingselement”,
“wijk”
],
“format”: “citygml”,
“geofilter”: “POLYGON(({} {},{} {},{} {},{} {},{} {}))”.format(rd_box[0], rd_box[1], rd_box[0], rd_box[3], rd_box[2], rd_box[3], rd_box[2], rd_box[1], rd_box[0], rd_box[1])
}

#doe een POST-request
x=requests.post(url,json=settings)
response_post=x.text
word=“downloadRequestId”
a=response_post.rfind(word)
b=a+20
requestid=str(response_post[b:-2])
url=“https://api.pdok.nl/lv/bgt/download/v1_0/full/custom/"+requestid+"/status”
OUT=[x.status_code,response_post,requestid,url]

Hieruit krijg ik:
[0] 202
[1] {"_links":{“status”:{“href”:"/lv/bgt/download/v1_0/full/custom/8d16775c-a77f-42e0-68d5-f83ef76b803b/status"}},“downloadRequestId”:“8d16775c-a77f-42e0-68d5-f83ef76b803b”}
[2] 8d16775c-a77f-42e0-68d5-f83ef76b803b
[3] https://api.pdok.nl/lv/bgt/download/v1_0/full/custom/8d16775c-a77f-42e0-68d5-f83ef76b803b/status

Deze laatste url gebruik ik vervolgens in de GET-request waarbij ik een loop gebruik om de request te blijven uitvoeren tot de status_code 201 (bestand gereed om te downloaden)

response=requests.get(url)

while response.status_code == 200:
time.sleep(3) # wait for 3 seconds before trying again
response = requests.get(url)

#als de GET-request gereed is, voer dan de tekst uit die terug komt
if response.status_code == 201:
OUT=response.text

Mogelijk doe ik wat fout in de code, zien jullie misschien wat dat dan is?

Op zich ben je op de goede weg volgens mij als ik met een schuin oog naar je code kijk. Het draait echter niet om de status code 200 of 201; maar om de status in de response json. Ik zou
met de json output van de response checken wat de status is in de json. Als die COMPLETED is, kan je downloaden.

Zie hier: de status in de repsonse:
https://api.pdok.nl/lv/bgt/download/v1_0/full/custom/8d16775c-a77f-42e0-68d5-f83ef76b803b/status

-edit- je code moet dus nog ietsjes langer wachten -edit-

-edit- dit klopt niet ik kijk nog even verder-edit-

Hmmm. Op dat punt is de documentatie dan toch enigszins verwarrend. Want daaruit lijkt het alsof HTTP-code 201 betekent dat het bestand klaar staat om te downloaden, en HTTP 201 Created bevestigd dat. Als dat dus niet zo hoeft te zijn, dat je een HTTP-200 kunt krijgen als je bestand klaar staat om te downloaden, zou dan wel in de documentatie opgenomen moeten worden denk ik. Ik heb geen nut aan de BGT, dus ik hoef 'm ook niet te downloaden, maar ik vrees dat ik hier ook in getrapt zou zijn…

Ik denk dat het aan mijn de python engine ligt op een of andere manier (ookal zou dat heel raar zijn) Deze link krijg ik namelijk nu eruit maar als ik deze link in mijn webbrowser stop, is die wel completed

[0] 200
[1] {"_links":{“self”:{“href”:"/lv/bgt/download/v1_0/full/custom/a50cd576-0fd8-4037-4875-cb38d5a2becb/status"}},“progress”:0,“status”:“PENDING”}

Je hebt gelijk @sbjager wat ik schrijf over die 201 klopt niet. Daar had ik niet goed naar gekeken. Ik ga er even verder in duiken.

Het is mij gelukt, het heeft inderdaad met de tijd te maken die nodig is om de link voor te bereiden. Door een andere module+driver te gebruiken, en de loop om te vormen naar een situatie waarbij hij iedere seconde de pagina refreshed totdat het woord “COMPLETE” erin voorkomt, kan ik wel de juiste output krijgen!

Dit is de code die nu goed lijkt te werken:

url2=“https://api.pdok.nl/lv/bgt/download/v1_0/full/custom/"+requestid+"/status”

driver = webdriver.Chrome()

while True:
driver.get(url2)
if “COMPLETED” in driver.page_source:
page_source = driver.page_source
driver.quit()
break
time.sleep(1)

2 likes

@DRH bij deze het vriendelijke verzoek om code in markdown code formatting blocks op te nemen, met drievoudige backticks ( `), en je kan ook taal specifieke syntax highlighting toevoegen:

image

Resulteert in:

url2=“https://api.pdok.nl/lv/bgt/download/v1_0/full/custom/"+requestid+"/status”

driver = webdriver.Chrome()

while True:
    driver.get(url2)
    if “COMPLETED” in driver.page_source:
        page_source = driver.page_source
        driver.quit()
        break
    time.sleep(1)

Dit maakt posts met code een stuk overzichtelijker.

Yes, zal ik doen. Ik zit nog niet zolang op het forum dus bedankt voor de tip!

2 likes

Kan je mij toevallig ook vertellen hoe ik de tab in de code op het forum kan verwerken want daar kom ik niet echt uit (of verwijzen naar een pagina waar dit te vinden is)?

Aah, voor zover ik weet kan je geen tab karakters opnemen in markdown en zal je tabs moeten vervangen met spaties. Kennelijk kan je wel een &emp; karakter opnemen wat lijkt op een tab en zal een witruimte van 4 spaties weergeven, zie stackoverflow.

Overigens gebruikt Python standaard 4 spaces als indentatie eenheid. Dus Python code met 4 spaties kan je zo copy-pasten in de editor van het Geoforum. Ik heb bovenstaande voorbeeld aangepast met spatises (alhoewel ik niet helemaal zeker weet of de indentiate zo correct is).

Dit topic is 180 dagen na het laatste antwoord automatisch gesloten. Nieuwe antwoorden zijn niet meer toegestaan.