Coding STEM

Air-quality GUI Application Using Webservices (Python)

This is a complete GUI application in Python to retrieve air quality information based on a zipcode (within USA). It utilizes the following concepts:
  • Using tkinter library for GUI
  • Calling a webservice
  • Parsing JSON payload
  • Formatting date and UI controls (input box, button, label, will dynamic updates)
  • How to name your application title, attaching your custom icon, and basic window geometry as bonus.


The full source code is below. I will assume general knowledge of Python here as I won’t go line by line for the basic instructions, rather highlight the specifics around the bulleted list items stated above.

Before we make use of the webservice, note that I’m using a public API from Each API key has to be individually acquired so I’ll obfuscate that part that’s assigned to my application. That API key is required to get any result back.

Once you get the API, here are some resources to understand the parameters they support and what they return:

In the application, import all from tkinter library. My instance is called root. Using that object we can set title, icon (needs to be a real ico file).

Wherever you see, note that it is a more precise version of pack() in that we can place a widget specifying x,y coordinates.

In the main framework, we initialize the variables (ui_zipcode), create the input box (called Entry widget in tkinter), a label to display the information. And we call my custom functions makeurl() and callAPI().

My custom functions are:


This is called whenever Go button is pressed. It takes the user-input zipcode value from the input box (Entry) and does some basic validation. Its job is to pass that validated zipcode to my other custom function makeurl().


Its job is to construct a full URL that can be used to make the webservice call. The string it creates is in this format:

Replace xxx with the API key assigned to you. 99999 is a placeholder for the zipcode value entered by user. Distance parameter tells it the radius in miles from the zipcode to retrieve info about. Format parameter specifies in what format we want the returned payload. In this case, we wanted json, but you can also specify text/csv if you wish and parse it accordingly.


This is where the API call happes within try-except block to be sure. If it succeeds the returned payload will be in the following format:

{"DateObserved":"2020-05-08 ","HourObserved":11,"LocalTimeZone":"PST","ReportingArea":"Everett-Marysville-Lynnwood","StateCode":"WA","Latitude":48.0551,"Longitude":-122.1758,"ParameterName":"PM2.5","AQI":28,"Category":{"Number":1,"Name":"Good"}

More information on what AQI means and to follow their color codes based on values, see

Here we also change the label’s background color based on AQI values.

The date returned in DateObserved is in format: 2020-05-08 (YYY-MM-DD)
datestring=loads[0][‘DateObserved’] and I wanted to format it my way (because I wanted to know how to modify the format and also make it more user-friendly). So, I use dateutil library’s parse module to convert the string into a date-time object. Once I have that, I can split the year, month, day and reconstruct them in any order I wish. This is done inside my callAPI().

This is all you need to know to write this fully-functional application.

The intial UI looks like this (added labels to call attention to a few elements):

See it in Action

Full Source Code

Due to the length of the code and for brevity, I’ll put in the overall framework code and function codes separately…just plug in the function code in their appropriate locations as indicated below.

Main framework:

The functions’ codes to plug into above code:

Maximize your browser to see the following code better:


If you like more info or actual source file to learn/use, contact me via this form  or directly by emailing me at trseattle at outlook dot com. To support this voluntary work, you can also donate via the Home page.

Leave a Reply

Your email address will not be published. Required fields are marked *

Back To Top