Making Semantic Web Applications With Flask: Starting With FOAF
WHEN INTRODUCING the Semantic Web, Sir Tim Berners-Lee asked us to share not just our documents, but also our data. The Semantic Web uses the internet as a database. A big, messy, poorly organised database with latency and availability issues. But this is still better than the big, messy, poorly organised collection of documents with latency and availability issues that currently comprises the world-wide-web. Plus, you can exploit it in some really useful ways.
As web-developers we use databases on a regular basis. We make them to suit our own needs, use our own terms, and manage them ourselves. On the Semantic Web, we need to link all our data together, if we tried this with all our databases we’d likely find don’t align very nicely. So in the Semantic Web we borrow from ontology. An ontology is designed to represent the truth, as opposed to fulfil our needs, they define terms so everyone has a common language, and they are created by teams of experts.
We’re going to use an ontology called “FOAF”, it’s one of the early explorations into semantic web and a good place to start. We’ll create our own FOAF file and make it available via Flask. We’ll then consume our own data in our application and make it discoverable for others. In later posts we’ll look at how Google, Facebook and Twitter consume semantic web data and how we can consume data from other sources too.
Get FOAF
YOU CAN read all the FOAF docs for the FOAF terminology
and write out your own FOAF.rdf
file in XML. But I’d recommend you visit
foaf-a-matic and use the free tool Leigh Dodds
created to generate one. You can always add to it later.
The file you’ll get will be in XML, you should save it as foaf.rdf
. Not all
semantic web documents are in XML, you can also use JSON-LD and there’s N3 or Turtle
if you’d like something with a YAML feel. But this is an old tool, so XML it is. This
is an excerpt from my file.
<foaf:Person rdf:ID="me">
<foaf:name>Paul Brown</foaf:name>
<foaf:title>Mr</foaf:title>
<foaf:givenname>Paul</foaf:givenname>
<foaf:family_name>Brown</foaf:family_name>
<foaf:homepage rdf:resource="http://www.paulbrownmagic.com"/>
</foaf:Person>
Get Flask
FLASK IS a light-weight web development for Python, we’re using it because it’s unopinionated, meaning it’s easy us to work with RDF data.
We’ll go through what you need for this application, but if Flask is new to you, I’d recommend their tutorial.
First we need to pip install
Flask.
:~$ pip3 install flask
Next, setup the directory structure. I usually have a directory for all my rdf
in static
, along with ones for css, javascript, images etc.
foaf_flask/
|-- dev.py
|-- foaf_flask/
| |-- main.py
| |-- templates/
| |-- index.html
| |-- static/
| |-- rdf/
| |-- foaf.rdf
Let’s start with some code. dev.py
is to run inbuilt development server, when
you actually deploy a Flask application you’ll want something better but it’ll do
for now. This file is our entry point and just runs that app.
from foaf_flask.main import app
if __name__ == "__main__":
app.run(debug=True)
Now for the real code, this is main.py
. It’s your Flask “Hello, world” with
a template.
from flask import Flask, render_template
app = Flask(__name__)
@app.route("/")
def home_page():
return render_template("index.html")
This is the template index.html
.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>FOAF With Flask</title>
</head>
<body>
<h1>Hello, world!</h1>
</body>
</html>
Run the app, open your browser at http://127.0.0.1:5000 and you should see “Hello, world!”. If you go to http://127.0.0.1:5000/static/rdf/foaf.rdf you will get your FOAF. Congratulations, you can now publish data to the semantic web!
:~$ python3 dev.py
Consume Your Data
WE’VE GOT some data, we may as well use it. Plus, this demonstrates one of the dreams of the semantic web. Imagine you got married and changed your name. How many accounts would you need to update? Wouldn’t it be easier to just update your FOAF and allow all your accounts to get their information from there?
To consume our data we’ll use rdflib
, which is Python’s library for handling
your semantic web data. We’ll read our FOAF into it, run a SPARQL query against it,
and send the result to our template. First, we need to install rdflib
.
:~$ pip3 install rdflib
Now let’s update main.py
. The SPARQL query here makes sure we’re getting the
foaf:givenname
of a foaf:Person
. It assumes it will be returning rows of results,
we know we only need the first row, so we only return that from get_me()
.
from flask import Flask, render_template
from rdflib import Graph
from rdflib.namespace import FOAF
app = Flask(__name__)
foaf = Graph()
foaf.parse("flask_foaf/static/rdf/foaf.rdf")
def get_me():
res = foaf.query("""SELECT DISTINCT ?fname
WHERE {
?me a foaf:Person .
?me foaf:givenname ?fname .
}
""", initNs={"foaf": FOAF})
return list(res)[0]
@app.route("/")
def home_page():
return render_template("index.html",
me= get_me()
)
In the template we can access the ?fname
using object notation: me.fname
.
Here’s the updated template.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>FOAF With Flask</title>
</head>
<body>
<h1>Hello, world!</h1>
<p> My name is {{ me.fname }}.</p>
</body>
</html>
Run the application and you’ll see your name. Congratulations, you can query and use your FOAF file data. To adapt your query, look at the terms in the FOAF docs. Can you get your full name?
Make Your Data Discoverable
THE LAST step is to help machines and people find your FOAF file. The recommended
method is to use the link
tag in the head of your HTML. That’ll help machines, but
I’d also recommend putting a visible link to it for people, like I have in my footer.
I’ve provided you with the link
tag to put in the <head></head>
of your index.html
.
<link href="{{ url_for('static', filename='rdf/foaf.rdf', _external=True) }}" rel="meta" title="FOAF" type="application/rdf+xml">
Conclusion
YOU CAN now host an RDF file, SPARQL query it, use that data in your template and make the RDF file discoverable. There’s still a lot to learn! I’d recommend adding some more information to your FOAF using their terms and playing with SPARQL queries on your FOAF file for now.
In later posts we’ll look at including the data in your HTML, who consumes this data and how you can exploit that, other ways to serve your data and how you can consume other’s data. If you publish your FOAF, let me know in the comments.
Until next time, happy coding. Paul
Get The Code
THE CODE for this tutorial is available on github at: https://github.com/PaulBrownMagic/flask_foaf
*[FOAF]: Friend Of A Friend