HTTP-verzoeken zijn de basis van hoe het internet werkt. Wanneer je een website bezoekt of gegevens uit een API ophaalt, gebeurt dit met een HTTP-verzoek. Python biedt een geweldige bibliotheek, requests
, waarmee je eenvoudig met het web kunt communiceren.
Met requests
kun je gegevens ophalen, versturen, en zelfs communiceren met web-API’s zonder dat je je zorgen hoeft te maken over de technische details van het protocol. Laten we samen leren hoe je requests
gebruikt en begrijpen hoe HTTP werkt! 🚀
Wat is HTTP? (Een korte opfrisser) #
HTTP (Hypertext Transfer Protocol) is de taal waarmee clients (zoals je browser) en servers met elkaar communiceren. Elke HTTP-methode heeft een specifieke rol:
- GET: Vraag gegevens op van een server.
- POST: Stuur gegevens naar de server om iets te maken.
- PUT: Werk bestaande gegevens bij of voeg ze toe als ze nog niet bestaan.
- DELETE: Verwijder gegevens van de server.
Met Python’s requests
-bibliotheek kun je deze methoden eenvoudig uitvoeren.
HTTP-Verzoeken met requests
#
1. GET-verzoeken uitvoeren #
Een GET-verzoek gebruik je om gegevens op te halen. Denk aan het opvragen van een webpagina of het lezen van informatie uit een API.
Voorbeeld: Een webpagina ophalen
import requests
response = requests.get("https://jsonplaceholder.typicode.com/posts/1")
print(response.text)
PythonWat gebeurt hier?
requests.get()
stuurt een GET-verzoek naar de URL.- De server reageert met de gevraagde gegevens.
response.text
geeft de inhoud van de serverreactie als tekst.
Queryparameters toevoegen aan een GET-verzoek Met queryparameters kun je specifieke gegevens opvragen.
Voorbeeld:
params = {"userId": 1}
response = requests.get("https://jsonplaceholder.typicode.com/posts", params=params)
print(response.url)
# Toont de volledige URL met parameters
print(response.json())
# Geeft de reactie in JSON-formaat
Python2. POST-verzoeken uitvoeren #
Met een POST-verzoek kun je gegevens naar een server sturen. Dit wordt vaak gebruikt om formulieren in te dienen of gegevens naar een API te verzenden.
Voorbeeld: Gegevens versturen met een POST-verzoek
data = {"title": "Mijn Post", "body": "Dit is de inhoud", "userId": 1}
response = requests.post("https://jsonplaceholder.typicode.com/posts", json=data)
print(response.status_code)
# Controleer de statuscode
print(response.json())
# Reactie van de server in JSON-formaat
PythonWat gebeurt hier?
- De data wordt in JSON-formaat naar de server gestuurd.
- De server verwerkt de data en geeft een antwoord terug.
3. PUT-Verzoeken: Gegevens Bewerken of Toevoegen #
Een PUT-verzoek wordt gebruikt om een bestaande bron (bijvoorbeeld een item in een database) bij te werken. Als de bron nog niet bestaat, maakt de server deze vaak aan.
Voorbeeld: Een bestaand item bijwerken
Stel dat je een API hebt die blogposts beheert, en je wilt een post bijwerken.
import requests
# Gegevens die we willen bijwerken
data = {"title": "Gewijzigde titel", "body": "Bijgewerkte inhoud", "userId": 1}
# Verstuur een PUT-verzoek
response = requests.put("https://jsonplaceholder.typicode.com/posts/1", json=data)
# Controleer de status en toon de serverreactie
if response.status_code == 200:
print("Post bijgewerkt!")
print(response.json())
# Toont de bijgewerkte gegevens
else:
print(f"Fout: {response.status_code}")
PythonWat gebeurt hier?
- Het PUT-verzoek stuurt de nieuwe gegevens naar de server.
- De server verwerkt het verzoek en werkt de gegevens bij (of maakt een nieuwe bron aan als dat nodig is).
4. DELETE-Verzoeken: Gegevens Verwijderen #
Een DELETE-verzoek wordt gebruikt om gegevens van de server te verwijderen. Dit is handig voor het verwijderen van records in een database of bestanden op een server.
Voorbeeld: Een item verwijderen
Laten we een API gebruiken om een specifieke post te verwijderen.
import requests
# Verstuur een DELETE-verzoek
response = requests.delete("https://jsonplaceholder.typicode.com/posts/1")
# Controleer de status
if response.status_code == 200:
print("Post succesvol verwijderd!")
else:
print(f"Fout: {response.status_code}")
PythonWat gebeurt hier?
- Het DELETE-verzoek vertelt de server dat een bepaalde bron moet worden verwijderd.
- De server verwijdert de gegevens en stuurt een bevestiging terug.
Overzicht van alle HTTP-verzoeken #
Hier is een samenvatting van de vier methoden met voorbeelden:
HTTP-Methode | Gebruik | Voorbeeld |
GET | Vraag gegevens op van de server. | requests.get(“https://api.example.com/items“) |
POST | Stuur gegevens naar de server om iets nieuws te maken. | requests.post(“https://api.example.com/items“, json={“naam”: “Nieuw item”}) |
PUT | Werk bestaande gegevens bij of voeg ze toe als ze niet bestaan. | requests.put(“https://api.example.com/items/1“, json={“naam”: “Bijgewerkt item”}) |
DELETE | Verwijder gegevens van de server. | requests.delete(“https://api.example.com/items/1“) |
Headers en Authenticatie #
Met headers kun je extra informatie aan een verzoek toevoegen, zoals een API-sleutel of de voorkeur voor het gegevensformaat.
Voorbeeld: Headers toevoegen
headers = {"Authorization": "Bearer mijn_api_sleutel"}
response = requests.get("https://api.example.com/data", headers=headers)
print(response.status_code)
PythonFoutafhandeling en Statuscodes Begrijpen #
Bij het maken van HTTP-verzoeken is het belangrijk om de status van een reactie te controleren. HTTP gebruikt statuscodes om aan te geven of een verzoek is geslaagd.
Veelvoorkomende statuscodes #
- 200 OK: Het verzoek is geslaagd.
- 201 Created: Er is succesvol een nieuwe resource aangemaakt (bijvoorbeeld bij een POST-verzoek).
- 400 Bad Request: Het verzoek is ongeldig.
- 401 Unauthorized: Je hebt geen toestemming (bijvoorbeeld door een ontbrekende API-sleutel).
- 404 Not Found: De opgevraagde bron bestaat niet.
- 500 Internal Server Error: Er is iets misgegaan aan de kant van de server.
Voorbeeld: Statuscodes controleren
response = requests.get("https://jsonplaceholder.typicode.com/posts/99999")
if response.status_code == 200:
print("Succes!")
elif response.status_code == 404:
print("Niet gevonden!")
else:
print(f"Fout: {response.status_code}")
PythonWerken met JSON-gegevens #
Veel API’s sturen gegevens terug in JSON-formaat (JavaScript Object Notation), een gestructureerd formaat dat gemakkelijk te lezen en te verwerken is in Python.
Voorbeeld: JSON-antwoorden verwerken
response = requests.get("https://jsonplaceholder.typicode.com/posts/1")
data = response.json()
print(data)
print(data["title"])
# Toegang tot een specifiek veld
PythonTimeouts in HTTP-verzoeken: Wat, Waarom en Hoe? #
Wanneer je een HTTP-verzoek uitvoert, wacht je code standaard totdat de server een antwoord terugstuurt. Dit kan echter problemen veroorzaken als de server niet reageert of traag is. Hier komen timeouts om de hoek kijken. Met timeouts kun je ervoor zorgen dat je programma niet oneindig blijft wachten en in plaats daarvan na een bepaalde tijd stopt met proberen.
Wat is een timeout? #
Een timeout is een limiet voor hoe lang je wilt wachten op een reactie van een server. Als de server binnen die tijd geen antwoord geeft:
- Wordt een uitzondering (error) opgegooid.
- Kan je programma door met andere taken zonder vast te lopen.
Timeouts zijn belangrijk om je applicatie stabiel en responsief te houden, vooral bij API-aanroepen naar externe servers die je niet onder controle hebt.
Hoe stel je een timeout in met requests
? #
In de requests
-bibliotheek kun je een timeout instellen met de parameter timeout
. Deze geeft aan hoe lang je maximaal wilt wachten voordat je een foutmelding krijgt.
Basisvoorbeeld: Timeout instellen #
import requests
try:
response = requests.get("https://httpbin.org/delay/5", timeout=3)
# Maximaal 3 seconden wachten
print(response.status_code)
except requests.exceptions.Timeout:
print("De server reageerde niet op tijd.")
PythonWat gebeurt hier?
- De server probeert te reageren, maar als dit langer duurt dan 3 seconden, gooit
requests
eenTimeout
-fout. - Het programma stopt niet, maar geeft een nette foutmelding.
Soorten timeouts #
requests
biedt flexibiliteit om verschillende soorten timeouts in te stellen:
- Connect-timeout: Hoe lang je wacht tot een verbinding met de server tot stand komt.
- Read-timeout: Hoe lang je wacht om gegevens van de server te ontvangen.
Je kunt beide instellen met een tuple (connect_timeout, read_timeout)
.
Voorbeeld: Verschillende timeouts instellen
try:
response = requests.get(
"https://httpbin.org/delay/5",
timeout=(2, 4)
# 2 seconden voor verbinden, 4 seconden voor lezen
)
print(response.status_code)
except requests.exceptions.Timeout:
print("Timeout: De server reageerde niet binnen de opgegeven tijd.")
PythonBest Practices voor timeouts #
1. Stel altijd een timeout in #
Als je geen timeout instelt, kan je programma oneindig blijven wachten als de server niet reageert. Dit kan leiden tot vastlopers of slechte gebruikerservaringen.
# Vermijd dit: Geen timeout ingesteld
response = requests.get("https://example.com")
PythonAl wat beter (maar pas liever ook nog een try catch toe):
response = requests.get("https://example.com", timeout=5)
Python2. Gebruik realistische timeoutwaarden #
- Te kort: Een timeout van 0,5 seconde kan te agressief zijn en onnodige fouten veroorzaken.
- Te lang: Een timeout van 30 seconden kan je applicatie traag maken.
Aanbeveling: Gebruik een connect-timeout van 3-5 seconden en een read-timeout van 5-20 seconden, afhankelijk van je toepassing.
3. Foutafhandeling toevoegen #
Zorg ervoor dat je Timeout
-fouten afhandelt, zodat je programma niet crasht.
Voorbeeld: Foutafhandeling
try:
response = requests.get("https://example.com", timeout=5)
print(response.text)
except requests.exceptions.Timeout:
print("Timeout: De server reageert niet.")
except requests.exceptions.RequestException as e:
print(f"Een andere fout opgetreden: {e}")
PythonVeelvoorkomende Foutmeldingen/Uitzonderingen in requests
#
Uitzondering | Beschrijving |
requests.exceptions.Timeout | De server reageerde niet binnen de opgegeven tijd. |
requests.exceptions.ConnectionError | Er is een probleem opgetreden bij het maken van de verbinding met de server. |
requests.exceptions.HTTPError | De server retourneerde een HTTP-foutstatuscode (bijvoorbeeld 404 of 500). |
requests.exceptions.TooManyRedirects | Er waren te veel omleidingen (bijvoorbeeld een oneindige redirect-lus). |
requests.exceptions.RequestException | De algemene basisklasse voor alle fouten in requests. Alle andere uitzonderingen erven hiervan. |
requests.exceptions.InvalidURL | De opgegeven URL is ongeldig of verkeerd geformatteerd. |
requests.exceptions.SSLError | Er is een probleem opgetreden bij het verifiëren van het SSL-certificaat van de server. |
requests.exceptions.ProxyError | Er is een probleem opgetreden bij het gebruik van een proxyserver (bijvoorbeeld verbinding mislukt). |
requests.exceptions.ChunkedEncodingError | De server verstuurde een beschadigde of onvolledige chunk tijdens het streamen van data. |
Wanneer zijn timeouts belangrijk? #
- Werken met externe API’s
Als je een API aanroept die je niet onder controle hebt, kunnen timeouts je beschermen tegen servers die niet reageren. - Batchverwerking van meerdere verzoeken
Bij een grote hoeveelheid HTTP-verzoeken wil je niet dat één trage server de hele batch ophoudt. - Applicaties met gebruikersinterface (UI)
Voor toepassingen zoals webapps of mobiele apps zorgt een timeout voor een betere gebruikerservaring door te voorkomen dat de app vastloopt. - Kritieke systemen
In real-time systemen of applicaties waarbij vertraging schadelijk kan zijn, zijn strikte timeouts essentieel.
Werken met SSL in requests
#
SSL (Secure Sockets Layer) is een cryptografisch protocol dat zorgt voor een veilige verbinding tussen een client (bijvoorbeeld je browser of applicatie) en een server. Wanneer je een website bezoekt via HTTPS, wordt SSL gebruikt om gegevens zoals wachtwoorden en API-sleutels te beschermen tegen onderschepping.
De requests
-bibliotheek maakt het eenvoudig om met HTTPS te werken, inclusief het controleren van SSL-certificaten. In deze gids behandelen we hoe requests
met SSL omgaat, wat je kunt doen bij SSL-problemen, en hoe je SSL-gerelateerde opties configureert.
Wat doet requests
automatisch met SSL? #
Wanneer je een HTTPS-verzoek uitvoert met requests
, controleert het automatisch het SSL-certificaat van de server. Als het certificaat geldig is, wordt de verbinding veilig tot stand gebracht. Als het certificaat ongeldig is (bijvoorbeeld verlopen, zelfondertekend, of niet vertrouwd), wordt een uitzondering opgegooid: requests.exceptions.SSLError
.
Veelvoorkomende SSL-situaties #
1. Geldig SSL-certificaat #
Met een geldig certificaat gebeurt er niets speciaals – je verzoek wordt uitgevoerd zoals verwacht.
2. Ongeldig SSL-certificaat #
Als een server een ongeldig of verlopen certificaat heeft, wordt een SSLError
opgegooid.
Voorbeeld:
import requests
try:
response = requests.get("https://expired.badssl.com/")
except requests.exceptions.SSLError as e:
print(f"SSL-fout opgetreden: {e}")
PythonVeelvoorkomende oorzaken van SSL-fouten:
- Verlopen certificaat: Het certificaat van de server is niet meer geldig.
- Zelfondertekend certificaat: Het certificaat is niet uitgegeven door een vertrouwde autoriteit.
- Verkeerde domeinnaam: Het certificaat is niet bedoeld voor het opgevraagde domein.
SSL-certificaatvalidatie uitschakelen #
In sommige situaties, zoals bij zelfondertekende certificaten tijdens ontwikkeling, wil je de certificaatvalidatie uitschakelen (doe dit nooit in productie). Je kunt dit doen met de parameter verify=False
.
Voorbeeld: Validatie uitschakelen
import requests
response = requests.get("https://self-signed.badssl.com/", verify=False)
print("Statuscode:", response.status_code)
Python⚠️ Waarschuwing:
Het uitschakelen van SSL-verificatie is onveilig en moet alleen worden gebruikt in gecontroleerde omgevingen, zoals lokaal testen. Voor productiegebruik is dit sterk af te raden.
Werken met aangepaste certificaten #
Soms wil je een specifiek SSL-certificaat of een certificeringsketen gebruiken. Dit kan met de parameter verify
door een pad naar een certificaatbestand (.pem
) op te geven.
Voorbeeld: Aangepast certificaat gebruiken
import requests
response = requests.get("https://example.com", verify="/pad/naar/certificaat.pem")
print("Statuscode:", response.status_code)
PythonWerken met een SSL-certificaat als string #
In plaats van een bestandspad naar een .pem
-certificaat te geven, kun je het certificaat als string laden en een in-memory bestand creëren met de io
-module.
Voorbeeld: SSL-certificaat in stringformaat
import requests
import io
# Het SSL-certificaat als string (bijvoorbeeld opgehaald uit een database of variabele)
certificaat = """
-----BEGIN CERTIFICATE-----
MIIDXTCCAkWgAwIBAgIJAOsoUVFnROriMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
...
w0BAQsFADBFMQswCQYDVQQGEwJVUzELMAkGA1UECAwCV0ExETAPBgNVBAcMCE5l
...
-----END CERTIFICATE-----
"""
# Zet de string om naar een in-memory bestand
certificaat_in_memory = io.StringIO(certificaat)
# Gebruik het in-memory bestand als het "verify"-parameter in requests
response = requests.get("https://example.com", verify=certificaat_in_memory)
print("Statuscode:", response.status_code)
PythonHoe werkt dit? #
- Certificaat als string:
Het certificaat is opgeslagen in een stringvariabele in PEM-formaat (tekstformaat met begin- en eindmarkeringen). - Gebruik van
io.StringIO
:StringIO
maakt een in-memory bestand van de string, zodat het functioneert alsof het een fysiek bestand is. - Invoer voor
verify
:
De parameterverify
accepteert nu het in-memory bestand als bron voor het certificaat.
SSL-opties instellen #
Je kunt meer controle krijgen over SSL door een aangepaste SSLContext te gebruiken. Dit is handig voor gevorderde configuraties, zoals het aanpassen van de ondersteunde TLS-versies.
Voorbeeld: SSLContext gebruiken
import requests
import ssl
from requests.adapters import HTTPAdapter
from urllib3.poolmanager import PoolManager
class SSLAdapter(HTTPAdapter):
def __init__(self, ssl_context=None, **kwargs):
self.ssl_context = ssl_context
super().__init__(**kwargs)
def init_poolmanager(self, *args, **kwargs):
kwargs["ssl_context"] = self.ssl_context
return super().init_poolmanager(*args, **kwargs)
# Stel SSLContext in
context = ssl.create_default_context()
context.minimum_version = ssl.TLSVersion.TLSv1_2
# Sta alleen TLS 1.2 of hoger toe
# Gebruik de aangepaste context
session = requests.Session()
session.mount("https://", SSLAdapter(ssl_context=context))
response = session.get("https://www.example.com")
print("Statuscode:", response.status_code)
PythonBest Practices voor SSL met requests
#
- Altijd certificaatvalidatie gebruiken in productie:
Gebruik nooitverify=False
in productieomgevingen. - Log SSL-fouten duidelijk:
Zorg dat je applicatie foutmeldingen zoalsSSLError
op een begrijpelijke manier rapporteert. - Gebruik aangepaste certificaten in beveiligde omgevingen:
Als je zelfondertekende certificaten gebruikt, voeg deze toe aan je vertrouwde certificaten en gebruik ze met de parameterverify
. - Werk met de nieuwste TLS-versies:
GebruikSSLContext
om oude, onveilige versies van TLS uit te schakelen (bijvoorbeeld TLS 1.0 en TLS 1.1).
Een Praktisch Voorbeeld: API-data ophalen en verwerken #
Laten we een voorbeeld maken waarbij we gegevens ophalen van een API en deze verwerken.
Doel: Haal alle posts op van een specifieke gebruiker en toon alleen de titels.
Dit script haalt gegevens op van een API, controleert of het verzoek geslaagd is, en toont de titels van alle posts van een specifieke gebruiker. Het bevat foutafhandeling voor verschillende HTTP- en SSL-gerelateerde problemen.
Code:
import requests
from requests.exceptions import HTTPError, Timeout, ConnectionError, SSLError
def fetch_user_posts(user_id, timeout=5):
"""
Haalt posts op van een specifieke gebruiker en toont de titels.
Parameters:
user_id (int): De ID van de gebruiker.
timeout (int): De tijdslimiet voor het verzoek (standaard 5 seconden).
Returns:
None
"""
url = "https://jsonplaceholder.typicode.com/posts"
params = {"userId": user_id}
try:
# Stap 1: Verstuur een GET-verzoek
response = requests.get(url, params=params, timeout=timeout)
response.raise_for_status() # Controleer of de statuscode een fout is
# Stap 2: Verwerk het antwoord
posts = response.json()
if not posts:
print(f"Geen posts gevonden voor gebruiker met ID {user_id}.")
return
# Stap 3: Toon de titels van de posts
print(f"Titels van posts voor gebruiker ID {user_id}:")
for post in posts:
print(f"- {post['title']}")
except HTTPError as http_err:
print(f"HTTP-fout opgetreden: {http_err}")
except ConnectionError as conn_err:
print(f"Verbindingsfout: Kan geen verbinding maken met de server. Details: {conn_err}")
except SSLError as ssl_err:
print(f"SSL-fout opgetreden: {ssl_err}")
except Timeout:
print(f"Timeout: De server reageerde niet binnen de opgegeven tijd van {timeout} seconden.")
except Exception as err:
print(f"Een onverwachte fout is opgetreden: {err}")
# Roep de functie aan
fetch_user_posts(user_id=1)
PythonOutput bij succes::
Titels van posts:
- Eerste post
- Tweede post
- Derde post
PythonBij een timeout:
Timeout: De server reageerde niet binnen de opgegeven tijd van 5 seconden.
PythonBij een verbinding met een onbereikbare server:
Verbindingsfout: Kan geen verbinding maken met de server. Details: HTTPSConnectionPool(host='jsonplaceholder.typicode.com', port=443): Max retries exceeded...
PythonBij een foutstatuscode:
HTTP-fout opgetreden: 404 Client Error: Not Found for url: https://jsonplaceholder.typicode.com/posts
PythonWaarom requests
gebruiken voor HTTP-verzoeken? #
- Eenvoudig te gebruiken: De syntaxis is intuïtief en krachtig.
- Flexibel: Ondersteunt headers, queryparameters, en JSON-data.
- Betrouwbaar: Behandelt automatisch redirects, fouten, en encoding.
Samenvatting #
Met de requests
-bibliotheek kun je elke HTTP-methode uitvoeren:
- GET: Gegevens ophalen.
- POST: Nieuwe gegevens aanmaken.
- PUT: Gegevens bijwerken of toevoegen.
- DELETE: Gegevens verwijderen.
Het begrijpen van deze methoden geeft je de tools om krachtige applicaties te bouwen die moeiteloos communiceren met servers en API’s. Begin met kleine experimenten en werk naar grotere projecten toe, zoals het bouwen van je eigen API-client! 🎉🚀