Cache je HTTP requests

Cache je HTTP requests

11 maart 2024
Erwin Matijsen
Geplaatst in Tip
Onderdeel van Werken met JSON


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.

Lees alle tutorials in deze reeks: Werken met JSON

Over de auteur


Erwin Matijsen

Erwin Matijsen

Erwin is de oprichter van python-cursus.nl. In allerlei rollen heeft hij Python ingezet, van het eenvoudiger maken van zijn werk tot het opleveren van complete (web)applicaties. Met vrouw en kinderen woont hij in Havelte (Drenthe), midden in de prachtige natuur. Daar wandelt hij graag, zeker ook omdat de beste ingevingen tijdens een wandeling - weg van de computer - lijken te komen.



Contact

Vragen, opmerkingen?

Heb je vragen, opmerkingen, suggesties of tips naar aanleiding van deze blog? Neem dan contact met ons op, of laat het weten via Mastodon of LinkedIN.