Prerequisites: This post assumes basic knowledge of Python and HTTP APIs.
Welcome to the second part of this eInk prototype experiment mini-series. Today we’ll look at the draft code (Gist) used to fetch the weather itself.
Note that we’ll be speeding through some very rough code. We’ll polish it up as the series progresses. You can see the complete file at the end of the post.
Let’s break it down section by section, focusing on the most relevant code.
A simple Python class serving as a data store. It provides a clean interface for the code that will import this module.
The counterpart to WeatherError
. This is returned when something goes wrong while fetching the data.
The core functionality exported by this module. This method performs the actual weather service query. We’ll cover it in multiple parts.
Initial setup. The required API key is passed in as an environment variable in order to keep it private and to prevent accidental uploads to, say, GitHub. Looking at the code again, I would do the same for the city name. This URL likely also needs a state
parameter or the like. We then make the actual HTTP request to the weather API.
The HTTP code for the response is then checked. If it’s 200
(OK
) then we’re good to go and can pass the necessary parts of the response onto the initializer for WeatherReport
.
The results are shown with print
for debugging purposes. It’s unusual for a module to print logs like these but this is proof of concept code.
If the response code was anything other than 200
, we treat it as an error. Common errors for this API include: 401 - Invalid API key
and 404 - City not found
. As before, we print out the results for debugging purposes.
And that’s a quick run through the code! It’s not what I would call “excellent” code but it does the job and that’s often enough. After all, I care more about having a readable weather report on my wall than about having perfect code hidden in a hard drive. I hope that this peek into what real, pragmatic programming looks like inspires you to start your own such project!
Look forward to an analysis of the eInk display code in the next part of this series.
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
import requests, json, os
class WeatherReport:
def __init__(self, report, weather):
self.current_temperature = report["temp"]
self.feels_like = report["feels_like"]
self.high = report["temp_max"]
self.low = report["temp_min"]
self.humidity = report["humidity"]
self.weather_description = weather[0]["description"]
class WeatherError:
def __init__(self, response):
self.response = response
self.error_code = response["cod"]
self.message = response["message"]
def fetch_weather():
base_url = "http://api.openweathermap.org/data/2.5/weather"
api_key = os.environ.get('OPENWEATHER_API_KEY')
city_name = "Astoria"
complete_url = "{}?appid={}&q={}&units=imperial".format(base_url, api_key, city_name)
response = requests.get(complete_url).json()
if response["cod"] == 200:
weather = response["weather"]
report = WeatherReport(response["main"], weather)
print("Temp: {}F\nFeels Like: {}F\nHigh: {}F\nLow: {}F\nHumidity: {}\nDescription: {}".format(
report.current_temperature,
report.feels_like,
report.high,
report.low,
report.humidity,
report.weather_description
))
return report
else:
print("Error: {}", response)
return WeatherError(response)