Hi! Hope you're enjoying this blog. I have a new home at www.goldsborough.me. Be sure to also check by there for new posts <3

Thursday, July 25, 2013

Tutorial: Weather forecast in Python using pywapi

Today I want to show you how get weather data from weather.com, Yahoo! weather or NOAA. It's fairly simple to do, the only thing you will need is the pywapi api, which you can download from their google page. Install it with pip, easy_install or just manually with the command line using setup.py install in the pywapi directory. To give you an example, the following code:

import pywapi

weather_com_result = pywapi.get_weather_from_weather_com('UKXX0085')

print ("Weather.com says: It is " + weather_com_result['current_conditions']['text'].lower() + " and " + weather_com_result['current_conditions']['temperature'] + "°C now in London.")

will give you this output:

Weather.com says: It is partly cloudy and 24°C now in London.

I always use weather.com, but if you wish to use Yahoo! weather or NOAA (which only works for US cities), the syntax will essentially be the same. I'll show you how to do a couple things, but you'll find the whole documentation here: https://code.google.com/p/python-weather-api/wiki/Examples#Weather.com.

So, after importing pywapi, we need to first fetch all the data from weather.com and assign it to a variable, so we can access it later on. this is done by calling pywapi's get_weather_from_weather_com_result function, which takes the city code as it's argument. Now you may wonder how in the world you are supposed to know all of these city codes, especially as they have nothing to do with postal codes or anything. You can either:
  1. Go to the weather.com website, type in the city and look in the page's url, which contains the code or
  2. Use pywapi.get_location_ids(), which takes the city's name as it's argument. A bit easier I think. 
So if you wanted to let the user input a city, you could do this by looking up the inputted city name and getting it's city code, like so:

import pywapi

city = input("Enter city name: ")

#this will give you a dictionary of all cities in the world with this city's name Be specific (city, country)!
lookup = pywapi.get_location_ids(city)

#workaround to access last item of dictionary
for i in lookup:
    location_id = i

#location_id now contains the city's code
weather_com_result = pywapi.get_weather_from_weather_com(location_id)

Now that you know how to look up any city in the world, let me show you what you can look up. As I said before, all the data from weather.com is stored in the weather_com_result variable. Let me show you how to access it.

There are two main sets of data, "current_conditions", which holds all of today's data, and "forecast", which holds the data for the next few days. These, and all minor sets of data, are accessed with weather_com_result followed by square brackets with the data set in it. So to get all the current_conditions data, you need: weather_com_result["current conditions"], to get the forecasts, type weather_com_result["forecasts"]. 

For Los Angeles, current_conditions will print:

{'moon_phase': {'text': 'Waning Gibbous', 'icon': '18'}, 'last_updated': '7/25/13 8:45 AM PDT', 'temperature': '19', 'dewpoint': '15', 'text': 'Cloudy', 'uv': {'index': '1', 'text': 'Low'}, 'visibility': '9.7', 'humidity': '78', 'station': 'Los Angeles / Usc Campus Downtown, CA', 'barometer': {'direction': 'rising', 'reading': '1015.2'}, 'feels_like': '19', 'wind': {'gust': 'N/A', 'direction': '0', 'speed': 'calm', 'text': 'CALM'}, 'icon': '26'}

You can find a more readable version here or use something like BeautifulSoup. Anyway, the point is, that this major data set, holds a couple smaller ones, some of them holding even smaller ones. For example, moon_phase is a set within current_conditions , which has {text: , icon: } as smaller ones. Now, say you want to get today's uv levels, you would now have to add ["uv"] to weather_com_result["current_conditions"], and then again add ["text"] (if text had a smaller data set you would again add that in brackets and so on). This would look like this: weather_com_result["current_conditions"]["uv"]["text"].

Temperature would be accessed with weather_com_result["current_conditions"]["temperature"] etc.

Now to the forecasts, do me a favor and look at them in the official documentation, since printing them in python will release an unreadable blob of words. Rather, I will show you how to access a few things.

The forecast days are a list, so they are accessed by index numbers. To get day one's date: weather_com_result["forecasts"][0]["date"]. Further, they are split into day and night. So day two's precipitation chance during the day (yes a lot of possibilites) would be weather_com_result["forecasts"][1]["day"]["chance_precip"], to print day three's temperature highs and lows, you'd type: weather_com_result["forecasts"][2]["high"] + "/" + weather_com_result["forecasts"][2]["low"] and so on.

Right, I think I explained pywapi's syntax, so go ahead and look at all the possibilities on the official documentation. Cheers!


  1. I had only one issue, I didn't need to access the last item of "lookup" because when I was specific (city, country) the correct location was the first item in "lookup". I just used location_id = next(iter(lookup)), that did the trick for me.
    Everything else worked like a charm, thanks mate.

  2. Apex Weather is a new weather app from the developers of Apex Launcher, one of the best Android launchers. This weather app is above average. You get your basic stuff like the current, daily, and hourly forecasts. It also includes a weather map, severe weather alerts, and some of the better clock and weather widgets we've seen in a while. It even shows less common stuff like sunrise and sunset times, air pressure, UV index, and more. You can get weather forecasts in the U.S., U.K., Canada, and Australia along with a rather bland news blog if you want one. The ads can be a tad annoying, but otherwise this weather app checks all of the boxes. You can also remove the ads with a single $5.99 payment.