Python In 30 Days - Day 9
Day nine was all about API calls.
The Challenge:
You're going to use the Open-Meteo API — it's free, requires no API key, and returns weather data as JSON.
The base URL is https://api.open-meteo.com/v1/forecast
It takes parameters including latitude, longitude, and current (what current conditions you want).
- Write a function get_weather(city, lat, lon) that:
- Makes a
GETrequest to the Open-Meteo API requesting current conditions for:temperature_2m,wind_speed_10m, andprecipitation - You'll also need to pass
temperature_unit="fahrenheit"as a parameter - Checks the status code and handles a failed request gracefully
- Parses the JSON response and returns a clean dictionary with:
city,temperature,wind_speed, andprecipitation
Write a function
print_weather(weather)that prints the results in a readable formatCall it for at least two cities of your choice — you'll need to look up their coordinates
Print the raw JSON structure from one response using
json.dumps()withindent=4so you can see what the API actually returns — this will help you figure out how to navigate the response
Things to figure out: the exact structure of the API response (the raw JSON print will help), how to install and import requests, and how to pull the right values out of a nested dictionary.
My Code:
import requests
import json
def get_weather(city, lat, lon, debug=False):
try:
response = requests.get(
"https://api.open-meteo.com/v1/forecast",
params={
"latitude": lat,
"longitude": lon,
"current": "temperature_2m,wind_speed_10m,precipitation",
"temperature_unit": "fahrenheit",
},
)
response.raise_for_status()
data = response.json()
dump = json.dumps(data, indent=4)
if debug:
print("Success!\n", dump)
else:
print("Success!")
city = city.capitalize()
current = data["current"]
temperature = current["temperature_2m"]
wind_speed = current["wind_speed_10m"]
precipitation = current["precipitation"]
weather = {
"city": city,
"temperature": temperature,
"wind": wind_speed,
"precipitation": precipitation,
}
return weather
except requests.exceptions.HTTPError as http_err:
print(f"HTTP error occurred: {http_err}") # e.g., 404 or 500
except requests.exceptions.ConnectionError as conn_err:
print(f"Connection error occurred: {conn_err}") # e.g., DNS failure
except requests.exceptions.Timeout as timeout_err:
print(f"Timeout error occurred: {timeout_err}") # Request took too long
except requests.exceptions.RequestException as err:
print(f"An unexpected error occurred: {err}") # Catch-all for Requests
def print_weather(weather):
print(
f"{weather['city']} Current Conditions:\nTemperature: {weather['temperature']}\nWind Speed: {weather['wind']}\nPrecipitation: {weather['precipitation']}\n"
)
knox = get_weather("knoxville", 35.89024565389892, -84.10664715769713, debug=True)
print_weather(knox)
orlando = get_weather("orlando", 28.4178, -81.5753)
print_weather(orlando)
Running The Code:
Success!
{
"latitude": 35.903,
"longitude": -84.11697,
"generationtime_ms": 0.32842159271240234,
"utc_offset_seconds": 0,
"timezone": "GMT",
"timezone_abbreviation": "GMT",
"elevation": 294.0,
"current_units": {
"time": "iso8601",
"interval": "seconds",
"temperature_2m": "\u00b0F",
"wind_speed_10m": "km/h",
"precipitation": "mm"
},
"current": {
"time": "2026-05-18T11:30",
"interval": 900,
"temperature_2m": 68.5,
"wind_speed_10m": 3.7,
"precipitation": 0.0
}
}
Knoxville Current Conditions:
Temperature: 68.5
Wind Speed: 3.7
Precipitation: 0.0
Success!
Orlando Current Conditions:
Temperature: 71.5
Wind Speed: 7.6
Precipitation: 0.0
Nailed it! Actually, this one is kind of useful and I might consider making it a little script that I use regularly for local weather, though there are already command line tools that do this.
Day ten is supposed to be about CSV files.