CS 105 - Exercise Nine
Goals
- Learn how to get data from the web
- Get some more practice with text and lists
Prerequisite
There is no starter code for this exercise, so go ahead and visit https://snap.berkeley.edu/snap/snap.html and make sure you are logged in.
Objective
In this exercise, we are going to learn how to fetch data from the web. We are going to be using a website called (OpenWeather)[https://openweathermap.org]. Our goal is to fetch information about the current temperature at various locations.
OpenWeather and APIs
OpenWeather provides a free (and not free, for heavy users) API for accessing weather information online. API stands for "Application Programming Interface", though that is not the most informative definition. For our purpose, it means that they have a server that we can request resources from. The API defines what sorts of questions we can ask / resources we can ask for.
They have a collection of different APIs available, but we will focus on the (current weather API)[https://openweathermap.org/current] for the moment.
Specifically, we will use their current weather by city name API (feel free to browse around and look at the other options).
To access the API, we will construct a URL.
We need to make a connection to OpenWeather's server, which is at api.openweather.org
.
Then we request a resource: /data/2.5/weather
And the we add some query terms to the request. Here are the possible values we can add to the URL:
parameter | value | |
---|---|---|
q | required | This will be three values separated by commas: city,state,country (e.g., middlebury,vt,us ) |
units | optional | This determines the units used for reporting, we will use imperial |
apikey | required | Use of the API is monitored and controlled through a unique API key. This makes sure that users are registered users. I will provide a key, though you can apply for one for free if you want to use the service behind this class. |
Putting that all together, we can request the weather in Middlebury right now with
api.openweathermap.org/data/2.5/weather?q=middlebury,vt,us&units=imperial&appid=
I left off the API key to avoid publishing it on a public website. Check Piazza for a post containing the key.
Try this out in your web browser. Paste the link in and then add the API key on the end. Your web browser should display a JSON file in response (the same one I showed you in the lecture).
Reading JSON
Depending on your web browser, this may look like an ugly mass of punctuation all squeezed together.
Items in curly braces (e.g., {"lon":-73.17,"lat":44.02}
) are objects, and they consist of comma separated properties. The property name is on the left of the colon and the value is on the right. So, this object has two properties: lon
and lat
, with values -73.17 and 44.02, respectively.
What makes this a little difficult to read is that values can be numbers (like the above), text (in double quotes), lists (comma separated values between square brackets), and other objects.
If you trace through carefully, you will see that the top level object has fourteen properties:
coord
, the longitude and latitude of the reportweather
, general conditionsbase
, internal parameter we don't care aboutmain
, the main numeric weather status (i.e., temperature, pressure, humidty, etc...)wind
, wind speed and directionclouds
, percentage of cloud coverrain
, recent rainfall historysnow
, recent snowfall historydt
, time of the observationsys
, internal parameters and sunrise and sunsettimezone
, the timezoneid
, the city idname
, the name of the citycod
, another internal parameter we don't care about
While I am sure that you can puzzle out what the current temperature is, and some of the other features, this is not the easiest way to interact with this data. Let's see what we can do in Snap!
Fetching data with Snap!
Buried in the Sensing palette, you will find .
This fetches data from remote websites and reports back their contents.
Paste the API call URL into the block and click on it (do not include the leading http://
). Bang, we have all of the data! Of course, it is even harder to read now.
Fortunately, we have some tools to help us out. The has a superpower. It knows how to read JSON files!
Put the in the
, and select
json
from the menu on the right. Now when you click the block, you will get this:
What exactly is that? Well, it is a list where every element is a list with two values. The first is the name of the property and the second is the value. Notice that many of the values are actually lists (they have the little ladder icon) -- in most cases these are themselves objects that have been split into this same structure.
Let's take a look at the wind
property. The wind
is in slot 6 of the list. But we are interested in the value associated with the wind, which is in slot 2 of the list at slot 6.
Notice how we first asked for item 6 of the results, and then item 2 of what we read from item 6.
Of course, this result is a further object, which we need to unpack. This all gets a lot cleaner if we use some variables...
So, for example, to find the wind speed, we could do this:
Find the temperature
Now it is your turn. Start with this basic structure:
Notice that I pulled out location
as a variable to make it easier to change the location, and used the to glue the URL together.
Locate the current temperature and have the sprite tell us how warm (or cold) it is in the chosen location.
Note that the location format is important -- city,state code,country code
with no spaces (e.g. middlebury,vt,us
).
(Optional) Improve the interface
Having to type locations into the is a little bit of a pain. Use what you learned in the last exercise and have the sprite ask the user for a city before reporting the temperature there.
You could even go further and ask for the city and state separately and glue them all together to get the format right.
What I will be looking for
- When I click the
, the sprite should say the current temperature
- I can set the city either by setting the variable or because the sprite asked me for the city to observe.
Submitting
Share the project using the instructions from exercise 1.
Visit the exercise page on Canvas to submit the URL.