Weather Data and Forecasts from Open Weather API | by Joseph Magiya | Towards Data Science

Adding weather to your analysis might bring something to light, or it might not. Either way, it is easier to explore and add this to your data now than ever before.
It is simpler than you think — let me show you how.
We’ll get our data from OpenWeather and use their API to get that data.
For this you’ll need to sign up and confirm your account. Once you do all that, you’ll receive an API Key which you’ll use to fetch the data through API calls.
This is the format of the API call using a city name — api.openweathermap.org/data/2.5/weather?q={city name},{state},{country code}&appid={your api key}
I’ve used — “b6907d289e10d714a6e88b30761fae22” as an example of an api key — but you need to change it to the one you receive from OpenWeather, this will not work.
City_API_endpoint = "http://api.openweathermap.org/data/2.5/weather?q="City = "Nairobi"Country = ",KE,"join_key = "&appid=" + "b6907d289e10d714a6e88b30761fae22"units = "&units=metric"
This is all we need to form our request URL, now we need to combine them to actually form a URL.
current_city_weather = City_API_endpoint + City + Country + join_key + unitsprint(current_city_weather)
Result
http://api.openweathermap.org/data/2.5/weather?q=Nairobi,KE,&appid=b6907d289e10d714a6e88b30761fae22&units=metric
If you go to that link, you’ll see something like this, ofcourse if you’re reading this in the future or even in the past — you’ll get a different result.
Before we go into how to extract the data and make it useful, let’s look at the second option.
This is my favorite one especially since I get to interact with coordinates a lot.
This is the format of the API call for a specific location using latitude and longitude — api.openweathermap.org/data/2.5/weather?lat={lat}&lon={lon}&appid={your api key}
API_endpoint = "http://api.openweathermap.org"join_1 = "&appid="API_key = "b6907d289e10d714a6e88b30761fae22"current_weather_lat_lon = "/data/2.5/weather?"+ "lat=" + str(round(lat,2))+ "&lon=" + str(round(long,2))
Let’s set the lat and long in variables, you can definitely pass multiple values e.g. a dataframe you’re analysing (I’ll cover this later...maybe in a separate blog).
lat = -1.2999792long = 36.7728897lat_long = "lat=" + str(lat)+ "&lon=" + str(long)
Let’s add the coordinates and other parts to the URL and create the full URL. You can obviously do this in one line, but I prefer my code being flexible and easy to understand.
coord_API_endpoint = "http://api.openweathermap.org/data/2.5/weather?"lat_long = "lat=" + str(lat)+ "&lon=" + str(long)join_key = "&appid=" + "b6907d289e10d714a6e88b30761fae22"units = "&units=metric"
Full URL
current_coord_weather_url= coord_API_endpoint + lat_long + join_key + unitsprint(current_coord_weather_url)
Result
http://api.openweathermap.org/data/2.5/weather?lat=-1.2999792&lon=36.7728897&appid=b6907d289e10d714a6e88b30761fae22&units=metric
For this we’ll need to import a python package — requests.
import requests
Here’s how we get the result of the response into a variable, which we’ll later break down so it’s more readable.
json_data = requests.get(current_coord_weather_url).json()print(json_data)
The result of this will have the same structure as the link you went to,
We’ll obviously need to import pandas
import pandas as pd
Let’s create an empty data frame first, we’ll later add the values here.
df_all_current_weather = pd.DataFrame()
Next we create empty lists for the keys in the dataframe.
# Create empty lists to store the JSON Datacurrent_weather_id = []current_time = []own_city_id = []city = []latitude = []longitude = []country = []timezone = []sunrise = []sunset = []temperature = []temperature_feel = []temperature_min = []temperature_max = []pressure = []humidity = []main = []main_description = []clouds = []wind_speed = []wind_degree = []visibility = []
Then we add the data from the JSON into the list:
# Add JSON Data to the listsprediction_num +=1current_weather_id.append(prediction_num + 1)current_time.append(pd.Timestamp.now())own_city_id.append(json_data['id'])city.append(json_data['name'])latitude.append(json_data['coord']['lat'])longitude.append(json_data['coord']['lon'])country.append(json_data['sys']['country'])if json_data['timezone'] >0 :    timezone.append(("+" + str((json_data['timezone'])/3600)))else:    timezone.append(((json_data['timezone'])/3600))sunrise.append(json_data['sys']['sunrise'])sunset.append(json_data['sys']['sunset'])temperature.append(json_data['main']['temp'])temperature_feel.append(json_data['main']['feels_like'])temperature_min.append(json_data['main']['temp_min'])temperature_max.append(json_data['main']['temp_max'])pressure.append(json_data['main']['pressure'])humidity.append(json_data['main']['humidity'])main.append(json_data['weather'][0]['main'])main_description.append(json_data['weather'][0]['description'])clouds.append(json_data['clouds']['all'])wind_speed.append(json_data['wind']['speed'])wind_degree.append(json_data['wind']['deg'])visibility.append(json_data['visibility'])
Finally we write the list into the dataframe that we created
# Write Lists to DataFramedf_all_current_weather['current_weather_id'] = current_weather_iddf_all_current_weather['current_time'] = current_timedf_all_current_weather['own_city_id'] = own_city_iddf_all_current_weather['city'] = citydf_all_current_weather['latitude'] = latitudedf_all_current_weather['longitude'] = longitudedf_all_current_weather['country'] = countrydf_all_current_weather['timezone'] = timezonedf_all_current_weather['sunrise'] = sunrisedf_all_current_weather['sunset'] = sunsetdf_all_current_weather['temperature'] = temperaturedf_all_current_weather['temperature_feel'] = temperature_feeldf_all_current_weather['temperature_min'] = temperature_mindf_all_current_weather['temperature_max'] = temperature_maxdf_all_current_weather['pressure'] = pressuredf_all_current_weather['humidity'] = humiditydf_all_current_weather['main'] = maindf_all_current_weather['main_description'] = main_descriptiondf_all_current_weather['clouds'] = cloudsdf_all_current_weather['wind_speed'] = wind_speeddf_all_current_weather['wind_degree'] = wind_degreedf_all_current_weather['visibility'] = visibility
Previewing the data frame will give you the result of the result of the API call but in a way that is more useful to analyse and join with your data.
This is for those who want to know what tomorrow is going to look like.
We’ll still use a few variables from the first section, and since we already know the basics, I’ll shorten this section.
One thing to note is that the result is going to be a longer JSON, because it has the forecast in 3 hour intervals, 5 times. This is very beneficial for analysis and predictions.
Think about how this can affect some of your forecasting projects e.g. the amount of traffic in a city.
Forecasts API Call using City Name Format — api.openweathermap.org/data/2.5/forecast?q={city name},{state},{country code}&appid={your api key}
City_API_endpoint = "http://api.openweathermap.org/data/2.5/forecast?q="City = "Nairobi"Country = ",KE,"join_key = "&appid=" + "b6907d289e10d714a6e88b30761fae22"units = "&units=metric"city_forecast = City_API_endpoint + City + Country + join_key + unitsprint(city_forecast)
Result
http://api.openweathermap.org/data/2.5/forecast?q=Nairobi,KE,&appid=b6907d289e10d714a6e88b30761fae22&units=metric
Following the link — you’ll find this, and this is just a part of it.
Forecasts API Call using Coordinates Format — api.openweathermap.org/data/2.5/forecast?lat={lat}&lon={lon}&appid={your api key}
lat = -1.2999792long = 36.7728897lat_long = "lat=" + str(lat)+ "&lon=" + str(long)coord_API_endpoint = "http://api.openweathermap.org/data/2.5/forecast?"lat_long = "lat=" + str(lat)+ "&lon=" + str(long)join_key = "&appid=" + "b6907d289e10d714a6e88b30761fae22"units = "&units=metric"forecast_coord_weather_url = coord_API_endpoint + lat_long + join_key + unitsprint (forecast_coord_weather_url)
Result
http://api.openweathermap.org/data/2.5/forecast?lat=-1.2999792&lon=36.7728897&appid=b6907d289e10d714a6e88b30761fae22&units=metric
Following the link — you’ll find this, very tiring to look at.
For this we’ll need to import a python package — requests.
import requests
Here’s how we get the result of the response into a variable, which we’ll later break down so it’s more readable.
forecast_json_data = requests.get(city_forecast).json()
The result of this will have the same structure as the link you went to,
Create an empty dataframe
df_predictions = pd.DataFrame()
We first create empty lists that will later hold the json data.
# Creating empty listsprediction_num = 0list_prediction_num = []date_time_prediction = []owm_city_id = []city_name = []latitude = []longitude = []country_name = []population = []timezone = [] # Shift in seconds from UTCsunrise = []sunset = []# Maintemp_prediction = []temp_feels_like_prediction = []temp_min_prediction = []temp_max_prediction = []pressure_prediction = []sea_level_prediction = []grnd_level_prediction = []humidity_prediction = []temp_kf_prediction = []# Weathermain_weather_prediction = []main_weather_description_prediction = []# Cloudsclouds_prediction = []# Windwind_speed_prediction = []wind_degree_prediction = []
Loop Through the JSON and add (append) the data to the lists we have created.
# Loop Through the JSONfor num_forecasts in forecast_json_data['list']:    df_predictions['prediction_num'] = prediction_num    list_prediction_num.append(prediction_num)    date_time_prediction.append(forecast_json_data['list'][prediction_num]['dt_txt'])        owm_city_id.append(forecast_json_data['city']['id'])    city_name.append(forecast_json_data['city']['name'])    latitude.append(forecast_json_data['city']['coord']['lat'])    longitude.append(forecast_json_data['city']['coord']['lon'])    country_name.append(forecast_json_data['city']['country'])    population.append(forecast_json_data['city']['population'])        if forecast_json_data['city']['timezone'] >0 :        timezone.append("+" + str((forecast_json_data['city']['timezone'])/3600))    else:        timezone.append((forecast_json_data['city']['timezone'])/3600)            sunrise.append(forecast_json_data['city']['sunrise'])    sunset.append(forecast_json_data['city']['sunset'])        # Main    temp_prediction.append(forecast_json_data['list'][prediction_num]['main']['temp'])    temp_feels_like_prediction.append(forecast_json_data['list'][prediction_num]['main']['feels_like'])    temp_min_prediction.append(forecast_json_data['list'][prediction_num]['main']['temp_min'])    temp_max_prediction.append(forecast_json_data['list'][prediction_num]['main']['temp_max'])    pressure_prediction.append(forecast_json_data['list'][prediction_num]['main']['pressure'])    sea_level_prediction.append(forecast_json_data['list'][prediction_num]['main']['sea_level'])    grnd_level_prediction.append(forecast_json_data['list'][prediction_num]['main']['grnd_level'])    humidity_prediction.append(forecast_json_data['list'][prediction_num]['main']['humidity'])    temp_kf_prediction.append(forecast_json_data['list'][prediction_num]['main']['temp_kf'])    # Weather    main_weather_prediction.append(forecast_json_data['list'][prediction_num]['weather'][0]['main'])    main_weather_description_prediction.append(forecast_json_data['list'][prediction_num]['weather'][0]['description'])    # Clouds    clouds_prediction.append(forecast_json_data['list'][prediction_num]['clouds']['all'])    # Wind    wind_speed_prediction.append(forecast_json_data['list'][prediction_num]['wind']['speed'])    wind_degree_prediction.append(forecast_json_data['list'][prediction_num]['wind']['deg'])        prediction_num += 1
Put the data into a dataframe
# Put data into a dataframedf_predictions['prediction_num'] = list_prediction_numdf_predictions['date_time_prediction'] = date_time_predictiondf_predictions['owm_city_id'] = owm_city_iddf_predictions['city_name'] = city_namedf_predictions['latitude'] = latitudedf_predictions['longitude'] = longitudedf_predictions['country_name'] = country_namedf_predictions['population'] = populationdf_predictions['timezone'] = timezonedf_predictions['sunrise'] = sunrisedf_predictions['sunset'] = sunset# Maindf_predictions['temp_prediction'] = temp_predictiondf_predictions['temp_feels_like_prediction'] = temp_feels_like_predictiondf_predictions['temp_min_prediction'] = temp_min_predictiondf_predictions['temp_max_prediction'] = temp_max_predictiondf_predictions['pressure_prediction'] = pressure_predictiondf_predictions['sea_level_prediction'] = sea_level_predictiondf_predictions['grnd_level_prediction'] = grnd_level_predictiondf_predictions['humidity_prediction'] = humidity_predictiondf_predictions['temp_kf_prediction'] = temp_kf_prediction    # Weatherdf_predictions['main_weather_prediction'] = main_weather_predictiondf_predictions['main_weather_description_prediction'] = main_weather_description_prediction    # Cloudsdf_predictions['clouds_prediction'] = clouds_prediction    # Winddf_predictions['wind_speed_prediction'] = wind_speed_predictiondf_predictions['wind_degree_prediction'] = wind_degree_prediction
Let’s look at the result
print(df_predictions.head())
You can find the Github repo here.