Lab: Web APIs and JSON-LD

From info216
Revision as of 05:02, 17 April 2020 by Say004 (talk | contribs)
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

Lab 12: Accessing and lifting Web APIs (RESTful web services)

Topics

Programming regular (non-semantic) as well as semantic Web APIs (RESTful web services) with JSON and JSON-LD.


Imports

  • import requests
  • import json
  • import pprint

Tasks

Regular JSON web APIs

Write a small program that accesses a regular (non-semantic) web API and download the result. The "json" library in python can be used to load a json string as a json object (json.loads(data)). Use the the prettyprint import to print a readable version of the json object.

The GeoNames web API (http://www.geonames.org/export/ws-overview.html) offers many services. For example, you can use this URL to access more information about Ines' neighbourhood in Valencia: http://api.geonames.org/postalCodeLookupJSON?postalcode=46020&country=ES&username=demo (register to get your own username instead of "demo").

You do not have to use the GeoNames web API. There are lots and lots of other web APIs out there. But we want something simple that does not require extensive registration (HTTPS can also make things more complex when the certificates are outdated). Here are some examples to get you started if you want to try out other APIs: http://opendata.app.uib.no/ , http://data.ssb.no/api , http://ws.audioscrobbler.com/2.0/ , http://www.last.fm/api /intro , http://wiki.musicbrainz.org/Development/JSON_Web_Service .

While you are testing and debugging things, it is good to make measures so that you do not need to call the GeoNames or other API over and over. A solution can be writing the returned data to a file, or copying it into a variable.

Here is an example of a results string you can use, if you have trouble connecting to GeoNames (note that you have to escape all the quotation marks inside the Java string): {\"postalcodes\":[{\"adminCode2\":\"V\",\"adminCode1\":\"VC\",\"adminName2\":\"Valencia\",\"lng\":-0.377386808395386,\"countryCode\":\"ES\",\"postalcode\":\"46020\",\"adminName1\":\"Comunidad Valenciana\",\"placeName\":\"Valencia\",\"lat\":39.4697524227712}]}"

Lifting JSON to JSON-LD

So far we have only used plain JSON. Now we want to move to JSON-LD. Make a new HashMap (and therefore also a JSON object) called context. Put a single entry into this map, with "@context" as the key and another HashMap as the value. It is this second map that contains the actual mappings. Put at least one pair of strings into it. For example, if you used the postcode API, the pair "lat" and "http://www.w3.org/2003/01/geo/wgs84_pos#lat". You can also put the pair "lng" and "http://www.w3.org/2003/01/geo/wgs84_pos#long".

Create a JsonLdOptions object and set its expand context to be the context object with the pair of strings in. Use the JsonLdProcessor to expand your jsonObject and pretty print the result. Has anything happened? Why/why not?!

Add this pair too to the context object: "postalcodes" and "http://dbpedia.org/ontology/postalCode". Rerun. Has anything happened now? Why/why not?!

Explanation: Did you JSON object contain other (nested) objects as values? If you try to map the names inside such a nested object, the expansion will only work if you map the name of the nested object itself too.

Add more string pairs, using existing or inventing new terms as you go along, to the context object and rerun expand. The expanded JSON object lifts the data from the web API. It can be used to provide a semantic version of the original web API.

In addition to expand, try the compact and flatten operations on the JSON object. What do they do?

Go back to the RDF/RDFS programs your wrote in labs 2 and 3. Extend the program so that it adds further information about the post codes of every person in your graph.

We will now make a Jena model from the JSON-LD object. To do this, first create a new default Jena model. Then convert the JSON-LD object to a string (use JsonUtils.toPrettyString). Then turn the string into an input stream (use IOUtils.toInputStream, with "UTF-8" as character set). Then read the input stream into your Jena model (use model.read). (There may be other ways to move from JSON object to Jena models, but this is a simple and straightforward way to start.)

Congratulations - you have now gone through the steps of accessing a web API over the net, lifting the results using JSON-LD, manipulating the in JSON-LD and reading them into a Jena RDF model. Of course, it is easy to convert the Jena model back into JSON-LD using model.write(..., "JSON-LD") ...

Parsing JSON-LD with RDFlib

Useful Reading

- Reading and writing with JSON - stackabuse.com