I was interested in the weatherunderground API for getting real time weather updates via the API and python.

WeatherUnderGroundApiLink:

http://www.wunderground.com/weather/api/

I was particularly interested in learning how to use the JSON python module. So I thought I would give you people a quick and dirty write up of how I get a daily weather update with endless categories via email on linux using python.

Ok so here we go, don’t get all excited and post this on hacker news and crash my t1.micro at AWS.

Let’s have a lookie at the python script where the magic takes place. O Yeah you will need to get an API KEY from WeatherUnderground for this. Look here:

http://www.wunderground.com/weather/api/d/login.html

The API will look like this once you obtain your copy:

426e8256148decXX 1 426e8256148decXX

Here is the link for requests:

http://docs.python-requests.org/en/master/

Ok let me break down the PY code:

It’s probably important to see what we get back from the API in JSON so the below code makes sense. Here we go, this is just pretty printing the JSON using pythons PPRINT module, Showing this snippet first to help understand the code.

SCRIPT:

import urllib2 import json import requests from pprint import pprint r = requests.get("http://api.wunderground.com/api/426e8256148decXX/forecast/q/NJ/newark.json") data = r.json() print "MILFORD CT forecast" pprint(data) 1 2 3 4 5 6 7 8 import urllib2 import json import requests from pprint import pprint r = requests . get ( "http://api.wunderground.com/api/426e8256148decXX/forecast/q/NJ/newark.json" ) data = r . json ( ) print "MILFORD CT forecast" pprint ( data )

OUTPUT:

MILFORD CT forecast {u'forecast': {u'simpleforecast': {u'forecastday': [{u'avehumidity': 75, u'avewind': {u'degrees': 7, u'dir': u'North', u'kph': 10, u'mph': 6}, u'conditions': u'Overcast', u'date': {u'ampm': u'PM', u'day': 8, u'epoch': u'1454976000', u'hour': 19, u'isdst': u'0', u'min': u'00', u'month': 2, u'monthname': u'February', u'monthname_short': u'Feb', u'pretty': u'7:00 PM EST on February 08, 2016', u'sec': 0, u'tz_long': u'America/New_York', u'tz_short': u'EST', u'weekday': u'Monday', u'weekday_short': u'Mon', u'yday': 38, u'year': 2016}, u'high': {u'celsius': u'3', u'fahrenheit': u'39'}, u'icon': u'cloudy', u'icon_url': u'http://icons.wxug.com/i/c/k/cloudy.gif', u'low': {u'celsius': u'-3', u'fahrenheit': u'26'}, u'maxhumidity': 0, u'maxwind': {u'degrees': 0, u'dir': u'', u'kph': 31, u'mph': 19}, u'minhumidity': 0, u'period': 1, u'pop': 20, u'qpf_allday': {u'in': 0.0, u'mm': 0}, u'qpf_day': {u'in': None, u'mm': None}, u'qpf_night': {u'in': 0.0, u'mm': 0}, u'skyicon': u'', u'snow_allday': {u'cm': 0.0, u'in': 0.0}, u'snow_day': {u'cm': None, u'in': None}, u'snow_night': {u'cm': 0.0, u'in': 0.0}}, {u'avehumidity': 67, u'avewind': {u'degrees': 45, u'dir': u'NE', u'kph': 16, u'mph': 10}, <<<---SNIP A MILLION LINES OF OUTPUT --->>> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 MILFORD CT forecast { u 'forecast' : { u 'simpleforecast' : { u 'forecastday' : [ { u 'avehumidity' : 75 , u 'avewind' : { u 'degrees' : 7 , u 'dir' : u 'North' , u 'kph' : 10 , u 'mph' : 6 } , u 'conditions' : u 'Overcast' , u 'date' : { u 'ampm' : u 'PM' , u 'day' : 8 , u 'epoch' : u '1454976000' , u 'hour' : 19 , u 'isdst' : u '0' , u 'min' : u '00' , u 'month' : 2 , u 'monthname' : u 'February' , u 'monthname_short' : u 'Feb' , u 'pretty' : u '7:00 PM EST on February 08, 2016' , u 'sec' : 0 , u 'tz_long' : u 'America/New_York' , u 'tz_short' : u 'EST' , u 'weekday' : u 'Monday' , u 'weekday_short' : u 'Mon' , u 'yday' : 38 , u 'year' : 2016 } , u 'high' : { u 'celsius' : u '3' , u 'fahrenheit' : u '39' } , u 'icon' : u 'cloudy' , u 'icon_url' : u 'http://icons.wxug.com/i/c/k/cloudy.gif' , u 'low' : { u 'celsius' : u '-3' , u 'fahrenheit' : u '26' } , u 'maxhumidity' : 0 , u 'maxwind' : { u 'degrees' : 0 , u 'dir' : u '' , u 'kph' : 31 , u 'mph' : 19 } , u 'minhumidity' : 0 , u 'period' : 1 , u 'pop' : 20 , u 'qpf_allday' : { u 'in' : 0.0 , u 'mm' : 0 } , u 'qpf_day' : { u 'in' : None , u 'mm' : None } , u 'qpf_night' : { u 'in' : 0.0 , u 'mm' : 0 } , u 'skyicon' : u '' , u 'snow_allday' : { u 'cm' : 0.0 , u 'in' : 0.0 } , u 'snow_day' : { u 'cm' : None , u 'in' : None } , u 'snow_night' : { u 'cm' : 0.0 , u 'in' : 0.0 } } , { u 'avehumidity' : 67 , u 'avewind' : { u 'degrees' : 45 , u 'dir' : u 'NE' , u 'kph' : 16 , u 'mph' : 10 } , < < < --- SNIP A MILLION LINES OF OUTPUT --- > > >

Ok let’s parse this JSON and send a freaking daily email with the fields we want, O Yeah.

Here is the script commenting on what we are doing.

[jralph@jr-sandbox bin]$ cat py_weather.py ### We import our modules or libraries here ### import urllib2 import json import requests ### r is the object we create when calling the API request, pay attention to the STATE:CT and CITY:Milford ### r = requests.get("http://api.wunderground.com/api/426e8256148decXX/forecast/q/CT/Milford.json") ### Lets tell the JSON library that we have JSON data we need to use, so r.json = data ### data = r.json() ### Here we print out the City and State with standard python print ### print "MILFORD CT forecast" ### Our for loop / main loop ### for day in data['forecast']['simpleforecast']['forecastday']: print day['date']['weekday'] + ":" print "Conditions: ", day['conditions'] print "HIGH: ", day['high']['celsius'] + "C", "LOW: ", day['low']['celsius'] + "C", '

' 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 [ jralph @ jr - sandbox bin ] $ cat py_weather . py ### We import our modules or libraries here ### import urllib2 import json import requests ### r is the object we create when calling the API request, pay attention to the STATE:CT and CITY:Milford ### r = requests . get ( "http://api.wunderground.com/api/426e8256148decXX/forecast/q/CT/Milford.json" ) ### Lets tell the JSON library that we have JSON data we need to use, so r.json = data ### data = r . json ( ) ### Here we print out the City and State with standard python print ### print "MILFORD CT forecast" ### Our for loop / main loop ### for day in data [ 'forecast' ] [ 'simpleforecast' ] [ 'forecastday' ] : print day [ 'date' ] [ 'weekday' ] + ":" print "Conditions: " , day [ 'conditions' ] print "HIGH: " , day [ 'high' ] [ 'celsius' ] + "C" , "LOW: " , day [ 'low' ] [ 'celsius' ] + "C" , '

'

Here is what comes out of this python script when we call the JSON variables we are attracted to:

MILFORD CT forecast Monday: Conditions: Overcast HIGH: 3C LOW: -3C Tuesday: Conditions: Overcast HIGH: 3C LOW: -1C Wednesday: Conditions: Partly Cloudy HIGH: 4C LOW: -3C Thursday: Conditions: Partly Cloudy HIGH: -1C LOW: -8C 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 MILFORD CT forecast Monday : Conditions : Overcast HIGH : 3C LOW : - 3C Tuesday : Conditions : Overcast HIGH : 3C LOW : - 1C Wednesday : Conditions : Partly Cloudy HIGH : 4C LOW : - 3C Thursday : Conditions : Partly Cloudy HIGH : - 1C LOW : - 8C

Ok let’s wrap this biatch into a shell script and have it call mail on linux so I can get a daily updates on the weather for Milford CT whenever I call the cron.

Here is the directory structure I setup for the scripts:

[jralph@jr-sandbox bin]$ pwd /home/jralph/weather/bin [jralph@jr-sandbox bin]$ ls -l total 8 -rwxrwxr-x 1 jralph jralph 456 Feb 8 23:21 py_weather.py -rwxrwxr-x 1 jralph jralph 485 Feb 8 22:36 weather_bash_wrap.sh 1 2 3 4 5 6 7 [ jralph @ jr - sandbox bin ] $ pwd / home / jralph / weather / bin [ jralph @ jr - sandbox bin ] $ ls - l total 8 - rwxrwxr - x 1 jralph jralph 456 Feb 8 23 : 21 py_weather . py - rwxrwxr - x 1 jralph jralph 485 Feb 8 22 : 36 weather_bash_wrap . sh

Here is the bash script that I wrote to bring it all together, it calls the python script and writes a log and mails it.

[jralph@jr-sandbox bin]$ cat weather_bash_wrap.sh #!/bin/bash # jralph # grab the daily weather for Milford CT and mail it via cron home=$HOME weather_home=$home/weather/ script_bin=$weather_home/bin/ t_date=$(date +\%Y\%m\%d) log_file=~/weather/weather_log.$t_date.log py_binary=$(which python) mail_binary=$(which mail) recipient_list='jralph@company.com' $py_binary $script_bin/py_weather.py > $log_file 2>&1 function mailer(){ $mail_binary -s "$t_date Milford Weather" $recipient_list < $log_file } mailer 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 [ jralph @ jr - sandbox bin ] $ cat weather_bash_wrap . sh #!/bin/bash # jralph # grab the daily weather for Milford CT and mail it via cron home = $ HOME weather_home = $ home / weather / script_bin = $ weather_home / bin / t_date = $ ( date + \ % Y \ % m \ % d ) log_file = ~ / weather / weather_log . $ t_date . log py_binary = $ ( which python ) mail_binary = $ ( which mail ) recipient_list = [email protected]' $ py_binary $ script_bin / py_weather . py > $ log_file 2 > &1 function mailer ( ) { $ mail_binary - s "$t_date Milford Weather" $ recipient_list < $ log_file } mailer

Here is the cron:

[jralph@jr-sandbox ~]$ crontab -l ### CRONS ### ### Get Daily Weather for Milford CT via Weather Underground API ### 00 07 * * * /bin/bash /home/jralph/weather/bin/weather_bash_wrap.sh > /dev/null 2>&1 1 2 3 4 [ jralph @ jr - sandbox ~ ] $ crontab - l ### CRONS ### ### Get Daily Weather for Milford CT via Weather Underground API ### 00 07 * * * / bin / bash / home / jralph / weather / bin / weather_bash_wrap . sh > / dev / null 2 > &1

Here is my morning email message:

Hope you had fun, I did. O and let me know how bad this post is and how you can do it better.

Love you