You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 3 Current »

Tupelo includes a Python client for the Tupelo Server Protocol. While it is fully functional, it has several limitations:

  • It is not known to work over HTTPs.
  • It only supports basic authentication
  • Blobs, both on read and write, are held in memory prior to each operation, limiting the size of blobs that can be read and written

Getting the code

The Python client is available as part of the Tupelo 2.4 release. The Tupelo client is in a directory called tupelo-python.

Dependencies

The client requires RDFLib, which it uses to represent RDF metadata.

Usage

To create a Tupelo client object, instantiate tupelo.HttpTupeloClient. Configure the following attributes:

  • hostport - the host and port of the Tupelo Server. Defaults to localhost:8080.
  • path - the path to the Tupelo Server endpoint. Defaults to /tupelo/tupelo.
  • auth - the username and password to authenticate with, separated by a colon. Defaults to user:password.

Once the client is configured, operations can be performed. There is no need to "close" the client when you're finished with it.

Operations

To perform an operation immediately, call the corresponding method. There is no way to "batch" or queue operations.

Data (blobs)

Blobs are simply represented as strings, and the client provides read/write/delete operations on them.

Put

To write a blob, call put with the following parameters:

  • uri - the URI of the blob you want to write
  • data - the octet stream (i.e., bytes) to write

For example:

myclient.put('tag:me@foo.org,2008:blah','This is some data')

Get

To read a blob, call get with the following parameters:

  • uri - the URI of the blob you want to read

It will return the data as a string.

For example:

assert myclient.get('tag:me@foo.org,2008:blah') == 'This is some data'

If no such blob exists, tupelo.NotFoundError will be raised.

Delete

To delete a blob, call delete with the following parameters:

  • uri - the URI of the blob you want to delete

Metadata (RDF)

Metadata is represented as RDF statements, which are represented using constructs from rdflib. Read/write/delete are provided, along with query operations.

MPut

To write metadata, call mput with the following parameters:

  • graph - an rdflib.Graph containing RDF statements

For example:

rdf = """<rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'
                xmlns:a='http://foo.fake/bar#'
                xmlns:t='tag:tupeloproject.org,2004:/test/'>
  <a:Thing rdf:about='http://foo.fake/bar#foo'>
    <a:yez rdf:datatype="urn:cow">zip</a:yez>
    <a:link>
      <a:Thing rdf:about='http://foo.fake/bar#baz'>
        <a:snooz>Hello, world</a:snooz>
      </a:Thing>
    </a:link>
  </a:Thing>
  <t:Person rdf:about='tag:tupeloproject.org,2004:/test/joe'>
    <t:hasParent rdf:resource='tag:tupeloproject.org,2004:/test/carolyn'/>
  </t:Person>
  <t:Person rdf:about='tag:tupeloproject.org,2004:/test/david'>
    <t:hasParent rdf:resource='tag:tupeloproject.org,2004:/test/carolyn'/>
  </t:Person>
  <t:Person rdf:about='tag:tupeloproject.org,2004:/test/genevieve'>
    <t:hasParent rdf:resource='tag:tupeloproject.org,2004:/test/carolyn'/>
  </t:Person>
  <t:Person rdf:about='tag:tupeloproject.org,2004:/test/carolyn'>
    <t:hasParent rdf:resource='tag:tupeloproject.org,2004:/test/zoe'/>
  </t:Person>
</rdf:RDF>
"""
toPut = ConjunctiveGraph()
toPut.parse(StringInputSource(rdf))
myclient.mput(toPut)

MGet

To get metadata, call mget with the following parameters:

  • uri - the URI of the RDF subject to get metadata about
  • depth (optional, default=1) - how many "hops" to fetch (warning: high values of depth can result in poor performance)

It will return the metadata as an rdflib.ConjunctiveGraph.

For example:

fooGraph = myclient.mget('http://foo.fake/bar#foo',2)

MDelete

To delete metadata, call mput with the following parameters:

  • graph - an rdflib.Graph containing the RDF statements to delete

Deleting a statement that is not present on the server is OK and will not cause a failure.

Match

To match a triple pattern, call match with three parameters:

  • subject - the subject URIRef
  • predicate - the predicate URIRef
  • object - the object URIRef or literal

Each of these parameters may be None, which functions as a wildcard, or an rdflib.URIRef, which will match the URI reference exactly. In addition theobject parameter may be a string, which will match a literal exactly.

The return value is an rdflib.Graph containing the matching triples.

For example to find all triples asserting a dc:title of "A Tale of Two Cities":

someGraph = myclient.match(None, URIRef('http://purl.org/dc/elements/1.1/title'), 'A Tale of Two Cities')

If no triples match, an empty graph will be returned.

MQuery SELECT

To issue a SPARQL SELECT query, pass the query to mquery_select. The result will be a list of dictionaries, each of which contains an entry for each variable binding in the solution.

For example:

for result in myClient.mquery_select("""PREFIX tt: <tag:tupeloproject.org,2004:/test/>
SELECT ?gc ?gp
WHERE {
  ?gc tt:hasParent ?p .
  ?p tt:hasParent ?gp . }"""):
    print "%s is the grandchild of %s" % (result['gc'], result['gp'])

MQuery CONSTRUCT

To issue a SPARQL CONSTRUCT query, pass the query to mquery_construct. The result will be an rdflib.Graph containing the constructed statements.

For example:

myGpGraph = myClient.mquery_construct("""PREFIX tt: <tag:tupeloproject.org,2004:/test/>
CONSTRUCT { ?gc tt:hasGrandparent ?gp }
WHERE {
  ?gc tt:hasParent ?p .
  ?p tt:hasParent ? gp . }""")
  • No labels