Tilbake
4.2
Hente data fra API-er

4.2 Hente data fra API-er

Bruke requests-biblioteket til å hente og behandle data.

60 min
6 oppgaver
RequestsGETAutentiseringStatuskoder
Du leser den tradisjonelle versjonen
Din fremgang i kapitlet
0 / 6 oppgaver

No som vi veit kva eit API er, skal vi lære å bruke det i Python. For å kommunisere med API-ar brukar vi requests-biblioteket, som gjer det enkelt å sende HTTP-førespurnader og motta svar.

I dette kapittelet skal vi:
- Installere og bruke requests-biblioteket
- Sende GET-førespurnader til API-ar
- Handtere svar og feilmeldingar
- Arbeide med API-nøklar
- Parse JSON-data

requests er ikkje inkludert i standard Python, så vi må installere det først.

Installasjon:

pip install requests

Når det er installert, kan vi importere det i Python-programmet vårt:

import requests

Dette gjev oss tilgang til alle funksjonane vi treng for å kommunisere med API-ar.

✏️Eksempel: Din første API-førespurnad

Lat oss hente data frå JSONPlaceholder, eit gratis test-API:

import requests

# Send GET-forespørsel til API-et
response = requests.get('https://jsonplaceholder.typicode.com/posts/1')

# Sjekk statuskoden
print(f"Statuskode: {response.status_code}")

# Hent JSON-data
data = response.json()

# Vis dataene
print(f"Tittel: {data['title']}")
print(f"Innhold: {data['body']}")

Output:

Statuskode: 200
Tittel: sunt aut facere repellat provident...
Innhold: quia et suscipit suscipit recusandae...

Forklaring:
- requests.get() sender ein GET-førespurnad
- response.status_code gjev HTTP-statuskoden (200 = OK)
- response.json() konverterer JSON-svaret til ein Python-dictionary

HTTP-statuskodar

HTTP-statuskodar fortel oss om førespurnaden var vellukka eller ikkje:

2xx – Suksess:
- 200 OK: Førespurnaden var vellukka
- 201 Created: Ny ressurs vart oppretta

4xx – Klientfeil:
- 400 Bad Request: Ugyldig førespurnad
- 401 Unauthorized: Manglar autentisering
- 404 Not Found: Ressursen finst ikkje

5xx – Serverfeil:
- 500 Internal Server Error: Serverfeil
- 503 Service Unavailable: Tenesta er utilgjengeleg

Vi bør alltid sjekke statuskoden før vi handsamar dataene.

✏️Eksempel: Handtere statuskodar

Her er korleis vi kan sjekke om førespurnaden var vellukka:

import requests

url = 'https://jsonplaceholder.typicode.com/posts/1'
response = requests.get(url)

if response.status_code == 200:
    print("Suksess! Data mottatt.")
    data = response.json()
    print(data)
elif response.status_code == 404:
    print("Feil 404: Ressursen finnes ikke.")
else:
    print(f"Noe gikk galt. Statuskode: {response.status_code}")

Eller bruk try-except:

import requests

try:
    response = requests.get(url, timeout=5)
    response.raise_for_status()  # Kaster exception hvis statuskode er 4xx eller 5xx
    data = response.json()
    print(data)
except requests.exceptions.HTTPError as e:
    print(f"HTTP-feil: {e}")
except requests.exceptions.ConnectionError:
    print("Kunne ikke koble til serveren.")
except requests.exceptions.Timeout:
    print("Forespørselen tok for lang tid.")
except requests.exceptions.RequestException as e:
    print(f"Feil: {e}")

Dette er god praksis for å handtere feil på ein elegant måte.

Mange API-ar lèt deg sende query-parametrar for å filtrere eller tilpasse dataene du får tilbake.

Eksempel-URL med parametrar:

https://api.example.com/search?q=python&limit=10

Her er:
- q=python ein parameter som søkjer etter "python"
- limit=10 ein parameter som avgrensar resultatet til 10 treff

I requests:
Du kan sende parametrar på to måtar:

1. I URL-en direkte:

response = requests.get('https://api.example.com/search?q=python&limit=10')

2. Som ein dictionary (anbefalt):

params = {
    'q': 'python',
    'limit': 10
}
response = requests.get('https://api.example.com/search', params=params)

Den andre metoden er meir lesbar og handterer spesialteikn automatisk.

✏️Eksempel: Værdata med parametrar

Lat oss hente værdata for Oslo frå Open-Meteo API:

import requests

# Base-URL
url = 'https://api.open-meteo.com/v1/forecast'

# Parametre
params = {
    'latitude': 59.91,      # Oslo
    'longitude': 10.75,
    'current_weather': True
}

# Send forespørsel
response = requests.get(url, params=params)

if response.status_code == 200:
    data = response.json()
    weather = data['current_weather']

    print(f"Temperatur: {weather['temperature']}°C")
    print(f"Vindhastighet: {weather['windspeed']} km/t")
    print(f"Værkode: {weather['weathercode']}")
else:
    print(f"Feil: {response.status_code}")

Output:

Temperatur: 12.5°C
Vindhastighet: 15.2 km/t
Værkode: 3

Her sende vi latitude og longitude som parametrar for å få værdata for ein spesifikk lokasjon.

Mange API-ar krev ein API-nøkkel for å få tilgang. Dette blir vanlegvis gjort på éin av to måtar:

1. Som query-parameter:

params = {
    'api_key': 'DIN_HEMMELIGE_NØKKEL',
    'q': 'Oslo'
}
response = requests.get(url, params=params)

2. I HTTP-headeren:

headers = {
    'Authorization': 'Bearer DIN_HEMMELIGE_NØKKEL'
}
response = requests.get(url, headers=headers)

Tryggleikstips:
- Lagre aldri API-nøklar direkte i koden om han blir delt offentleg
- Bruk miljøvariablar eller konfigurasjonsfiler
- Legg konfigurasjonsfiler til .gitignore om du brukar Git

Bruke miljøvariablar:

import os

api_key = os.getenv('MY_API_KEY')  # Hent fra miljøvariabel
params = {'api_key': api_key}

Dette held nøklane trygge og utanfor koden.

✏️Eksempel: Hente fleire postar

Lat oss hente ei liste med postar frå eit API:

import requests

url = 'https://jsonplaceholder.typicode.com/posts'
response = requests.get(url)

if response.status_code == 200:
    posts = response.json()  # Liste med dictionaries

    print(f"Antall poster: {len(posts)}")
    print("\nFørste 3 poster:")

    for post in posts[:3]:
        print(f"\nID: {post['id']}")
        print(f"Tittel: {post['title']}")
        print(f"Innhold: {post['body'][:50]}...")  # Første 50 tegn
else:
    print(f"Feil: {response.status_code}")

Output:

Antall poster: 100

Første 3 poster:

ID: 1
Tittel: sunt aut facere repellat...
Innhold: quia et suscipit suscipit recusandae...

ID: 2
Tittel: qui est esse
Innhold: est rerum tempore vitae...

ID: 3
Tittel: ea molestias quasi...
Innhold: et iusto sed quo iure...

Her får vi ei liste med 100 postar, og vi viser berre dei 3 første.

Når vi får JSON-data frå eit API, blir det konvertert til Python-datastrukturar:

JSON → Python:
- JSON-objekt → Python dictionary
- JSON-liste → Python list
- JSON-string → Python str
- JSON-tal → Python int/float
- JSON boolean → Python bool
- JSON null → Python None

Tilgang til data:

data = response.json()

# Dictionary-tilgang
print(data['key'])
print(data['nested']['value'])

# Liste-tilgang
print(data['items'][0])

# Iterer over liste
for item in data['items']:
    print(item['name'])

Sjekk om nøkkel eksisterer:

if 'key' in data:
    print(data['key'])
else:
    print("Nøkkelen finnes ikke")

# Eller bruk .get() med default-verdi
value = data.get('key', 'default')

Dette unngår feil om nøkkelen manglar i JSON-dataene.

✏️Praktisk eksempel: Land-info-søk

Lat oss lage eit program som hentar informasjon om land:

import requests

def hent_land_info(landnavn):
    """Hent informasjon om et land fra REST Countries API"""
    url = f'https://restcountries.com/v3.1/name/{landnavn}'

    try:
        response = requests.get(url, timeout=5)
        response.raise_for_status()

        data = response.json()
        land = data[0]  # Første treff

        # Hent relevant info
        navn = land['name']['common']
        hovedstad = land.get('capital', ['Ukjent'])[0]
        befolkning = land['population']
        region = land['region']

        # Språk (kan være flere)
        sprak = ', '.join(land.get('languages', {}).values())

        # Vis info
        print(f"\nLand: {navn}")
        print(f"Hovedstad: {hovedstad}")
        print(f"Befolkning: {befolkning:,}")
        print(f"Region: {region}")
        print(f"Språk: {sprak}")

    except requests.exceptions.HTTPError:
        print("Fant ikke landet.")
    except requests.exceptions.RequestException as e:
        print(f"Feil ved henting av data: {e}")

# Test programmet
hent_land_info('Norway')
hent_land_info('Japan')

Output:

Land: Norway
Hovedstad: Oslo
Befolkning: 5,379,475
Region: Europe
Språk: Norwegian Nynorsk, Norwegian Bokmål, Sami

Land: Japan
Hovedstad: Tokyo
Befolkning: 125,836,021
Region: Asia
Språk: Japanese

Dette viser korleis vi kan hente og handsame strukturert data frå eit API.

Oppsummering

I dette kapittelet har du lært:

- API-foresporsel: hente data frå eit API med f.eks. requests.
- HTTP-statuskodar: 2xx (suksess), 4xx (klientfeil), 5xx (serverfeil).
- Parametrar: sende verdiar med foresporselen.
- Handsame svar: dictionary- og liste-tilgang.
- .get(): trygg tilgang med standardverdi.

Noekkelbegreper


BegrepForklaring
API-foresporselHenvendelse til et API for å hente data
Statuskode 200OK - foresporselen var vellykket
Statuskode 404Not Found - ressurs ikke funnet

Oppgaver

Dette kapitlet er skrevet av Anthropics toppmodeller (Claude Opus og Claude Fable) og er foreløpig ikke manuelt gjennomgått — kvalitetskontrollen gjøres av uavhengige KI-agenter, og innmeldte feil rettes fortløpende. Funnet en feil? Meld fra, så retter vi den. Les mer om hvordan innholdet lages.