Building a Weather Forecast App With Python, Flask, and OpenWeather APIs
Tags: flask, webdev, python, tutorial
Published: 2022-12-08 00:32:44

This fall I was pleased to _finally_ finish Harvard's [CS50 course](https://cs50.harvard.edu/x/2022/), a great (free) online course for beginning programmers or intermediate programmers looking to deepen their computer science knowledge.

The final project for the course was open-ended - I could build anything I wanted, provided it was of interest to me and had enough complexity for the effort of completion to be greater than any of the course's problem sets. I had previously done a problem set with Python and Flask using HTTP GET and POST calls. But I still wanted to go deeper with Flask and making API calls. 

I'm a big meteorology nerd - I used to be a mountain guide, where my job involved constantly watching the weather and making critical group decisions based on forecast and real-time information. So for my final project, I decided to build a Flask app called "The Nowcast" which lets users input their zipcode and get back weather and pollution reports using [OpenWeather APIs](https://openweathermap.org/current). For the front end I used HTML (with the Bootstrap library) and CSS. 

I started out by familiarizing myself with the free versions of the OpenWeather APIs to understand the data that was available to me. I then started to build out my core file, `app.py`, with `app.py` in turn depending on the file with helper functions (`helpers.py`) and the relevant HTML files depending on if the user submits a GET or a POST request.

The `app.py` file contains the "meat" of the Flask application. It includes three functions: `weather_basic()`, `full_weather()`, and `full_aqi()`. All three functions serve html pages that allow users to submit a zipcode, and then based on that zipcode give basic or detailed reports with information from OpenWeather APIs.

The `helpers.py` file, meanwhile, defined a couple of key helper functions. One is the `get_coordinates()` function that takes the zipcode submitted by the user and returns the approximate latitude and longitude of that zipcode using the OpenWeather Geocoding API. This was a necessary first step for taking advantage of the other OpenWeather APIs which use latitude/longitude and not zipcode. It wasn't reasonable to expect users to know their GPS coordinates, so this enabled me to get the user's zipcode and do the work for them. 

The `get_weather()` function takes the user's latitude, longitude, and preferred units of measurement and returns the weather using the OpenWeather Current Weather API. And the `get_aqi()` function returns data on the Air Quality Index (AQI) for the user's zipcode with the OpenWeather Air Pollution API. Ultimately, the API calls in each of these functions return crucial data the user is looking for, which is then routed in the appropriate way in by functions in the `app.py` file to the relevant html display pages.

You can check out the full code for the app on [GitHub here](https://github.com/getsendy/thenowcast) - you just have to register for OpenWeather and get your own API key to add to run it. I've also created a [YouTube demo here](https://www.youtube.com/watch?v=6tMH4ATphnQ&feature=youtu.be). 

_[Image courtesy of Pixabay](https://www.pexels.com/photo/white-clouds-531767/)_