Introduction to Internet APIs

From edX (link may not be reliable. --MF
An API (is an Application Programming Interface), and it's not specific to the web; it's the idea we explored in week 1 about Abstraction. It is the interface (or specifictaion) between some service or program or block (i.e., procedure or function) that tells another programmer how to use it. One can build extremely cool and powerful applications simply by "glueing" web APIs together.

Last week, you probably wondered if there were a better way to grab data from a web service (e.g., one that gives the weather for a particular zip code). Luckily, there is, but pedagogically we decided to teach you how to slog through the mud (in the rare case that there was no other way) before teaching you to fly over it.

Just as you can call a block from a library loaded in Snap! that you didn't write yourself (like map or substring), the idea here is that there is a way to pass arguments into a program that lives on the web, and have it either:

We'll start easy, with Internet APIs that return simple, human-readable values. We'll start with the API you explored last week.

  1. Bring up a new tab and copy/paste the following URL into it. (or just click on the link) http://ipv4bot.whatismyipaddress.com/. It should have "returned" your IP address. We used this in last week's lab.
  2. Most of the time APIs take input from the user. Here's one that returns the postal zip code given an IP address: http://ipinfo.io/207.192.252.171/postal.
  3. Try another one. Want a random English word? Try this one: http://randomword.setgetgo.com/get.php.
  4. Start a new Snap! project, pick a nice costume for your sprite, and have it start (when the green flag is clicked) by saying "click me to say a random word!". Then, when it is clicked, say the word that results from the http call to the API above as well as an offer to give them another if they click again.
  1. Think about how you might try to "hammer" on that API to find out how many words it has in its database.
  2. While you're at it, why not go back to your "Guess a Word" homework in BJC.2x and use the random word API to generate the word the user should guess, rather than have it come from the stored words in the list.

Lab Quiz

If the Random Word API had 100 words in its database, and you could request a new random word at a rate of one per second, how long would it take until you could guarantee you had extracted every word from it?

- This answer is unanswered.

What is this JSON thing anyway?

JSON (JavaScript Object Notation) is becoming the choice format for Internet APIs to return structured data, i.e., more than just one simple thing. It's optimized for computers to be able to understand, not for humans to read.

You feel like hearing a joke, and you heard there was an internet API that could serve one up. Let's try it.

  1. Go to http://tambal.azurewebsites.net/joke/random. Note that the joke is surrounded by strange characters.
  2. {"joke":"Two guys walk into a bar. You'd think the second one would have noticed."}
  3. Refresh the window a few times; notice how the jokes change but the format of strange characters doesn't (that's a good thing).

We could either user our scraping technique from the last lab to extract the joke, or we could learn how to extract it correctly. Rather than teach you the format of JSON, which you are welcome to read about on Wikipedia, we'll teach you how to work with it.

The basic idea is that JSON data is either one of three things:

  1. A number, boolean, null, or string (just like in Snap!). If you're looking at JSON, the strings are surrounded by quotes, the booleans are true and false, and null is null (an empty value in Snap!).
  2. A list (just like in Snap!). If you're looking at JSON, it's square brackets surrounding comma-separated elements, like this: [3, 2, 1, "Hike", true, false, null]
  3. An undordered collection (in Snap! it becomes a list) of key-value pairs (which in Snap! is a two-element list, with the first item as the key (a string), and the second item as the value. If you're looking at JSON, it's curly brackets surrounding comma-separated key-value pairs (whose keys and values are separated by a colon). In the back of your head, you can think of the colon as an equal sign. So in the following example: {"Course":"BJC", "Quarter":3, "Instructor":"Dan Garcia"}, it means that the course is BJC, it's the 3rd quarter class (i.e., BJC.3x), and Dan is the instructor.

Note that the elements of lists and the value of a key-value pair can also be one of those three things. So you can see how it can quickly become a very complicated mess of commas, colons, quotes, square and curly brackets:

{"coord":{"lon":-122.08,"lat":37.39}, "weather":[{"id":803, "main":"Clouds", "description":"broken clouds", "icon":"04n"}], "base":"cmc stations", "main":{"temp":282.47, "pressure":1022, "humidity":87, "temp_min":279.45, "temp_max":285.15}, "wind":{"speed":1.5, "deg":180}, "clouds":{"all":75}, "dt":1453619275, "sys":{"type":1, "id":471, "message":0.0036, "country":"US", "sunrise":1453648644, "sunset":1453685029}, "id":5375480, "name":"Mountain View", "cod":200}

Our philosophy in BJC is to shield you from JSON (say it with me, everyone: abstraction) by immediately converting it into Snap! lists. Then you have to figure out how to work with that, using either list operators or something to query value from the collection of key-value pairs. p.s. If you ever come face-to-face with JSON, and don't have Snap! handy, there are a few very good online JSON viewers that let you copy in JSON and view it in a tree format. Let's take a look at the blocks we provide you with to help, listify (that takes JSON and Snap!-ifies it), and query (that can return the value from a list of key-value pairs): Listify example Query example

One of the best practices we've seen with Internet APIs is to save the value returned from http into a global variable, we like to call JSON, then you never have to worry about your Internet connection or long delays to receive the same request over and over as you're debugging your query blocks "down river".
  1. Load this starter JSON-parsing project; we've already loaded "tools", "proxied http", "listify", and "query" to help you parse the listified (aka Snap!-ified) JSON.
  2. Build an app that tells a random joke when it starts, using the joke API, listify and query.
  3. Query temperature from hard-coded Mountain View JSON
  4. Copy and paste the weather JSON example above into a call to your listify block and create a program that (using appropriate calls to Query, we've shown an example above to extract the temperature), on Green flag startup, says:
    In Mountain View, the weather is Clouds with the temperature of 282.47 Kelvin.
    Another idea is to save the Snap!-ification of JSON into another variable called LoL (for lists-of-lists), make sure the LoL watcher checkbox is checked, go to full-screen mode and expand the list by clicking the "grow" region in the bottom-right corner to see what's in it.
  1. Read the documentations of OpenWeatherMap and figure out how to call it with your hard-coded location, and take that JSON and use it instead of the Mountain View one above so your program says your weather. Note that the API uses an appid key (similar to a cookie) to know you're you. We've found the best results when we clicked on the link below By ZIP code, generated JSON for Mountain View (notice the URL added an appid number?) Now just change the five numbers in the zip code to another one, and voilá! Then copy that URL and put it in your Snap! proxied http call (without the http://, remember), appid and all.
  2. Remove the hard-coding of your location and use the tools from the last problem on the last lab to get your location automatically, so your app will alwyas work and say the correct weather whereever you are.

Lab Quiz

Instead of using Query, you find that you could also explicitly walk down the Snap!-ified JSON list-of-lists by using the item( )of( ) block. What do you think of this idea?

- This answer is unanswered.

Breaking out on your own

Even though it's not the point of the exercise, it's really fun to add some graphics and sounds to Internet API projects after you get it working, to make it look more polished.

Now let's see you whip up some quick, fun programs.

  1. There's a service that will tell you what gender it thinks your name is at genderize.io; create an app that (over an over) asks for a name and then says "I believe the chance that (name) is a (gender) is (probability)", with the values in parenthesis coming from the API call. E.g., the call https://api.genderize.io/?name=dan returned {"name":"dan", "gender":"male", "probability":"0.98", "count":3240}, which you would translate to:
  2. I believe the chance Dan is a male is 98%
  3. Questions from the television show Jeopardy are available at jservice.io/api/random, create an app that (over and over) shows the title and question from a random Jeopardy question, then when space bar is hit, shows the answer (but read as "what is (answer)?"). Note that sometimes there's HTML included in the results; we don't expect you to have to worry about that, but think about how you might clean that up if you're so inclined.
  1. Take a look at this directory of Internet APIs (change "by Protocols/Formats" to "JSON") and take a look at some of the amazing things you can do with this power! Build an app that uses one of the APIs not listed here.