Using the Open Weather Map API with Python

In this post, I am showing you how to use the freely available Open Weather Map API to retrieve hourly weather forecasts 48 hours into the future for a given place using Python without external packages.

Continue reading if you need an easy and flexible way to obtain weather data in your python application and you want to avoid using third-party dependencies for the task. You will use the free tier of the Open Weather Map API. The resulting weather data includes:

  • temperature
  • sunrise and sunset time
  • “feels like” temperature
  • pressure
  • humidity
  • wind speed
  • cloudiness

All the above data points are returned hourly for the next 48 hours in JSON format for free.

We will use Python to query the API without using any dependencies except for the requests and json packages so you can easily adapt it to suit your particular needs. Let’s get started!

Obtaining an API Key

Go to the Open Weather Map website and register (for free): https://openweathermap.org/

Once logged in, go to API Keys in order to copy your API key.

To verify it works, run the following code (replacing your API key with the placeholder):

import requests
import json

api_key = "0123456789abcdef0123456789abcdef"
lat = "48.208176"
lon = "16.373819"
url = "https://api.openweathermap.org/data/2.5/onecall?lat=%s&lon=%s&appid=%s&units=metric" % (lat, lon, api_key)

response = requests.get(url)
data = json.loads(response.text)
print(data)

If you receive an error 401, this probably means that their backend has not yet activated your API key (in my case, this took almost half an hour).

You can also use Postman instead of Python to explore the API more interactively:

Sending the Request using Postman
Sending the Request using Postman

Mind that you need to provide coordinates (latitude and longitude) for your request – there are many free services such as latlong.net where you can convert a specific place to those coordinates. In my opinion, this is an advantage compared to using city names since coordinates are less ambiguous.

Also, I added units=metric to receive the temperature in degrees Celsius – depending on where you live, you might want to use imperial instead.

Current temperature

To extract the current temperature from the above call, simply access the JSON result:

current = data["current"]["dt"]
print(current)
# 5.25

Hourly Forecast

The hourly forecast is stored under the key hourly – it is easy to iterate over the result set and extract the hour and temperature for each entry:

hourly = data["hourly"]

for entry in hourly:
    dt = datetime.fromtimestamp(entry["dt"], pytz.timezone('Europe/Vienna'))
    temp = entry["temp"]

In the code above, I converted the UNIX timestamp given by the API into a datetime object in my timezone, but feel free to use your favourite method to obtain a readable date.

Wrap Up

The Open Weather API has proven to be very reliable and flexible in the project I was working on. Since no external dependencies are involved, this is a very simple and simultaneously flexible approach for obtaining weather data in Python.

Mind that currently, the free plan is limited to 1000 calls per day so it makes sense to cache the response at least for one hour per place to avoid hitting that limit.

Let me know if you have any questions or leave a comment if this was helpful. Thanks for reading!

Appendix – API Result Data Format

The API call used above returns JSON data in the following format (shortened):

{
    "lat": 48.21,
    "lon": 16.37,
    "timezone": "Europe/Vienna",
    "current": {
        "dt": 1586892055,
        "sunrise": 1586837154,
        "sunset": 1586886185,
        "temp": 5.33,
        "feels_like": -0.68,
        "pressure": 1023,
        "humidity": 41,
        "dew_point": -6.08,
        "uvi": 5.26,
        "clouds": 0,
        "visibility": 10000,
        "wind_speed": 4.6,
        "wind_deg": 320,
        "weather": [
            {
                "id": 800,
                "main": "Clear",
                "description": "clear sky",
                "icon": "01n"
            }
        ],
        "rain": {}
    },
    "hourly": [
        {
            "dt": 1586890800,
            "temp": 5.33,
            "feels_like": -0.1,
            "pressure": 1023,
            "humidity": 41,
            "dew_point": -6.08,
            "clouds": 0,
            "wind_speed": 3.76,
            "wind_deg": 337,
            "weather": [
                {
                    "id": 800,
                    "main": "Clear",
                    "description": "clear sky",
                    "icon": "01n"
                }
            ]
        },
        ...
    ]
}

 

Do NOT follow this link or you will be banned from the site!