Lesson 21 · Data analytics zero to hero
Pull Data from APIs with Python | Data Analytics #21
Video twenty-one of the 30-part series, and a new block: connecting directly to a live data source over the internet, instead of a local file. We're using…
- CourseData analytics zero to hero
- Lesson21 of 30
- Video10 min
- FormatJupyter notebook · 7 code cells
What you'll learn
Data
No separate download needed — the notebook creates or downloads everything it uses.
📓 Full notebook
Download .ipynbData Analytics Zero to Hero, Video 21: Working with APIs and Web Data#
- Video twenty-one of the 30-part series, and a new block: connecting directly to a live data source over the internet, instead of a local file.
- We're using Open-Meteo, a real, free weather API that needs no signup and no API key.
- Let's jump straight in.
Before You Start#
- Open a new Jupyter Notebook in VS Code and select your Python interpreter as the kernel.
- Install requests if you haven't already:
pip install requests. - You'll need an active internet connection for this video, since every cell here calls a real, live API.
Part 1: A First Real API Request#
import requests
url = 'https://api.open-meteo.com/v1/forecast'
params = {'latitude': 52.52, 'longitude': 13.41, 'current_weather': True}
response = requests.get(url, params=params)
print(response.status_code)
print(response.url)
data = response.json()
print(data.keys())
print(data['current_weather'])
Part 2: A Geocoding Lookup#
geo_url = 'https://geocoding-api.open-meteo.com/v1/search'
geo_params = {'name': 'Nairobi', 'count': 1}
geo_response = requests.get(geo_url, params=geo_params)
geo_data = geo_response.json()
result = geo_data['results'][0]
print(result['name'], result['country'], result['latitude'], result['longitude'])
def get_current_weather(city_name):
geo = requests.get('https://geocoding-api.open-meteo.com/v1/search', params={'name': city_name, 'count': 1}).json()
place = geo['results'][0]
weather = requests.get('https://api.open-meteo.com/v1/forecast', params={
'latitude': place['latitude'], 'longitude': place['longitude'], 'current_weather': True
}).json()
return place['name'], place['country'], weather['current_weather']['temperature']
for city in ['Tokyo', 'Cairo', 'Toronto']:
name, country, temp = get_current_weather(city)
print(f'{name}, {country}: {temp}C')
Part 3: Handling Errors#
try:
bad_response = requests.get('https://api.open-meteo.com/v1/forecast', params={'latitude': 999, 'longitude': 999})
bad_response.raise_for_status()
except requests.exceptions.HTTPError as e:
print(f'Real HTTP error caught: {e}')
except requests.exceptions.RequestException as e:
print(f'Real request failed entirely: {e}')
Part 4: Turning a Real API Response into a DataFrame#
import pandas as pd
hourly_params = {'latitude': 52.52, 'longitude': 13.41, 'hourly': 'temperature_2m,precipitation'}
hourly_response = requests.get('https://api.open-meteo.com/v1/forecast', params=hourly_params)
hourly_data = hourly_response.json()['hourly']
forecast_df = pd.DataFrame(hourly_data)
forecast_df['time'] = pd.to_datetime(forecast_df['time'])
print(forecast_df.head())
print(forecast_df.shape)
daily_avg = forecast_df.set_index('time')['temperature_2m'].resample('D').mean().round(1)
print(daily_avg)
Wrap-Up: What You Learned#
- Making a real GET request with requests.get, and reading status_code and json.
- Passing query parameters as a plain dictionary, and chaining two real API endpoints together.
- Handling real failures with raise_for_status and try/except.
- Converting a real JSON API response directly into a pandas DataFrame, ready for every tool from earlier in this series.
- All of it against Open-Meteo, a real, free, live weather API. Video twenty-two covers web scraping: pulling real structured data straight out of a web page's HTML when no API exists. Subscribe so it lands automatically see you there.
Found this useful?
All lessons, notebooks and datasets here are free. If they helped you, a coffee keeps new lessons coming.



