In een aantal eerdere tutorials heb je al geleerd over requests
, een Python library om HTTP-verzoeken mee te maken. Bijvoorbeeld in Werken met JSON kwam dit aan de orde. In dat voorbeeld download je data van het CBS met een functie get_data
en sla je het op in een bestand. Roep je de functie nogmaals aan met refresh=False
, dan download je de data niet nogmaals van het CBS, maar lees je het direct uit het bestand. De functie ziet er zo uit:
Alle code van dit project is ook op Github te bekijken. Omdat deze respository in meerdere tutorials wordt gebruikt, zijn er meerdere branches. Zorg dat je voor deze tutorial versie-2 kiest.
main.py
import json
import requests
URL = "https://opendata.cbs.nl/ODataApi/odata/85496NED/TypedDataSet"
def get_data(refresh=True):
if not refresh:
try:
with open("data.json") as f:
data = json.load(f)
except FileNotFoundError:
print("Bestand niet gevonden, downloaden")
# Roep deze functie aan, met `refresh=True`
return get_data(refresh=True)
else:
response = requests.get(URL)
# Als de HTTP-code 400 of hoger is, zal er een uitzondering worden opgeworpen
response.raise_for_status()
data = response.json()
# Sla bestand op
with open("data.json", "w") as f:
json.dump(data, f, indent=2)
return data
Dit werkt prima, maar er is een handigere manier. Met requests-cache stel je eenvoudig in hoe lang je de HTTP-responses wilt cachen. Vervolgens kun je de code gelijk houden, en zal bijvoorbeeld een GET
alleen uitgevoerd worden als de cache verlopen is.
Bovenstaand voorbeeld kun je eerst herschrijven naar een eenvoudigere versie zonder (handmatige) caching:
main
import json
import requests
URL = "https://opendata.cbs.nl/ODataApi/odata/85496NED/TypedDataSet"
def get_data():
response = requests.get(URL)
# Als de HTTP-code 400 of hoger is, zal er een uitzondering worden opgeworpen
response.raise_for_status()
data = response.json()
# Sla bestand op
with open("data.json", "w") as f:
json.dump(data, f, indent=2)
return data
Vervolgens voeg je een cache toe met requests-cache
.
main
from datetime import datetime, timedelta
import json
import requests_cache
URL = "https://opendata.cbs.nl/ODataApi/odata/85496NED/TypedDataSet"
now = datetime.now()
tonight = datetime(now.year, now.month, now.day) + timedelta(days=1)
def get_data():
session = requests_cache.CachedSession(expire_after=tonight)
response = session.get(URL)
# Als de HTTP-code 400 of hoger is, zal er een uitzondering worden opgeworpen
response.raise_for_status()
data = response.json()
# Sla bestand op
with open("data.json", "w") as f:
json.dump(data, f, indent=2)
return data
Boven de functie definieer je eerst tonight
, ingesteld op 00:00 van de volgende dag. Dus roep je het script op 11 maart om 15:00 aan, dan is tonight
gelijk aan 12 maart, 00:00.
In plaats van response = requests.get(url)
maak je de HTTP-request met response = session.get(url)
. Die sessie maak je eerst aan, en je stelt in wanneer de cache moet verlopen. In dit geval stel je het in op tonight
(00:00).
De rest van de functie hou je gelijk.
Roep je deze functie nu meerdere malen aan op een dag, dan zal het de eerste keer de data downloaden, maar bij elke volgende aanroep de opgeslagen response gebruiken. Roep je de functie een dag later weer aan (na 00:00), dan zal het de data de eerste keer wel weer downloaden.
Standaard gebruikt requests-cache
een sqlite database om de response in op te slaan. Lees de documentatie om te leren hoe je andere opslagmethoden gebruikt en om meer te leren over requests-cache
.
Alle code van dit project is ook op Github te bekijken. Omdat deze respository in meerdere tutorials wordt gebruikt, zijn er meerdere branches. Zorg dat je voor deze tutorial versie-2 kiest.