Skip to content

SADI Semantic Web Services framework

timrdf edited this page Apr 13, 2013 · 57 revisions
csv2rdf4lod-automation is licensed under the [Apache License, Version 2.0](https://github.com/timrdf/csv2rdf4lod-automation/wiki/License)

Semantic Automated Discovery and Integration (SADI) is the coolest way to do web services. It requires so little, and naturally reuses the semantic web to communicate what each service does by using OWL semantics for its inputs and outputs. If OWL is too heavyweight, then you can also just use RDFS. Their source code is on google code, they have sadi-discuss and sadi-dev email lists, and they offer some training sessions, which have some very straightforward and concise introduction materials.

(protege's SADI plugin or curl to POST an RDF file to it)

SADI's hello world from curl

Let's walk through a typical interaction with a SADI service.

Step 1: Find out that http://sadiframework.org/examples/hello is a SADI service.

Step 2: Get a Turtle description of the service from the service itself (using the RDF pocketknife rapper):

rapper -g -o turtle  http://sadiframework.org/examples/hello > service-interface-definition.ttl

Step 3: See what owl:Class it accepts (NamedIndividual):

@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix mygrid: <http://www.mygrid.org.uk/mygrid-moby-service#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .

<http://sadiframework.org/examples/hello>
    mygrid:hasOperation [
        mygrid:inputParameter [
            mygrid:objectType <http://sadiframework.org/examples/hello.owl#NamedIndividual> ;
            a mygrid:parameter
        ] ;

Step 4: Grab the description of NamedIndividual:

rapper -g -o turtle http://sadiframework.org/examples/hello.owl#NamedIndividual > hello.owl

and (Step 5) find out that NamedIndividual needs at least one foaf:name:

<http://sadiframework.org/examples/hello.owl#NamedIndividual>
    a owl:Class ;
    owl:equivalentClass [
        a owl:Restriction ;
        owl:minCardinality "1"^^<http://www.w3.org/2001/XMLSchema#int> ;
        owl:onProperty <http://xmlns.com/foaf/0.1/name>
    ] .

Step 6: Gin up some input to feed the service:

bash-3.2$ cat input.ttl
@prefix foaf: <http://xmlns.com/foaf/0.1/> .

<http://tw.rpi.edu/instances/TimLebo> 
   a <http://sadiframework.org/examples/hello.owl#NamedIndividual>; 
   foaf:name "Tim";
.

Step 7: Send it off with an HTTP POST to get your greeting (to me):

bash-3.2$ curl -H "Content-type: text/rdf+n3" -d @input.ttl http://sadiframework.org/examples/hello
<rdf:RDF
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:hello="http://sadiframework.org/examples/hello.owl#">
  <hello:GreetedIndividual rdf:about="http://tw.rpi.edu/instances/TimLebo">
    <hello:greeting>Hello, Tim!</hello:greeting>
  </hello:GreetedIndividual>
</rdf:RDF>

Add -H "Accept: text/rdf+n3" to get Turtle instead of RDF/XML:

@prefix hello:   <http://sadiframework.org/examples/hello.owl#> .

<http://tw.rpi.edu/instances/TimLebo>
      a       hello:GreetedIndividual ;
      hello:greeting "Hello, Tim!" .

Using Protege's SADI plugin to get a greeting

There is a SADI plugin for Protege that lets you invoke a SADI service using instances in a currently loaded ontology.

A practical example

While browsing the SADI service listing, I noticed http://unbsj.biordf.net/util-sadi-serv/pdf2ascii.

Sounds useful for a variety of applications. Let's see if we can use SADI to get some ascii from a PDF.

$ rapper -q -g -o turtle http://unbsj.biordf.net/util-sadi-serv/pdf2ascii
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix j.0: <http://www.mygrid.org.uk/mygrid-moby-service#> .

<http://unbsj.biordf.net/util-sadi-serv/pdf2ascii>
    j.0:hasOperation <http://unbsj.biordf.net/util-sadi-serv/pdf2ascii#operation> ;
    j.0:hasServiceDescriptionText "Extracts ASCII contents from a PDF file" ;
    j.0:hasServiceNameText "pdf2ascii"^^<http://www.w3.org/2001/XMLSchema#string> ;
    a <http://www.mygrid.org.uk/mygrid-moby-service#serviceDescription> .

<http://unbsj.biordf.net/util-sadi-serv/pdf2ascii#input>
    j.0:objectType <http://unbsj.biordf.net/util-sadi-services/util-sadi-services-ontology.owl#pdf2ascii_Input> ;
    a <http://www.mygrid.org.uk/mygrid-moby-service#parameter> .

<http://unbsj.biordf.net/util-sadi-serv/pdf2ascii#operation>
    j.0:inputParameter <http://unbsj.biordf.net/util-sadi-serv/pdf2ascii#input> ;
    j.0:outputParameter <http://unbsj.biordf.net/util-sadi-serv/pdf2ascii#output> ;
    a <http://www.mygrid.org.uk/mygrid-moby-service#operation> .

<http://unbsj.biordf.net/util-sadi-serv/pdf2ascii#output>
    j.0:objectType <http://unbsj.biordf.net/util-sadi-services/util-sadi-services-ontology.owl#pdf2ascii_Output> ;
    a <http://www.mygrid.org.uk/mygrid-moby-service#parameter> .

OK, it wants an instance of http://unbsj.biordf.net/util-sadi-services/util-sadi-services-ontology.owl#pdf2ascii_Input.

rapper -g -o turtle http://unbsj.biordf.net/util-sadi-services/util-sadi-services-ontology.owl#pdf2ascii_Input shows:

@prefix rss:  <http://purl.org/rss/1.0/> .
@prefix bibo: <http://purl.org/ontology/bibo/> .
@prefix dc:   <http://purl.org/dc/elements/1.1/> .

:pdf2ascii_Input
    a owl:Class ;
    owl:equivalentClass [
        a owl:Class ;
        owl:unionOf (bibo:Document
            [
                a owl:Class ;
                owl:intersectionOf ([
                        a owl:Restriction ;
                        owl:onProperty rss:link ;
                        owl:someValuesFrom xsd:anyURI
                    ]
                    [
                        a owl:Restriction ;
                        owl:hasValue "application/pdf" ;
                        owl:onProperty dc:format
                    ]
                )
            ]
        )
    ] .

So, gin up the following RDF:

@prefix rss:  <http://purl.org/rss/1.0/> .
@prefix bibo: <http://purl.org/ontology/bibo/> .
@prefix dc:   <http://purl.org/dc/elements/1.1/> .

<http://www.springerlink.com/content/v562h13xp5n8u880/fulltext.pdf#>
   a bibo:Document;
   rss:link <http://www.springerlink.com/content/v562h13xp5n8u880/fulltext.pdf>;
   dc:format "application/pdf";
.

Dumb it down to RDF/XML with rapper -g -o rdfxml mydoc.ttl > mydoc.rdf and send it off:

curl -d @mydoc.rdf http://unbsj.biordf.net/util-sadi-serv/pdf2ascii

and get the very disappointing response:

<rdf:RDF
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" > 
</rdf:RDF>

A bit anti-climatic. And, the service doesn't provide contact information, so we're stuck. Bummer.

What next?

See the page on DataFAQs wiki for how to write your first SADI service in python.

Clone this wiki locally