Sample Solid application on Python Flask

Recently, we stumbled upon Inrupt’s Solid and after going through their fundamental documentation, we became keen on building a sample solid application and get a better understanding of it. All of Solid’s examples are built on JQuery and NodeJS. We like Python and so we wanted to build some Python-based examples. This post will focus on how to use Python to load, parse and traverse Solid data.


Before going into deep details, lets first understand what Solid is about and what kind of data it deals with.

Solid Overview

Solid (derived from “social linked data”) is a decentralized platform for social Web applications. In the Solid platform, each user stores their data in personal online datastore (or pod) served by different public pod servers and identity providers. In solid, the applications and data are decoupled. Applications built using Solid platform do not have their own data but they can access data which is stored in a place of user’s choice using different protocols, authentication and access control system.

Before going into details of our code, we will first understand about few most commonly used terms in Solid which we will be referring in below sections like POD, WebID, Linked data, Namespaces and RDF(Resource Description framework) which is the data model for Linked Data.


POD(Personal online datastore)

In Solid platform, each user stores their data in a personal online datastore (pod) that resides on a pod server. You can give applications read/write access to parts of your data in POD. You can learn more about Solid POD’s here


WebID

Solid uses WebID URIs as universal usernames. When you register with Solid, you get a public Solid POD URL(which is like the homepage for your Solid pod) and public Solid WebID which acts as a global ID that you can use to identify and authenticate yourself with other PODs across the world. In Solid, the registered identity provider stores the user’s profile document in Turtle and RDF formats. You can learn more about WebID here


Linked Data

In Solid platform, users can store any piece of the data in their pods and this data in one pod can be linked with data in different pods. This connected data is referred to as Linked Data. You can learn more about Linked Data here


Namespaces in RDF

RDFLib provides several short-cuts to working with many URIs in the same namespace. The purpose of the namespace is simply to avoid name conflicts with tags of the same name. You can refer here for more details on RDF Vocabulary and namespaces


RDF – the data model for Linked Data

Linked Data is typically represented in RDF, the Resource Description Framework. It is based on the idea of making statements about resources in expressions of the form subject–predicate–object, known as triples. RDF has different syntaxes like Turtle, N-Triples, N3, JSON-LD, RDF/XML etc., You can learn more about RDF here


Sample Python solid profile viewer application

Based on the example profile viewer app, we built a sample python solid application using flask. This profile viewer will show data from different people’s profiles based on the given WebID. We used python rdflib library for reading Solid data.

Pre-requisites: In order to read and write Solid data, we need our own Solid POD and identity. We created a POD from Get a Solid POD

To brief, our sample solid python web application does the following:

1. Gets the user input ‘Profile’ webID using the HTTP Get method.
2. Creates an RDF Graph
3. Based on the webID, reads data from a Solid pod.
4. Parse the data returned into a graph
5. Get the friends list for the given webID
6. Display the returned friends webID list on the browser.

To get started, we need to download and install some Python modules. While there are several Python modules for working with RDF data, this post will focus on RDFLib. The RDFLib module provides a powerful set of tools for creating, parsing, traversing and editing RDF data. It allows us to interact with Linked Data stored in Solid pods.

RDFLib aims to be a pythonic RDF API, a Graph is a python collection of RDF Subject, Predicate, Object Triples:

Let’s dive into the code. We created a file named ‘sample_python_solid.py‘ with following content:

"""
This is a Flask application for Inrupt Solid profile viewer. 
 
"""
 
from flask import Flask, jsonify, render_template, request
import json
import logging
import urllib2
import rdflib   
from rdflib import URIRef,Graph,RDF
from rdflib.namespace import FOAF
 
 
app = Flask(__name__)
 
def post_friends_list(uri):
    "create,parse graph and get the friends list for the given URI"
    # Create a Empty graph      
    graph = rdflib.Graph()   
    graph.parse(uri)   
    for person in graph[: RDF.type: FOAF.Person]:
        name = graph.value(person, FOAF.name)             
        friends = list(graph[person:FOAF.knows])
        app.logger.info('%s friends', friends)
        if friends:
            app.logger.info("%s's friends:", graph.value(person, FOAF.name))           
 
        return friends,name          
 
 
@app.route("/", methods=['GET','POST'])
@app.route("/view", methods=['GET','POST'])
def view():
    "Endpoint for getting the friends list for the given URI"
    if request.method == 'GET':
        #return the form
        return render_template('sample_solid.html')
    if request.method == 'POST':
        #return the answer
        uri = request.form.get('profile')        
        result,name = post_friends_list(uri)        
        api_response = {"answer": result, 
                        "name": name}        
        return jsonify(api_response)
 
 
#---START OF SCRIPT
if __name__ == '__main__':
    app.run(host='127.0.0.1', port=6464, debug= True)

First, we make a Flask object, use the ‘route’ decorator functions to define GET (Render a template when the route is triggered with GET method) and POST (post URI to that URL). Then, call post_friends_list() function(which we will be discussing in below section) and finally a ‘run’ function when we run it locally (which you can confirm by calling python sample_python_solid.py and visiting localhost:6464 in your browser.)


Using built-in RDFLib functions

In the above code, you can see a method called post_friends_list(), which is the actual python code in which we used RDFLib libraries to create a RDF Graph. A Graph is a python collection of RDF Subject, Predicate, Object Triples. It is like a database which is arbitrary in terms of what is related to what. The way you parse RDF with rdflib is you create a Graph, which is a sort of empty holder for data. Imagine this as a big container for data, and you can throw into the container as much data as you like, then just filter out the bits you want.

First we should import the Graph class from the rdflib package and create a Graph instance as shown below:

 
from rdflib import URIRef, Graph
 
graph = rdflib.Graph()

The ‘graph’ variable now has an empty graph. Now we should load some data into the graph. The graph object has a method called ‘parse’ which allows you to give it a file name from your local system or an HTTP URI and it will try to load data from that source. In our case, we’ll load in data to parse a specified URI which the user inputs in the URL.

To fetch user’s profile document, we are iterating over the triples and getting the name of the person using FOAF(Friend of a Friend) Vocabulary. Below are the steps performed:

1. Loop over each FOAF: Person in the graph(RDF.type: FOAF.Person)
2. Using graph.value() to get the person’s name
3. Fetch the list of friends using graph[person:FOAF.knows] attribute.
4. Return the user full name and his friend’s webID list.

Sample Solid Python Application

About our HTML page

We have a input field which accepts the webID from the user. When clicked on the View button the user information(Full Name and friend’s list) is loaded in the browser page. We have written Javascript code to make the friend’s webID clickable. When a webID link is clicked from the friend’s list, that person’s webID is loaded into the Profile input field and when the user clicks on the View Button, the name of his friends is loaded in the page. This information is fetched directly from the friend’s pods. Note:- You need to add a few friends to your profile before trying this.


You can find the code associated with this post on Qxf2’s GitHub. We hope this article helps you get started with implementing Solid web applications using python.


References

1. Solid – Getting Started
2. RDFLib Documentation
3. Making sense of linked data with python

Indira Nellutla

I am an engineer with about 10 years of experience in software development and testing. Prior to joining Qxf2, I worked with reputed companies like Dell and Infosys. They helped me gain good experience in the manufacturing and healthcare domains. My QA career started at Dell. I got exposure to various testing tools, processes and methodologies, got an opportunity to work on various platforms like JMS Hermes, SOAP UI, data integration, queues, etc. I chose Qxf2 because it allowed remote working. My interests are vegetable gardening using organic methods, listening to music and reading books.

Be First to Comment

Leave a Reply

Your email address will not be published.