OldMan: Python OLDM

Wise old man from https://openclipart.org/detail/190655/wise-old-man-by-j4p4n-190655

OldMan is a Python Object Linked Data Mapper (OLDM). It relies on the popular RDFlib Python library. See the foreword for further characteristics.

User’s Guide

Foreword

OldMan is a Python Object Linked Data Mapper (OLDM).

An OLDM let you create, retrieve and update RDF representations of Web Resources by manipulating them as Python objects.

OldMan, in its core, is based on two W3C standards:

  1. RDF (the Resource Description Framework) as data model;
  2. JSON-LD context for mapping objects and RDF graphs.

It is designed to support multiple protocols for interacting with data stores hosting these resources. Currently, only SPARQL is officially supported.

OldMan relies on the RDFlib Python library.

Why a new term?

Some similar projects employ the term Object RDF Mapper for denoting the mapping between objects and RDF graphs. This terminology uses the same initials than the well-known notion of Object Relational Mapper (ORM) that consider table rows instead of RDF graphs.

The Object Linked Data Mapper (OLDM) term avoids this confusion. It also emphasizes that the manipulated resources can be on the Web, not just in a local database. It should lead users to interact with data stores on which they not always have full control (e.g. a tiers Web API).

Mission

OldMan has one main objective: help you to declare your models using RDF triples and JSON-LD contexts instead of programming Python model classes yourself.

However, OldMan does not force you to express all your domain logic in a declarative style. OldMan makes easy for you to add dynamically plain-old Python methods to resource objects.

By adopting a declarative style:

  1. You can provide both RDF and JSON data to your clients.
  2. Your schema (including validation constraints) can be published and reused by hypermedia-driven Web clients.
  3. Your declared domain logic becomes independent of Python and its frameworks.

It also acknowledges that IRIs or compact URIs (CURIEs) -like strings are not always pleasant to use: arbitrary short names and objects are usually more user-friendly. However, you can still manipulate IRIs when it is relevant for you to do so. Everything remains mapped to IRIs.

Current core features

  • Resource-centric validation based on RDF vocabularies:

  • Inheritance (attributes and Python methods);

  • An attribute can require its value to be a collection (a set, a list or a language map);

  • Arbitrary attribute names (e.g. plural names for collections);

  • Separation between the client and data store models;

  • Extensibility to various sorts of data stores (not just SPARQL endpoints);

  • IRI generation for new resources (if not done by the remote data store);

  • Optional resource cache relying on the popular dogpile.cache library.

Status

OldMan is a young project still in an early stage. Feel free to contribute and to subscribe to our mailing list oldman AT librelist.com.

Only Python 2.7 is currently supported, but support for Python 3.x is of course something we would like to consider.

Planned features

See our issue tracker.

Continue to installation or the quickstart.

Installation

Python 2.7 is required, so if in your distribution you have both Python 2.7 and Python 3.x, please make sure you are using the right version (usually, the command python links to Python 3.x).

Virtualenv

We recommend you to isolate the installation of OldMan and its dependencies by using Virtualenv.

If virtualenv is not already installed on your computer, you can install it with easy_install or pip:

$ sudo easy_install-2.7 install virtualenv

or:

$ sudo pip2 install virtualenv

Now create a directory where to install your virtualenv. For instance:

$ mkdir -p ~/envs/oldman-2.7

Move in, init and activae your virtualenv:

$ cd ~/envs/oldman-2.7
$ virtualenv2 .
$ source bin/activate

Install OldMan and its dependencies

$ mkdir src
$ cd src
$ git clone https://github.com/oldm/OldMan.git oldman
$ cd oldman

Install first the concrete requirements:

$ pip install -r requirements.txt

And then install oldman and its abstract (not yet fulfilled) dependencies:

$ python setup.py install

To test your installation, we encourage you to install the nose testing library:

$ pip install nose

You can run the tests:

$ nosetests tests/

Hope everything is ok!

Continue to the quickstart example.

Quickstart

Model creation

1. Get the declared domain knowledge

First, let’s import some functions and classes:

from rdflib import Graph
from oldman import create_mediator, parse_graph_safely, SparqlStore

and create the RDF graph schema_graph that will contain our schema:

schema_graph = Graph()

The role of the schema graph is to contain most of the domain logic necessary to build our models. In this example, we load it from a RDF file:

schema_url = "https://raw.githubusercontent.com/oldm/OldMan/master/examples/quickstart_schema.ttl"
parse_graph_safely(schema_graph, schema_url, format="turtle")

Another main piece of the domain logic is found in the JSON-LD context. Here, we just need its IRI:

ctx_iri = "https://raw.githubusercontent.com/oldm/OldMan/master/examples/quickstart_context.jsonld"

We now have most of the domain knowledge we need to instantiate the store and its models.

2. Instantiate the store

Here, we consider an in-memory triplestore (read-write SPARQL endpoint) as a store (SparqlStore):

# In-memory triplestore
data_graph = Graph()
store = SparqlStore(data_graph, schema_graph=schema_graph)

We extract the prefix information from the schema graph:

store.extract_prefixes(schema_graph)
3. Create the store model

We create a LocalPerson StoreModel for the store. Like for any model, we need:

  • The IRI or a JSON-LD term of the RDFS class of the model. Here “LocalPerson” is an alias for http://example.org/myvoc#LocalPerson defined in the context file ;
  • The JSON-LD context.

Moreover, since this model is associated to a store with limited capabilities (SparqlStore), it also has to generate IRIs for new resources. Here we provide the following additional information:

  • A prefix for creating the IRI of new resources (optional) ;

  • An IRI fragment (optional);

  • To declare that we want to generate incremental IRIs with short numbers for new Resource objects (optional).

    store.create_model("LocalPerson", ctx_iri, iri_prefix="http://localhost/persons/",
                            iri_fragment="me", incremental_iri=True)
    
4. Load the mediator and the client model

Store models are not directly manipulated; the user is expected to use their relative client models instead. Oldman distinguishes client and store models so that they can have (if necessary) a slightly different but compatible domain logic. However here, for the sake of simplicity, client models are directly derived (i.e. imported) from the store models.

First we instantiate a Mediator object that will be in charge of the mediation between the client and store models:

mediator = create_mediator(store)

Then we import the client model from the store model:

mediator.import_store_models()

lp_model = mediator.get_client_model("LocalPerson")

That’s it, now our client model is ready to be used for creating new resources.

Resource editing

Now that the domain logic has been declared, we can create ClientResource objects for two persons, Alice and Bob.

Oldman requires the creation of a new ClientResource to be done inside a ClientSession for performance reasons.

session1 = mediator.create_session()

alice = lp_model.new(session1, name="Alice", emails={"alice@example.org"},
                     short_bio_en="I am ...")
bob = lp_model.new(session1, name="Bob", blog="http://blog.example.com/",
                   short_bio_fr=u"J'ai grandi en ... .")

We now have to ClientResource in memory but Alice and Bob are not yet in the store. Actually, Bob is not ready yet to be persisted because some information is still missing: its email addresses. This information is required by our domain logic. Let’s satisfy this constraint and flush the session:

>>> bob.is_valid()
False
>>> bob.emails = {"bob@localhost", "bob@example.org"}
>>> bob.is_valid()
True
>>> session1.flush()

Let’s now declare that they are friends and save this change:

alice.friends = {bob}
bob.friends = {alice}
session1.flush()

That’s it. Have you seen many IRIs? Only one, for the blog. Let’s look at them:

>>> alice.id
"http://localhost/persons/1#me"
>>> bob.id
"http://localhost/persons/2#me"
>>> bob.types
[u'http://example.org/myvoc#LocalPerson', u'http://xmlns.com/foaf/0.1/Person']

and at some other attributes:

>>> alice.name
"Alice"
>>> bob.emails
set(['bob@example.org', 'bob@localhost'])
>>> bob.short_bio_en
None
>>> bob.short_bio_fr
u"J'ai grandi en ... ."

We can also assign an IRI when creating a ClientResource object:

>>> john_iri = "http://example.org/john#me"
>>> john = lp_model.new(session1, iri=john_iri, name="John", emails={"john@example.org"})
>>> session1.flush()
>>> john.id.iri
"http://example.org/john#me"

Resource retrieval

By default, resources are not cached. We can retrieve Alice and Bob from the data graph as follows:

>>> alice_iri = alice.id.iri
>>> session2 = mediator.create_session()
>>> # First person found named Bob
>>> bob = lp_model.first(session2, name="Bob")
>>> alice = lp_model.get(session2, iri=alice_iri)

>>> # Or retrieve her as the unique friend of Bob
>>> alice = list(bob.friends)[0]
>>> alice.name
"Alice"

Finds all the persons:

>>> set(lp_model.all(session2))
set([ClientResource(<http://example.org/john#me>), ClientResource(<http://localhost/persons/2#me>), ClientResource(<http://localhost/persons/1#me>)])
>>> # Equivalent to
>>> set(lp_model.filter(session2))
set([ClientResource(<http://localhost/persons/1#me>), ClientResource(<http://localhost/persons/2#me>), ClientResource(<http://example.org/john#me>)])

Serialization

JSON:

>>> print alice.to_json()
{
  "emails": [
    "alice@example.org"
  ],
  "friends": [
    "http://localhost/persons/2#me"
  ],
  "id": "http://localhost/persons/1#me",
  "name": "Alice",
  "short_bio_en": "I am ...",
  "types": [
    "http://example.org/myvoc#LocalPerson",
    "http://xmlns.com/foaf/0.1/Person"
  ]
}

JSON-LD:

>>> print john.to_jsonld()
{
  "@context": "https://raw.githubusercontent.com/oldm/OldMan/master/examples/quickstart_context.jsonld",
  "emails": [
    "john@example.org"
  ],
  "id": "http://example.org/john#me",
  "name": "John",
  "types": [
    "http://example.org/myvoc#LocalPerson",
    "http://xmlns.com/foaf/0.1/Person"
  ]
}

Turtle:

>>> print bob.to_rdf("turtle")
@prefix bio: <http://purl.org/vocab/bio/0.1/> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix myvoc: <http://example.org/myvoc#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix xml: <http://www.w3.org/XML/1998/namespace> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

<http://localhost/persons/2#me> a myvoc:LocalPerson,
        foaf:Person ;
    bio:olb "J'ai grandi en ... ."@fr ;
    foaf:knows <http://localhost/persons/1#me> ;
    foaf:mbox "bob@example.org"^^xsd:string,
        "bob@localhost"^^xsd:string ;
    foaf:name "Bob"^^xsd:string ;
    foaf:weblog <http://blog.example.com/> .

Validation

Validation is also there:

>>> # Email is required
>>> lp_model.new(session1, name="Jack")
>>> session1.flush()
oldman.core.exception.OMRequiredPropertyError: emails

>>> # Invalid email
>>> bob.emails = {'you_wont_email_me'}
oldman.core.exception.OMAttributeTypeCheckError: you_wont_email_me is not a valid email (bad format)

>>> # Not a set
>>> bob.emails = "bob@example.com"
oldman.core.exception.OMAttributeTypeCheckError: A container (<type 'set'>) was expected instead of <type 'str'>

>>> # Invalid name
>>> bob.name = 5
oldman.core.exception.OMAttributeTypeCheckError: 5 is not a (<type 'str'>, <type 'unicode'>)

>>> session1.close()
>>> session2.close()

Domain logic

Here is the declared domain logic that we used:

JSON-LD context https://raw.githubusercontent.com/oldm/OldMan/master/examples/quickstart_context.jsonld:

{
  "@context": {
    "xsd": "http://www.w3.org/2001/XMLSchema#",
    "foaf": "http://xmlns.com/foaf/0.1/",
    "bio": "http://purl.org/vocab/bio/0.1/",
    "myvoc": "http://example.org/myvoc#",
    "Person": "foaf:Person",
    "LocalPerson": "myvoc:LocalPerson",
    "id": "@id",
    "types": "@type",
    "friends": {
      "@id": "foaf:knows",
      "@type": "@id",
      "@container": "@set"
    },
    "short_bio_fr": {
      "@id": "bio:olb",
      "@language": "fr"
    },
    "name": {
      "@id": "foaf:name",
      "@type": "xsd:string"
    },
    "emails": {
      "@id": "foaf:mbox",
      "@type": "xsd:string",
      "@container": "@set"
    },
    "blog": {
      "@id": "foaf:weblog",
      "@type": "@id"
    },
    "short_bio_en": {
      "@id": "bio:olb",
      "@language": "en"
    }
  }
}

Schema (uses the Hydra vocabulary) https://raw.githubusercontent.com/oldm/OldMan/master/examples/quickstart_schema.ttl:

@prefix bio: <http://purl.org/vocab/bio/0.1/> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix hydra: <http://www.w3.org/ns/hydra/core#> .
@prefix myvoc: <http://example.org/myvoc#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .

# Properties that may be given to a foaf:Person (no requirement)
foaf:Person a hydra:Class ;
    hydra:supportedProperty [ hydra:property foaf:mbox ],
        [ hydra:property foaf:weblog ],
        [ hydra:property foaf:name ],
        [ hydra:property bio:olb ],
        [ hydra:property foaf:knows ].

# Local version of a Person with requirements
myvoc:LocalPerson a hydra:Class ;
    rdfs:subClassOf foaf:Person ;
    hydra:supportedProperty [ hydra:property foaf:mbox ;
            hydra:required true ],
        [ hydra:property foaf:name ;
            hydra:required true ].

Core concepts

THIS PAGE IS OUT-DATED. TODO: rewrite it.

Resource

A Resource object represents a Web resource identified by a regular IRI (internationalized URI) or or a skolem IRI (if it should treated as a blank node).

In OldMan, Web resources are described in conformance to the Resource Description Framework (RDF). A Resource object may have some attributes that provide the predicate (also called property) and the object terms of RDF triples describing the resource. The resource itself is the subject of the triple (expect if the property is reversed). Its attributes have arbitrary short names as defined in the JSON-LD context.

A Resource object access to its attributes through the Model objects to which it relates (through its types). Thus, if it has no type or its types that are not related to a Model object, a Resource object has no “RDF” attribute.

In OldMan, the relation between Resource and Model objects is many-to-many. It differs from traditional ORMs where the relation is one-to-many (the resource is usually an instance of the model and the latter is a Python class in these frameworks). However, we expect that most Resource objects will relate to one Model object, but this is not a requirement. It is common for a resource in RDF to be instance of multiple RDFS classes so OldMan had to be ok with this practise.

Some inherited Python methods may also be provided by the Model objects.

Features
  1. Edit its properties:

    >>> # We assume that a model has been created for the RDFS class schema:Person.
    >>> alice = Resource(resource_manager, types=["http://schema.org/Person"])
    >>> alice.name = "Alice"
    >>> print alice.name
    Alice
    >>> print alice.id
    'http://localhost/person/3#me'
    >>> alice.add_type("http://schema.org/Researcher")
    >>> print alice.types
    [u'http://schema.org/Person', u'http://schema.org/Researcher']
    
  2. Persist its new values in the triplestore:

    alice.save()
    
  3. Call inherited methods:

    alice.do_that()
    
  4. Serialize to JSON, JSON-LD or any other RDF format:

    >>> alice.to_jsonld()
    {
      "@context": "https://example.com/context.jsonld",
      "id": "http://localhost/person/3#me",
      "name": "Alice",
      "types": [
        "http://schema.org/Person",
        "http://schema.org/Researcher"
      ]
    }
    >>> alice.to_rdf(format="turtle")
    @prefix schema: <http://schema.org/> .
    @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
    
    <http://localhost/persons/3#me> a schema:Person, schema:Researcher ;
                foaf:name "Alice"^^xsd:string .
    

UserMediator

TODO: update

A UserMediator object is the central object of OldMan.

It creates Model objects (create_model()) and retrieves Resource objects (get(), filter() and sparql_filter()).

It accepts Python method declarations if they happen before the creation of Model objects (declare_method()).

It also provide helper functions to create new Resource objects (create() and new()) but it is usually simpler to use those of a Model object.

For creating the UserMediator object, the schema graph and the data store (DataStore) must be given.

Basically, the schema graph describes which properties should be expected for a given RDFS class, which are required and what are the constraints.

Model

In OldMan, models are not Python classes but Model objects. However, on the RDF side, they correspond to RDFS classes (their class_iri attributes).

Their main role is to provide attributes and methods to Resource objects, as explained above.

Model objects are created by the UserMediator object.

A model provide some helpers above the UserMediator object ( get(), filter(), new() and create()) that include the class_iri to the types parameter of these methods.

DataStore

A DataStore implements the CRUD operations on Web Resources exposed by the UserMediator and Model objects.

The vision of OldMan is to include a large choice of data stores. But currently, only SPARQL endpoints are supported.

Non-CRUD operations may also be introduced in the future (in discussion).

Any data store accepts a dogpile.cache.region.CacheRegion object to enable its ResourceCache object. By default the latter is disabled so it does not cache the Resource objects loaded from and stored in the data store.

SPARQLDataStore

A SPARQLDataStore object relies on one or two RDF graphs (rdflib.graph.Graph): the data and default graphs.

The data graph is where regular resources are saved and loaded.

The default graph (rdflib.graph.ConjunctiveGraph or rdflib.graph.Dataset) may be given as an optional second graph. Its only constraint is to include the content of the data graph in its default graph.

Examples

DBpedia querying (read-only)

Source code

This example presents a use case where an OLDM produces a significant overhead that is important to understand.

We want to query the DBpedia which contains RDF statements extracted from the info-boxes of Wikipedia. DBpedia provides a public SPARQL endpoint powered by Virtuoso.

Inspired by a gist of O. Berger, we will display:

  1. The 10 first French films found on DBpedia and the names of their actors;
  2. The films in which Michel Piccoli had a role.
Direct SPARQL queries (without OldMan)

First, let’s create a Graph to access the DBpedia SPARQL endpoint

from rdflib import Graph
from rdflib.plugins.stores.sparqlstore import SPARQLStore
data_graph = Graph(SPARQLStore("http://dbpedia.org/sparql", context_aware=False))
Query 1
import time
q3_start_time = time.time()

results = data_graph.query("""
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX dcterms: <http://purl.org/dc/terms/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX dbpo: <http://dbpedia.org/ontology/>

SELECT ?film ?title_fr ?title_en ?actor ?actor_name_fr ?actor_name_en
WHERE {
    {
     SELECT ?film
     WHERE {
        ?film a dbpo:Film ;
              dcterms:subject <http://dbpedia.org/resource/Category:French_films> .
      }
      LIMIT 10
    }
    OPTIONAL {
       ?film rdfs:label ?title_en .
       FILTER langMatches( lang(?title_en), "EN" ) .
    }
    OPTIONAL {
       ?film rdfs:label ?title_fr .
       FILTER langMatches( lang(?title_fr), "FR" ) .
    }
    OPTIONAL {
      ?film dbpo:with ?actor .
      OPTIONAL {
        ?actor foaf:name ?actor_name_en .
        FILTER langMatches( lang(?actor_name_en), "EN" ) .
      }
      OPTIONAL {
        ?actor foaf:name ?actor_name_fr .
        FILTER langMatches( lang(?actor_name_fr), "FR" ) .
      }
    }
}
""")

Now we extract the film titles and the names of the actors:

film_titles = {}
film_actors = {}
for film_iri, title_fr, title_en, actor_iri, actor_name_fr, actor_name_en in results:
    if film_iri not in film_titles:
        for t in [title_fr, title_en, film_iri]:
            if t is not None:
                film_titles[film_iri] = unicode(t)
                break
    for name in [actor_name_fr, actor_name_en, actor_iri]:
        if name is not None:
            if film_iri not in film_actors:
                film_actors[film_iri] = [name]
            elif name not in film_actors[film_iri]:
                film_actors[film_iri].append(unicode(name))
            break

and display them:

>>> for film_iri in film_titles:
...     title = film_titles[film_iri]
...     if film_iri not in film_actors:
...         print "%s %s (no actor declared)" % (title, film_iri)
...     else:
...         actor_names = ", ".join(film_actors[film_iri])
...         print "%s with %s" % (title, actor_names)
And Now... Ladies and Gentlemen with Patricia Kaas, Jeremy Irons, Thierry Lhermitte
Un long dimanche de fiançailles (film) with Dominique Pinon, Marion Cotillard, Ticky Holgado, Audrey Tautou, Jodie Foster, Chantal Neuwirth, Gaspard Ulliel, André Dussollier, Andre Dussolier
Charlotte et Véronique http://dbpedia.org/resource/All_the_Boys_Are_Called_Patrick (no actor declared)
Toutes ces belles promesses with Jeanne Balibar, Bulle Ogier, Valerie Crunchant, http://dbpedia.org/resource/Renaud_B%C3%A9card
Édith et Marcel with Évelyne Bouix, Evelyne Bouix, http://dbpedia.org/resource/Marcel_Cerdan_Jr
Une robe d'été http://dbpedia.org/resource/A_Summer_Dress (no actor declared)
9 semaines 1/2 with Kim Basinger, Mickey Rourke
Tout sur ma mère with Penélope Cruz, Penélope Cruz Sánchez, Cecilia Roth, Antonia San Juan, Candela Pena, Marisa Paredes
Artemisia (film) with Miki Manojlović, Predrag Miki Manojlovic, Michel Serrault, Valentina Cervi
Two Days in Paris with Julie Delpy, Adam Goldberg, Daniel Bruhl
>>> print "Done in %.3f seconds" % (time.time() - q3_start_time)
Done in 0.252 seconds

Some names are missing in the DBpedia and are replaced by the URI. The film URI is also displayed when the actors are unknown so that you can check with your browser that this information is missing.

Query 2
q4_start_time = time.time()
results = data_graph.query("""
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX dcterms: <http://purl.org/dc/terms/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX dbpo: <http://dbpedia.org/ontology/>

SELECT ?film ?title_fr ?title_en
WHERE {
    ?film a dbpo:Film ;
          dbpo:with <http://dbpedia.org/resource/Michel_Piccoli> .
    OPTIONAL {
       ?film rdfs:label ?title_en .
       FILTER langMatches( lang(?title_en), "EN" ) .
    }
    OPTIONAL {
       ?film rdfs:label ?title_fr .
       FILTER langMatches( lang(?title_fr), "FR" ) .
    }
}
""")
>>> for film_iri, title_fr, title_en in results:
...     if film_iri not in film_titles:
...         for t in [title_fr, title_en, film_iri]:
...             if t is not None:
...                 print t
...                 break
    La Diagonale du fou
    Le Journal d'une femme de chambre (film, 1964)
    La Grande Bouffe
    Max et les Ferrailleurs
    La Voie lactée (film, 1969)
    Les Demoiselles de Rochefort
    Le Saut dans le vide
    Belle toujours
    Boxes
    Des enfants gâtés
    Une étrange affaire
    Belle de Jour (film)
    Benjamin ou les Mémoires d'un puceau
    Le Mépris (film)
    Dillinger est mort
    Généalogies d'un crime
    Je rentre à la maison
    La Belle Noiseuse
    La Chamade (film)
    Le Prix du danger (film)
    Mauvais Sang (film)
    Milou en mai
    Passion (film, 1982)
    La Prophétie des grenouilles
    La Poussière du temps
    Le Fantôme de la liberté
    Compartiment tueurs
    Les Choses de la vie
    Themroc
    Une chambre en ville
    Vincent, François, Paul... et les autres
    Habemus papam (film)
    Les Noces rouges
    Les Cent et Une Nuits de Simon Cinéma
    La Décade prodigieuse
    Der Preis fürs Überleben
    Party (1996 film)
    The Distant Land
    Passion in the Desert
>>> print "Done in %.3f seconds" % (time.time() - q4_start_time)
Done in 0.180 seconds
With OldMan

Let’s first create two Model objects: film_model and person_model from these context and schema:

from oldman import create_mediator, SparqlStore
from dogpile.cache import make_region

schema_url = "https://raw.githubusercontent.com/oldm/OldMan/master/examples/dbpedia_film_schema.ttl"
schema_graph = Graph().parse(schema_url, format="turtle")

context_url = "https://raw.githubusercontent.com/oldm/OldMan/master/examples/dbpedia_film_context.jsonld"

# Same data graph that before
data_graph = Graph(SPARQLStore("http://dbpedia.org/sparql", context_aware=False))

cache_region = make_region().configure('dogpile.cache.memory_pickle')

# store: SPARQL-aware triple store, with two models
store = SparqlStore(data_graph, schema_graph=schema_graph, cache_region=cache_region)
store.create_model("http://dbpedia.org/ontology/Film", context_url)
# JSON-LD terms can be used instead of IRIs
store.create_model("Person", context_url)

# Mediator for users
mediator = create_mediator(store)
# Re-uses the models of the data store
mediator.use_all_store_models()
film_model = mediator.get_client_model("http://dbpedia.org/ontology/Film")
actor_model = mediator.get_client_model("Person")

Please note that we set up a resource cache and reused the data_graph.

We also declare two extraction functions:

def extract_title(film):
    if len(film.titles) > 0:
        key = "fr" if "fr" in film.titles else film.titles.keys()[0]
        return "%s (%s version)" % (film.titles[key], key)
    return film.id

def extract_name(person):
    if person.names is not None and len(person.names) > 0:
        for key in ["fr", "en"]:
            if key in person.names:
                return person.names[key]
        return person.names.values()[0]
    return person.id
Query 1 (lazy)

By default, OldMan behaves lazily:

>>> q1_start_time = time.time()
>>> for film in film_model.filter(subjects=["http://dbpedia.org/resource/Category:French_films"],
...                               limit=10):
...     title = extract_title(film)
...     if film.actors is None:
...         print "   %s %s (no actor declared)" % (title, film.id)
...     else:
...         actor_names = ", ".join([extract_name(a) for a in film.actors])
...         print "%s with %s" % (title, actor_names)
Édith et Marcel (fr version) with http://dbpedia.org/resource/Marcel_Cerdan_Jr, Evelyne Bouix
Two Days in Paris (fr version) with Julie Delpy, Adam Goldberg, Daniel Bruhl
9 semaines 1/2 (fr version) with Kim Basinger, Mickey Rourke
Une robe d'été (fr version) http://dbpedia.org/resource/A_Summer_Dress (no actor declared)
Un long dimanche de fiançailles (film) (fr version) with Jodie Foster, Chantal Neuwirth, Marion Cotillard, Ticky Holgado, André Dussollier, Dominique Pinon, Audrey Tautou, Gaspard Ulliel
Tout sur ma mère (fr version) with Cecilia Roth, Antonia San Juan, Marisa Paredes, Candela Pena, Penélope Cruz Sánchez
Charlotte et Véronique (fr version) http://dbpedia.org/resource/All_the_Boys_Are_Called_Patrick (no actor declared)
Toutes ces belles promesses (fr version) with Valerie Crunchant, Jeanne Balibar, Bulle Ogier, http://dbpedia.org/resource/Renaud_B%C3%A9card
And Now... Ladies and Gentlemen (fr version) with Thierry Lhermitte, Jeremy Irons, Patricia Kaas
Artemisia (film) (fr version) with Michel Serrault, Miki Manojlović, Valentina Cervi
>>> print "Done in %.3f seconds" % (time.time() - q1_start_time)
Done in 17.123 seconds

17s? Why is it so slow? There are two reasons:

  1. OldMan loads a Resource object for each film or actor that is displayed. Loading a Resource object implies to retrieve all the triples in which the resource is the subject. In DBpedia, entries like films and actors have often many triples. Some of them have long textual literal values (localized paragraphs from Wikipedia). For instance, see http://dbpedia.org/resource/Penelope_Cruz. This approach retrieves much more information than we need for our specific query.
  2. By default OldMan is lazy so it retrieves each a Resource object at the last time, one by one in sequence. The execution of this long sequence of queries takes a long time, partly because of the network latency that is multiplied by the number of queries.
Query 1 (eager)

While this first phenomenon is something you should expect when using an OLDM, the second reason can avoided by adopting an eager strategy:

>>> q1_start_time = time.time()
>>> for film in film_model.filter(subjects=["http://dbpedia.org/resource/Category:French_films"],
...                               limit=10, eager=True,
...                               pre_cache_properties=["http://dbpedia.org/ontology/starring"]):
... # Code and results not shown
>>> print "Done in %.3f seconds" % (time.time() - q1_start_time)
Done in 2.518 seconds

The eager strategy makes one heavy SPARQL request that returns all the triples about the films but also about the actors (thanks to the pre-cached property dbpo:starring). The network latency is then almost minimal.

If we re-query it again lazily, thanks to the cache it makes just one lightweight SPARQL query:

>>> q1_start_time = time.time()
>>> for film in film_model.filter(subjects=["http://dbpedia.org/resource/Category:French_films"],
...                               limit=10):
... # Code and results not shown
>>> print "Done in %.3f seconds" % (time.time() - q1_start_time)
Done in 0.182 seconds

But if we re-query it eagerly, the heavy query will be sent again. The cache is then of little interest:

>>> # Code and results not shown
>>> print "Done in %.3f seconds" % (time.time() - q1_start_time)
Done in 2.169 seconds
Query 2 (lazy)
>>> q2_start_time = time.time()
>>> for film in film_model.filter(actors=["http://dbpedia.org/resource/Michel_Piccoli"]):
...     print extract_title(film)
... # Results not shown
>>> print "Done in %.3f seconds" % (time.time() - q2_start_time)
Done in 16.419 seconds
Query 2 (eager)
>>> q2_start_time = time.time()
>>> for film in film_model.filter(actors=["http://dbpedia.org/resource/Michel_Piccoli"],
                                  eager=True):
... # Code and results not shown
>>> print "Done in %.3f seconds" % (time.time() - q2_start_time)
Done in 1.503 seconds

API reference

Main classes manipulated by end-users: Mediator, ClientModel and ClientResource.

PermanentIDGenerator classes can be found in the oldman.storage.id_generation module.

Store classes can be found in the package oldman.storage.store.

oldman package

Subpackages

oldman.client package
Subpackages
oldman.client.hydra package
Submodules
oldman.client.hydra.operation module
oldman.client.hydra.operation.append_to_hydra_collection(collection_resource, new_resources=None, graph=None, **kwargs)[source]

TODO: improve the mechanism of operation

oldman.client.hydra.operation.append_to_hydra_paged_collection(collection, graph=None, new_resources=None, **kwargs)[source]
Module contents
oldman.client.mediation package
Submodules
oldman.client.mediation.default module
class oldman.client.mediation.default.DefaultMediator(data_stores, oper_extractor, schema_graph=None, attr_extractor=None)[source]

Bases: oldman.client.mediation.mediator.Mediator

create_session()[source]

TODO: explain it

declare_method(method, name, class_iri)[source]

TODO: point this comment to the definition.

get_client_model(class_name_or_iri)[source]
import_store_model(class_iri, data_store=None)[source]
import_store_models(store=None)[source]

TODO: check possible conflicts with local models.

oldman.client.mediation.mediator module
class oldman.client.mediation.mediator.Mediator[source]

Bases: object

TODO: describe

create_session()[source]

TODO: explain it

declare_method(method, name, class_iri)[source]

Attaches a method to the Resource objects that are instances of a given RDFS class.

Like in Object-Oriented Programming, this method can be overwritten by attaching a homonymous method to a class that has a higher inheritance priority (such as a sub-class).

To benefit from this method (or an overwritten one), Resource objects must be associated to a Model that corresponds to the RDFS class or to one of its subclasses.

Parameters:
  • method – Python function that takes as first argument a Resource object.
  • name – Name assigned to this method.
  • class_iri – Targeted RDFS class. If not overwritten, all the instances (Resource objects) should inherit this method.
get_client_model(class_name_or_iri)[source]
import_store_model(class_iri, store=None)[source]
import_store_models(store=None)[source]
oldman.client.mediation.store_proxy module
class oldman.client.mediation.store_proxy.DefaultStoreProxy(store_selector, conversion_manager)[source]

Bases: oldman.client.mediation.store_proxy.StoreProxy

filter(resource_finder, resource_factory, types=None, hashless_iri=None, limit=None, eager=True, pre_cache_properties=None, **kwargs)[source]

TODO: explain

:return list of ClientResource ?

first(client_tracker, resource_factory, types=None, hashless_iri=None, pre_cache_properties=None, eager_with_reversed_attributes=True, **kwargs)[source]
flush(resource_factory, client_resources_to_update, client_resources_to_delete, is_end_user)[source]

TODO: explain

:return list of the new ClientResource ?

get(client_tracker, resource_factory, iri, types=None, eager_with_reversed_attributes=True)[source]

TODO: explain

TODO: also consider the client resource tracker.

:return a ClientResource

sparql_filter(client_tracker, resource_factory, query)[source]

TODO: explain

:return list of ClientResource ?

class oldman.client.mediation.store_proxy.StoreProxy[source]

Bases: object

TODO: find a better name

filter(resource_tracker, resource_factory, types=None, hashless_iri=None, limit=None, eager=False, pre_cache_properties=None, **kwargs)[source]

TODO: explain

:return list of ClientResource ?

first(resource_finder, resource_factory, types=None, hashless_iri=None, pre_cache_properties=None, eager_with_reversed_attributes=True, **kwargs)[source]
flush(resource_factory, client_resources_to_update, client_resources_to_delete, is_end_user)[source]

TODO: explain

:return list of the updated ClientResource ?

get(client_tracker, resource_factory, iri, types=None, eager_with_reversed_attributes=True)[source]

TODO: explain

:return a ClientResource

sparql_filter(resource_finder, resource_factory, query)[source]

TODO: explain

:return list of ClientResource ?

oldman.client.mediation.store_selector module
class oldman.client.mediation.store_selector.StoreSelector(stores)[source]

TODO: continue

select_sparql_stores(query)[source]
select_store(client_resource, **kwargs)[source]

TODO: what is the correct behavior when multiple stores are returned?

select_stores(id=None, **kwargs)[source]
stores
Module contents
oldman.client.model package
Submodules
oldman.client.model.manager module
class oldman.client.model.manager.ClientModelManager(oper_extractor, declare_default_operation_functions=True, **kwargs)[source]

Bases: oldman.core.model.manager.ModelManager

Client ModelManager.

In charge of the conversion between and store and client models.

create_model(class_name_or_iri, context_iri_or_payload, untyped=False, is_default=False, context_file_path=None, accept_new_blank_nodes=False)[source]

TODO: describe

import_model(store_model, is_default=False, store_schema_graph=None)[source]

Imports a store model. Creates the corresponding client model.

oldman.client.model.model module
class oldman.client.model.model.ClientModel(name, class_iri, ancestry_iris, context, om_attributes, operations=None, local_context=None, accept_new_blank_nodes=False)[source]

Bases: oldman.core.model.model.Model

TODO: describe.

TODO: further study this specific case.

Contains methods for end-users (–> layer above the user mediator).

all(session, limit=None, eager=False)[source]

Finds every Resource object that is instance of its RDFS class.

Parameters:
  • limit – Upper bound on the number of solutions returned (SPARQL LIMIT). Positive integer. Defaults to None.
  • eager – If True loads all the Resource objects within one single SPARQL query. Defaults to False (lazy).
Returns:

A generator of Resource objects.

classmethod copy_store_model(store_model, operations)[source]

TODO: describe

declare_method(method, name, ancestor_class_iri)[source]

TODO: describe. Not for end-users!

filter(session, hashless_iri=None, limit=None, eager=True, pre_cache_properties=None, **kwargs)[source]

Finds the Resource objects matching the given criteria.

The class_iri attribute is added to the types.

See oldman.resource.finder.ResourceFinder.filter() for further details.

first(session, hashless_iri=None, eager_with_reversed_attributes=True, pre_cache_properties=None, **kwargs)[source]

Finds the Resource objects matching the given criteria.

The class_iri attribute is added to the types.

See oldman.resource.finder.ResourceFinder.filter() for further details.

get(session, iri, eager_with_reversed_attributes=None)[source]

Gets the first Resource object matching the given criteria.

The class_iri attribute is added to the types. Also looks if reversed attributes should be considered eagerly.

See oldman.store.datastore.DataStore.get() for further details.

get_operation(http_method)[source]

TODO: describe

get_operation_by_name(name)[source]

TODO: describe

methods

dict of Python functions that takes as first argument a Resource object. Keys are the method names.

new(session, iri=None, hashless_iri=None, collection_iri=None, **kwargs)[source]

Creates a new Resource object without saving it.

The class_iri attribute is added to the types.

See new() for more details.

oldman.client.model.operation module

TODO: explain

class oldman.client.model.operation.Operation(http_method, excepted_type, returned_type, function, name)[source]

Bases: object

TODO: describe

expected_type
name
returned_type
oldman.client.model.operation.not_implemented(resource, **kwargs)[source]
Module contents
oldman.client.parsing package
Submodules
oldman.client.parsing.operation module
class oldman.client.parsing.operation.HydraOperationExtractor[source]

Bases: oldman.client.parsing.operation.OperationExtractor

TODO: describe

extract(ancestry, schema_graph, operation_functions)[source]

TODO: comment

class oldman.client.parsing.operation.OperationExtractor[source]

Bases: object

TODO: describe

extract(ancestry, schema_graph, operation_functions)[source]

TODO: describe

oldman.client.parsing.operation.get_operation_function(operation_functions, class_iri, ancestry, method)[source]
Module contents
oldman.client.rest package
Submodules
oldman.client.rest.controller module
class oldman.client.rest.controller.HTTPController(user_mediator, config={})[source]

Bases: object

HTTP.

TODO: check declared methods (only GET and HEAD are implicit).

DEFAULT_CONFIG = {'allow_put_new_resource': True, 'allow_put_new_type_existing_resource': False, 'allow_put_remove_type_existing_resource': False}
delete(hashless_iri, **kwargs)[source]

TODO: describe.

No declaration required.

get(hashless_iri, accept_header='*/*', **kwargs)[source]

TODO: describe.

No support declaration required.

head(hashless_iri, **kwargs)[source]

TODO: describe.

No support declaration required.

options(hashless_iri, **kwargs)[source]

TODO: implement it

patch(hashless_iri, content_type=None, payload=None, **kwargs)[source]

TODO: implement it

post(hashless_iri, content_type=None, payload=None, **kwargs)[source]

TODO: categorize the resource to decide what to do.

Support declaration and implementation are required.

put(hashless_iri, content_type=None, payload=None, **kwargs)[source]

TODO: describe.

No support declaration required.

oldman.client.rest.crud module
class oldman.client.rest.crud.HashLessCRUDer(user_mediator)[source]

Bases: object

A HashlessCRUDer object helps you to manipulate your Resource objects in a RESTful-like manner.

Please note that REST/HTTP only manipulates hash-less IRIs. A hash IRI is the combination of a hash-less IRI (fragment-less IRI) and a fragment. Multiple hashed IRIs may have the same hash-less IRI and only differ by their fragment values. This is a concern for each type of HTTP operation.

This class is generic and does not support the Collection pattern (there is no append method).

Parameters:managerResourceManager object.

Possible improvements:

  • Add a PATCH method.
delete(hashless_iri)[source]

Deletes every Resource object having this hash-less IRI.

Parameters:hashless_iri – Hash-less IRI.
get(hashless_iri, content_type='text/turtle')[source]

Gets the main Resource object having its hash-less IRI.

When multiple Resource objects have this hash-less IRI, one of them has to be selected. If one has no fragment value, it is selected. Otherwise, this selection is currently arbitrary.

TODO: stop selecting the resources and returns the graph containing these resources.

Raises an ObjectNotFoundError exception if no resource is found.

Parameters:
  • hashless_iri – hash-less of the resource.
  • content_type – Content type of its representation.
Returns:

The representation of selected Resource object and its content type

update(hashless_iri, document_content, content_type, allow_new_type=False, allow_type_removal=False)[source]

Updates every Resource object having this hash-less IRI.

Raises an OMDifferentBaseIRIError exception if tries to create of modify non-blank Resource objects that have a different hash-less IRI. This restriction is motivated by security concerns.

Accepts JSON, JSON-LD and RDF formats supported by RDFlib.

Parameters:
  • hashless_iri – Document IRI.
  • document_content – Payload.
  • content_type – Content type of the payload.
  • allow_new_type – If True, new types can be added. Defaults to False. See oldman.resource.Resource.full_update() for explanations about the security concerns.
  • allow_type_removal – If True, new types can be removed. Same security concerns than above. Defaults to False.
Module contents
Submodules
oldman.client.resource module
class oldman.client.resource.ClientResource(model_manager, session, iri=None, hashless_iri=None, collection_iri=None, iri_fragment=None, is_new=True, **kwargs)[source]

Bases: oldman.core.resource.resource.Resource

ClientResource: resource manipulated by the end-user.

Has access to the session.

TODO: complete the description.

Parameters:
  • iri – IRI of the resource. If not given, this IRI is generated by the main model. Defaults to None.
  • hashless_iri – Hash-less IRI that is given to the main model for generating a new IRI if no id is given. The IRI generator may ignore it. Defaults to None. Must be None if collection_iri is given.
  • collection_iri – IRI of the controller to which this resource belongs. This information is used to generate a new IRI if no id is given. The IRI generator may ignore it. Defaults to None. Must be None if hashless_iri is given.
  • iri_fragment – TODO: describe.

Is not serializable.

classmethod load_from_graph(mediator, model_manager, id, subgraph, is_new=True, collection_iri=None)[source]

Loads a new ClientResource object from a sub-graph.

TODO: update the comments.

Parameters:
  • mediatorMediator object.
  • id – IRI of the resource.
  • subgraphrdflib.Graph object containing triples about the resource.
  • is_new – When is True and id given, checks that the IRI is not already existing in the union_graph. Defaults to True.
Returns:

The Resource object created.

receive_deletion_notification_from_store()[source]

TODO: explain

receive_local_deletion_notification()[source]

TODO: explain and find a better name.

“Pre”-deletion.

session
oldman.client.resource_factory module
class oldman.client.resource_factory.ClientResourceFactory[source]

Bases: object

new_resource(iri=None, hashless_iri=None, collection_iri=None, types=None, iri_fragment=None, is_new=True, **kwargs)[source]

TODO: describe

class oldman.client.resource_factory.DefaultClientResourceFactory(model_manager, session)[source]

Bases: oldman.client.resource_factory.ClientResourceFactory

new_resource(iri=None, hashless_iri=None, collection_iri=None, types=None, iri_fragment=None, is_new=True, **kwargs)[source]
oldman.client.session module
class oldman.client.session.ClientSession[source]

Bases: oldman.core.session.session.Session

filter(types=None, hashless_iri=None, limit=None, eager=True, pre_cache_properties=None, **kwargs)[source]

See oldman.store.store.Store.filter().

first(types=None, hashless_iri=None, eager_with_reversed_attributes=True, pre_cache_properties=None, **kwargs)[source]
new(iri=None, types=None, hashless_iri=None, collection_iri=None, **kwargs)[source]

Creates a new Resource object without saving it in the data_store.

The kwargs dict can contains regular attribute key-values that will be assigned to OMAttribute objects.

TODO: update this doc

Parameters:
  • iri – IRI of the new resource. Defaults to None. If not given, the IRI is generated by the IRI generator of the main model.
  • types – IRIs of RDFS classes the resource is instance of. Defaults to None. Note that these IRIs are used to find the models of the resource (see find_models_and_types() for more details).
  • hashless_iri – hash-less IRI that MAY be considered when generating an IRI for the new resource. Defaults to None. Ignored if id is given. Must be None if collection_iri is given.
  • collection_iri – IRI of the controller to which this resource belongs. This information is used to generate a new IRI if no id is given. The IRI generator may ignore it. Defaults to None. Must be None if hashless_iri is given.
Returns:

A new Resource object.

sparql_filter(query)[source]

See oldman.store.store.Store.sparql_filter().

class oldman.client.session.DefaultClientSession(model_manager, store_proxy)[source]

Bases: oldman.client.session.ClientSession

TODO: find a better name

close()[source]

TODO: implement it

delete(client_resource)[source]

TODO: describe.

Wait for the next flush() to remove the resource from the store.

filter(types=None, hashless_iri=None, limit=None, eager=False, pre_cache_properties=None, **kwargs)[source]
first(types=None, hashless_iri=None, eager_with_reversed_attributes=True, pre_cache_properties=None, **kwargs)[source]
flush(is_end_user=True)[source]

TODO: describe.

TODO: re-implement it, very naive

get(iri, types=None, eager_with_reversed_attributes=True)[source]

See oldman.store.datastore.DataStore.get().

get_updated_iri(tmp_iri)[source]

TODO: remove it

new(iri=None, types=None, hashless_iri=None, collection_iri=None, **kwargs)[source]

TODO: explain

receive_reference(reference, object_resource=None, object_iri=None)[source]

Not for end-users!

receive_reference_removal_notification(reference)[source]

Not for end-users!

sparql_filter(query)[source]

See oldman.store.store.Store.sparql_filter().

Module contents
oldman.core package
Subpackages
oldman.core.model package
Submodules
oldman.core.model.ancestry module
class oldman.core.model.ancestry.ClassAncestry(child_class_iri, schema_graph)[source]

Bases: object

Ancestry of a given RDFS class.

Parameters:
  • child_class_iri – IRI of the child RDFS class.
  • schema_graphrdflib.Graph object contains all the schema triples.
bottom_up

Ancestry list starting from the child.

child

Child of the ancestry.

parents(class_iri)[source]

Finds the parents of a given class in the ancestry.

Parameters:class_iri – IRI of the RDFS class.
Returns:List of class IRIs
top_down

Reverse of the bottom_up attribute.

oldman.core.model.attribute module
class oldman.core.model.attribute.Entry(saved_value=None)[source]

Bases: object

Mutable.

TODO: describe

clone()[source]
current_value
diff()[source]

TODO: explain

has_changed()[source]

True if the value differs from the stored one

receive_storage_ack()[source]

TODO: explain

class oldman.core.model.attribute.OMAttribute(metadata, value_format)[source]

Bases: object

An OMAttribute object corresponds to a JSON-LD term that refers to a RDF property.

TODO: update the documentation. No direct access to the resource_manager anymore (indirect through the resource).

Technically, the name of the OMAttribute object is a JSON-LD term, namely “a short-hand string that expands to an IRI or a blank node identifier” (cf. the JSON-LD standard) which corresponds here to a RDF property (see OMProperty).

In JSON-LD, the same RDF property may correspond to multiple JSON-LD terms that have different metadata. For instance, a foaf:Person resource may have two attributes for its bio in English and in French. These attributes have two different languages but use the same property bio:olb. Look at the quickstart example to see it in practice.

An OMAttribute object manages the values of every Resource object that depends on a given Model object.

Each value may be :

  • None;
  • The Python equivalent for a RDF literal (double, string, date, etc.);
  • An IRI;
  • A collection (set, list and dict) of these types.
Parameters:
  • metadataOMAttributeMetadata object.
  • value_formatValueFormat object that validates the format of values and converts RDF values into regular Python objects.
check_validity(resource, is_end_user=True)[source]

Raises an OMEditError exception if the attribute value assigned to a resource is invalid.

Parameters:
  • resourceResource object.
  • is_end_userFalse when an authorized user (not a regular end-user) wants to force some rights. Defaults to True.
check_value(value)[source]

Checks a new when assigned.

Raises an oldman.exception.OMAttributeTypeCheckError exception if the value is invalid.

Parameters:value – collection or atomic value.
container

JSON-LD container (“@set”, “@list”, “@language” or “@index”). May be None.

diff(resource)[source]

Gets out the former value that has been replaced.

TODO: update this comment

Parameters:resourceResource object.
Returns:The former and new attribute values.
get(resource)[source]

Gets the attribute value of a resource.

Parameters:resourceResource object.
Returns:Atomic value or a generator.
get_entry(resource)[source]

TODO: describe. Clearly not for end-users!!!

get_lightly(resource)[source]

Gets the attribute value of a resource in a lightweight manner.

By default, behaves exactly like get(). See the latter function for further details.

has_changed(resource)[source]
Parameters:resourceResource object.
has_entry(resource)[source]

TODO: describe. Clearly not for end-users!!!

has_value(resource)[source]

Tests if the resource attribute has a non-None value.

Parameters:resourceResource object.
Returns:False if the value is None.
is_read_only

True if the property cannot be modified by regular end-users.

is_required

True if its property is required.

is_valid(resource, is_end_user=True)[source]

Tests if the attribute value assigned to a resource is valid.

See check_validity() for further details.

Returns:False if the value assigned to the resource is invalid and True otherwise.
is_write_only

True if the property cannot be accessed by regular end-users.

jsonld_type

JSON-LD type (datatype IRI or JSON-LD keyword). May be None.

language

Its language if localized.

name

Its name as an attribute.

om_property

OMProperty to which it belongs.

other_attributes

Other OMAttribute objects of the same property.

receive_storage_ack(resource)[source]

Clears the former value that has been replaced.

TODO: update this description.

Parameters:resourceResource object.
reversed

True if the object and subject in RDF triples should be reversed.

set(resource, value)[source]

Sets the attribute value of a resource.

Parameters:
  • resourceResource object.
  • value – Its value for this attribute.
set_entry(resource, entry)[source]

TODO: describe. Clearly not for end-users!!!

to_nt(resource)[source]

Converts its current attribute value to N-Triples (NT) triples.

Relies on value_to_nt().

Parameters:resourceResource object.
Returns:N-Triples serialization of its attribute value.
update_from_graph(resource, sub_graph, initial=False)[source]

Updates a resource attribute value by extracting the relevant information from a RDF graph.

Parameters:
  • resourceResource object.
  • sub_graphrdflib.Graph object containing the value to extract.
  • initialTrue when the value is directly from the datastore. Defaults to False.
value_format

ValueFormat object that validates the format of values and converts RDF values into regular Python objects.

value_to_nt(value)[source]

Converts value(s) to N-Triples (NT) triples.

Parameters:value – Value of property.
Returns:N-Triples serialization of this value.
class oldman.core.model.attribute.OMAttributeMetadata(name, property, language, jsonld_type, container, reversed)

Bases: tuple

container

Alias for field number 4

jsonld_type

Alias for field number 3

language

Alias for field number 2

name

Alias for field number 0

property

Alias for field number 1

reversed

Alias for field number 5

class oldman.core.model.attribute.ObjectOMAttribute(metadata, value_format)[source]

Bases: oldman.core.model.attribute.OMAttribute

An ObjectOMAttribute object is an OMAttribute object that depends on an owl:ObjectProperty.

get(resource)[source]

See get().

Returns:Resource object or a generator of Resource objects.
get_lightly(resource)[source]

Gets the attribute value of a resource in a lightweight manner.

By contrast with get() only IRIs are returned, not Resource objects.

Returns:An IRI, a list or a set of IRIs or None.
set(resource, original_value)[source]

See set().

Accepts Resource object(s) or IRI(s).

oldman.core.model.attribute.get_iris(references)[source]

TODO: describe it

oldman.core.model.manager module
class oldman.core.model.manager.ModelManager(schema_graph=None, attr_extractor=None)[source]

Bases: object

TODO: update this documentation

The model_manager creates and registers Model objects.

Internally, it owns a ModelRegistry object.

Parameters:
  • schema_graphrdflib.Graph object containing all the schema triples.
  • data_storeDataStore object.
  • attr_extractorOMAttributeExtractor object that will extract OMAttribute for generating new Model objects. Defaults to a new instance of OMAttributeExtractor.
declare_operation_function(func, class_iri, http_method)[source]

TODO: comment

find_descendant_models(top_ancestor_name_or_iri)[source]

TODO: explain. Includes the top ancestor.

find_main_model(type_set)[source]

See oldman.model.registry.ModelRegistry.find_main_model().

find_models_and_types(type_set)[source]

See oldman.model.registry.ModelRegistry.find_models_and_types().

get_model(class_name_or_iri)[source]
has_default_model()[source]
include_reversed_attributes

Is True if at least one of its models use some reversed attributes.

models

TODO: describe.

non_default_models

TODO: describe.

schema_graph
oldman.core.model.model module
class oldman.core.model.model.Model(name, class_iri, ancestry_iris, context, om_attributes, accept_new_blank_nodes, local_context=None)[source]

Bases: object

A Model object represents a RDFS class on the Python side.

TODO: update this documentation

It gathers OMAttribute objects and Python methods which are made available to Resource objects that are instances of its RDFS class.

It also creates and retrieves Resource objects that are instances of its RDFS class. It manages an IriGenerator object.

Model creation

Model objects are normally created by a ResourceManager object. Please use the oldman.resource.manager.ResourceManager.create_model() method for creating new Model objects.

Parameters:
  • name – Model name. Usually corresponds to a JSON-LD term or to a class IRI.
  • class_iri – IRI of the RDFS class represented by this Model object.
  • ancestry_iris – ancestry of the attribute class_iri. Each instance of class_iri is also instance of these classes.
  • context – An IRI, a list or a dict that describes the JSON-LD context. See http://www.w3.org/TR/json-ld/#the-context for more details.
  • om_attributesdict of OMAttribute objects. Keys are their names.
  • accept_new_blank_nodes – TODO: describe.
  • methodsdict of Python functions that takes as first argument a Resource object. Keys are the method names. Defaults to {}. TODO: remove??
  • local_context – TODO: describe.
accept_new_blank_nodes

TODO: describe. Useful for knowing if a bnode ID of a resource is temporary or maybe not.

access_attribute(name)[source]

Gets an OMAttribute object.

Used by the Resource class but an end-user should not need to call it.

Parameters:name – Name of the attribute.
Returns:The corresponding OMAttribute object.
ancestry_iris

IRIs of the ancestry of the attribute class_iri.

class_iri

IRI of the class IRI the model refers to.

context

An IRI, a list or a dict that describes the JSON-LD context. See http://www.w3.org/TR/json-ld/#the-context for more details.

Official context that will be included in the representation.

has_reversed_attributes

Is True if one of its attributes is reversed.

is_subclass_of(model)[source]

Returns True if its RDFS class is a sub-class (rdfs:subClassOf) of the RDFS class of another model.

Parameters:modelModel object to compare with.
Returns:True if is a sub-class of the other model, False otherwise.
local_context

Context available locally (but not to external consumer). TODO: describe further

methods

Models does not support methods by default.

name

Name attribute.

om_attributes

dict of OMAttribute objects. Keys are their names.

oldman.core.model.model.clean_context(context)[source]

Cleans the context.

Context can be an IRI, a list or a dict.

oldman.core.model.property module
class oldman.core.model.property.OMProperty(property_iri, supporter_class_iri, is_required=False, read_only=False, write_only=False, reversed=False, cardinality=None, property_type=None, domains=None, ranges=None, link_class_iri=None)[source]

Bases: object

An OMProperty object represents the support of a RDF property by a RDFS class.

TODO: check this documentation after the removal of the resource_manager.

It gathers some OMAttribute objects (usually one).

An OMProperty object is in charge of generating its OMAttribute objects according to the metadata that has been extracted from the schema and JSON-LD context.

A property can be reversed: the Resource object to which the OMAttribute objects will be (indirectly) attached is then the object of this property, not its subject (?o ?p ?s).

Consequently, two OMProperty objects can refer to the same RDF property when one is reversed while the second is not.

Parameters:
  • property_iri – IRI of the RDF property.
  • supporter_class_iri – IRI of the RDFS class that supports the property.
  • is_required – If True instances of the supporter class must assign a value to this property for being valid. Defaults to False.
  • read_only – If True, the value of the property cannot be modified by a regular end-user. Defaults to False.
  • write_only – If True, the value of the property cannot be read by a regular end-user. Defaults to False.
  • reversed – If True, the property is reversed. Defaults to False.
  • cardinality – Defaults to None. Not yet supported.
  • property_type – String. In OWL, a property is either a DatatypeProperty or an ObjectProperty. Defaults to None (unknown).
  • domains – Set of class IRIs that are declared as the RDFS domain of the property. Defaults to set().
  • ranges – Set of class IRIs that are declared as the RDFS range of the property. Defaults to set().
  • link_class_iri – TODO: describe.
add_attribute_metadata(name, jsonld_type=None, language=None, container=None, reversed=False)[source]

Adds metadata about a future OMAttribute object.

Parameters:
  • name – JSON-LD term representing the attribute.
  • jsonld_type – JSON-LD type (datatype IRI or JSON-LD keyword). Defaults to None.
  • language – Defaults to None.
  • container – JSON-LD container (“@set”, “@list”, “@language” or “@index”). Defaults to None.
  • reversedTrue if the object and subject in RDF triples should be reversed. Defaults to False.
add_domain(domain)[source]

Declares a RDFS class as part of the domain of the property.

Parameters:domain – IRI of RDFS class.
add_range(p_range)[source]

Declares a RDFS class as part of the range of the property.

Parameters:p_range – IRI of RDFS class.
declare_is_required()[source]

Makes the property be required. Is irreversible.

default_datatype

IRI that is the default datatype of the property.

May be None (if not defined or if the property is an owl:ObjectProperty)

domains

Set of class IRIs that are declared as the RDFS domain of the property.

generate_attributes(attr_format_selector)[source]

Generates its OMAttribute objects.

Can be called only once. When called a second time, raises an OMAlreadyGeneratedAttributeError exception.

Parameters:attr_format_selectorValueFormatSelector object.
iri

IRI of RDF property.

is_read_only

True if the property cannot be modified by regular end-users.

is_required

True if the property is required.

is_write_only

True if the property cannot be accessed by regular end-users.

TODO: describe

om_attributes

Set of OMAttribute objects that depends on this property.

ranges

Set of class IRIs that are declared as the RDFS range of the property.

reversed

True if the property is reversed (?o ?p ?s).

supporter_class_iri

IRI of the RDFS class that supports the property.

type

The property can be a owl:DatatypeProperty (“datatype”) or an owl:ObjectProperty (“object”). Sometimes its type is unknown (None).

oldman.core.model.registry module
class oldman.core.model.registry.ModelRegistry[source]

Bases: object

A ModelRegistry object registers the Model objects.

Its main function is to find and order models from a set of class IRIs (this ordering is crucial when creating new Resource objects). See find_models_and_types() for more details.

default_model
find_descendant_models(top_ancestor_name_or_iri)[source]

TODO: explain. Includes the top ancestor.

find_main_model(type_set)[source]

TODO: see if it can be made more efficient.

find_models_and_types(type_set)[source]

Finds the leaf models from a set of class IRIs and orders them. Also returns an ordered list of the RDFS class IRIs that come from type_set or were deduced from it.

Leaf model ordering is important because it determines:

  1. the IRI generator to use (the one of the first model);
  2. method inheritance priorities between leaf models.

Resulting orderings are cached.

Parameters:type_set – Set of RDFS class IRIs.
Returns:An ordered list of leaf Model objects and an ordered list of RDFS class IRIs.
get_model(class_name_or_iri)[source]

Gets a Model object.

Parameters:class_name_or_iri – Name or IRI of a RDFS class
Returns:A Model object or None if not found
has_specific_models()[source]
Returns:True if contains other models than the default one.
model_names

Names of the registered models.

models
non_default_models

Non-default models.

register(model, is_default=False)[source]

Registers a Model object.

Parameters:
  • model – the Model object to register.
  • is_default – If True, sets the model as the default model. Defaults to False.
unregister(model)[source]

Un-registers a Model object.

Parameters:model – the Model object to remove from the registry.
Module contents
oldman.core.parsing package
Subpackages
oldman.core.parsing.schema package
Submodules
oldman.core.parsing.schema.attribute module
class oldman.core.parsing.schema.attribute.OMAttributeExtractor(property_extractors=None, attr_md_extractors=None, use_hydra=True, use_jsonld_context=True)[source]

Bases: object

Extracts OMAttribute objects from the schema and the JSON-LD context.

Extensible in two ways:

  1. New OMPropertyExtractor objects (new RDF vocabularies);
  2. New OMAttributeMdExtractor objects (e.g. JSON-LD context);
  3. New ValueFormat objects. See its value_format_registry attribute.
Parameters:
  • property_extractors – Defaults to [].
  • attr_md_extractors – Defaults to [].
  • use_hydra – Defaults to True.
  • use_jsonld_context – Defaults to True.
add_attribute_md_extractor(attr_md_extractor)[source]

Adds a new OMAttributeMdExtractor object.

add_property_extractor(property_extractor)[source]

Adds a new OMPropertyExtractor object.

extract(class_iri, type_iris, context_js, schema_graph)[source]

Extracts metadata and generates OMProperty and OMAttribute objects.

Parameters:
  • class_iri – IRI of RDFS class of the future Model object.
  • type_iris – Ancestry of the RDFS class.
  • context_js – the JSON-LD context.
  • schema_graphrdflib.graph.Graph object.
Returns:

dict of OMAttribute objects.

value_format_registry

ValueFormatRegistry object.

class oldman.core.parsing.schema.attribute.ValueFormatRegistry(special_properties=None, include_default_datatypes=True, include_well_known_properties=True)[source]

Bases: object

Finds the ValueFormat object that corresponds to a OMAttributeMetadata object.

New ValueFormat objects can be added, for supporting:

  1. Specific properties (eg. foaf:mbox and EmailValueFormat);
  2. Other datatypes, as defined in the JSON-LD context or the RDFS domain or range (eg. xsd:string).
Parameters:
  • special_properties – Defaults to {}.
  • include_default_datatypes – Defaults to True.
  • include_well_known_properties – Defaults to True.
add_datatype(datatype_iri, value_format)[source]

Registers a ValueFormat object for a given datatype.

Parameters:
  • datatype_iri – IRI of the datatype.
  • value_formatValueFormat object.
add_special_property(property_iri, value_format)[source]

Registers a ValueFormat object for a given RDF property.

Parameters:
  • property_iri – IRI of the RDF property.
  • value_formatValueFormat object.
find_value_format(attr_md)[source]

Finds the ValueFormat object that corresponds to a OMAttributeMetadata object.

Parameters:attr_mdOMAttributeMetadata object.
Returns:ValueFormat object.
oldman.core.parsing.schema.context module
class oldman.core.parsing.schema.context.JsonLdContextAttributeMdExtractor[source]

Bases: oldman.core.parsing.schema.context.OMAttributeMdExtractor

OMAttributeMdExtractor objects that extract attribute names and datatypes from the JSON-LD context.

update(om_properties, context_js, schema_graph)[source]

See oldman.parsing.schema.context.OMAttributeMdExtractor.update().

class oldman.core.parsing.schema.context.OMAttributeMdExtractor[source]

Bases: object

An OMAttributeMdExtractor object extracts OMAttributeMetadata tuples and transmits them to OMProperty objects.

update(om_properties, context_js, schema_graph)[source]

Updates the OMProperty objects by transmitting them extracted OMAttributeMetadata tuples.

Parameters:
  • om_propertiesdict of OMProperty objects indexed by their IRIs.
  • context_js – JSON-LD context.
  • schema_graphrdflib.graph.Graph object.
oldman.core.parsing.schema.property module
class oldman.core.parsing.schema.property.HydraPropertyExtractor[source]

Bases: oldman.core.parsing.schema.property.OMPropertyExtractor

OMPropertyExtractor objects that support the Hydra vocabulary.

Currently, this class supports:
update(om_properties, class_iri, type_iris, schema_graph)[source]

See oldman.parsing.schema.property.OMPropertyExtractor.update().

class oldman.core.parsing.schema.property.OMPropertyExtractor[source]

Bases: object

An OMPropertyExtractor object generates and updates OMProperty objects from the schema RDF graph.

This class is generic and must derived for supporting various RDF vocabularies.

update(om_properties, class_iri, type_iris, schema_graph)[source]

Generates new OMProperty objects or updates them from the schema graph.

Parameters:
  • om_propertiesdict of OMProperty objects indexed by their IRIs and their reverse status.
  • class_iri – IRI of RDFS class of the future Model object.
  • type_iris – Ancestry of the RDFS class.
  • schema_graphrdflib.graph.Graph object.
Returns:

Updated dict OMProperty objects.

Module contents
Submodules
oldman.core.parsing.value module
class oldman.core.parsing.value.AttributeValueExtractor(om_attribute)[source]

Bases: object

An AttributeValueExtractor object extracts values from RDF graphs for a given OMAttribute object.

Parameters:om_attributeOMAttribute object.
extract_value(resource, subgraph)[source]

Extracts a resource attribute value from a RDF graph.

Parameters:
  • resourceResource object.
  • subgraphrdflib.graph.Graph object containing the value to extract.
Returns:

Collection or atomic value.

Module contents
oldman.core.resource package
Submodules
oldman.core.resource.reference module
class oldman.core.resource.reference.ResourceReference(subject_resource, attribute, object_resource_or_iri)[source]

Bases: object

TODO: explain

“Subject” and “object” adjectives can be ROUGHLY understood like “subject predicate object”.

By roughly, we mean that we ignore the effect of “inverse property” (an attribute roughly corresponds to a predicate even in practice it can refer to an inverse predicate; we don’t make the distinction here).

attribute
detach()[source]

TODO: explain

get(must_be_attached=True)[source]
is_bound_to_object_resource
object_iri
subject_resource
oldman.core.resource.resource module
class oldman.core.resource.resource.Resource(id, model_manager, session, types=None, is_new=True, former_types=None, **kwargs)[source]

Bases: object

A Resource object is a subject-centric representation of a Web resource. A set of Resource objects is equivalent to a RDF graph.

In RDF, a resource is identified by an IRI (globally) or a blank node (locally). Because blank node support is complex and limited (rdflib.plugins.stores.sparqlstore.SPARQLStore stores do not support them), every Resource object has an IRI.

This IRI is either given or generated by a IriGenerator object. Some generators generate recognizable skolem IRIs that are treated as blank nodes when the resource is serialized into JSON, JSON-LD or another RDF format (for external consumption).

A resource is usually instance of some RDFS classes. These classes are grouped in its attribute types. Model objects are found from these classes, by calling the method oldman.resource.manager.ResourceManager.find_models_and_types(). Models give access to Python methods and to OMAttribute objects. Their ordering determines inheritance priorities. The main model is the first one of this list.

Values of OMAttribute objects are accessible and modifiable like ordinary Python attribute values. However, these values are checked so some OMAccessError or OMEditError errors may be raised.

This abstract class accepts two concrete classes: StoreResource and ClientResource. The former is serializable and can be saved directly by the datastore while the latter has to be converted into a StoreResource so as to be saved.

Example:

>>> alice = StoreResource(model_manager, data_store, types=["http://schema.org/Person"], name=u"Alice")
>>> alice.id
u'http://localhost/persons/1'
>>> alice.name
u'Alice'
>>> alice.save()
>>> alice.name = "Alice A."
>>> print alice.to_jsonld()
{
   "@context": "http://localhost/person.jsonld",
   "id": "http://localhost/persons/1",
   "types": [
              "http://schema.org/Person"
            ],
   "name": "Alice A."
}
>>> alice.name = 5
oldman.exception.OMAttributeTypeCheckError: 5 is not a (<type 'str'>, <type 'unicode'>)

Resource creation

Resource objects are normally created by a Model or a ResourceManager object. Please use the methods oldman.model.model.Model.create(), oldman.model.Model.new(), oldman.resource.manager.ResourceManager.create() or oldman.resource.manager.ResourceManager.new() for creating new Resource objects.

Parameters:
  • id – TODO:describe.
  • model_managerModelManager object. Gives access to its models.
  • types – IRI list or set of the RDFS classes the resource is instance of. Defaults to set().
  • is_new – When is True and id given, checks that the IRI is not already existing in the data_store. Defaults to True.
  • former_types – IRI list or set of the RDFS classes the resource was instance of. Defaults to set().
  • kwargs – values indexed by their attribute names.

TODO: update this comment!!!!!

add_type(additional_type)[source]

Declares that the resource is instance of another RDFS class.

Note that it may introduce a new model to the list and change its ordering.

Parameters:additional_type – IRI or JSON-LD term identifying a RDFS class.
attributes
Returns:An ordered list of list of OMAttribute objects.
check_validity(is_end_user=True)[source]

Checks its validity.

Raises an oldman.exception.OMEditError exception if invalid.

context

An IRI, a list or a dict that describes the JSON-LD context.

Derived from oldman.model.Model.context attributes.

former_non_model_types

RDFS classes that were not associated to a Model.

former_types

Not for end-users

get_attribute(attribute_name)[source]

Not for the end-user!

get_lightly(attribute_name)[source]

If the attribute corresponds to an owl:ObjectProperty, returns a IRI or None. Otherwise (if is a datatype), returns the value.

get_operation(http_method)[source]

TODO: describe

Not for end-users!

Gets a related Resource through its session.

If cannot get the resource, return its IRI.

id

IRI that identifies the resource.

in_same_document(other_resource)[source]

Tests if two resources have the same hash-less IRI.

Returns:True if these resources are in the same document.
is_blank_node()[source]

Tests if id.iri is a skolem IRI and should thus be considered as a blank node.

See is_blank_node() for further details.

Returns:True if id.iri is a locally skolemized IRI.
is_instance_of(model)[source]

Tests if the resource is instance of the RDFS class of the model.

Parameters:modelModel object.
Returns:True if the resource is instance of the RDFS class.
is_new

True if the resource has never been saved.

is_valid()[source]

Tests if the resource is valid.

Returns:False if the resource is invalid, True otherwise.
local_context

Context that is locally accessible but that may not be advertised in the JSON-LD serialization.

model_manager

ModelManager object. Gives access to the Model objects.

models

TODO: describe

non_model_types

RDFS classes that are not associated to a Model.

notify_reference(reference, object_resource=None, object_iri=None)[source]

Not for end-users!

TODO: describe

notify_reference_removal(reference)[source]

Not for end-users!

TODO: describe

receive_storage_ack(id)[source]

Receives the permanent ID assigned by the store. Useful when the permanent ID is given by an external server.

Replaces the temporary ID of the resource.

to_dict(remove_none_values=True, include_different_contexts=False, ignored_iris=None)[source]

Serializes the resource into a JSON-like dict.

Parameters:
  • remove_none_values – If True, None values are not inserted into the dict. Defaults to True.
  • include_different_contexts – If True local contexts are given to sub-resources. Defaults to False.
  • ignored_iris – List of IRI of resources that should not be included in the dict. Defaults to set().
Returns:

A dict describing the resource.

to_json(remove_none_values=True, ignored_iris=None)[source]

Serializes the resource into pure JSON (not JSON-LD).

Parameters:
  • remove_none_values – If True, None values are not inserted into the dict. Defaults to True.
  • ignored_iris – List of IRI of resources that should not be included in the dict. Defaults to set().
Returns:

A JSON-encoded string.

to_jsonld(remove_none_values=True, include_different_contexts=False, ignored_iris=None)[source]

Serializes the resource into JSON-LD.

Parameters:
  • remove_none_values – If True, None values are not inserted into the dict. Defaults to True.
  • include_different_contexts – If True local contexts are given to sub-resources. Defaults to False.
  • ignored_iris – List of IRI of resources that should not be included in the dict. Defaults to set().
Returns:

A JSON-LD encoded string.

to_rdf(rdf_format='turtle')[source]

Serializes the resource into RDF.

Parameters:rdf_format – content-type or keyword supported by RDFlib. Defaults to “turtle”.
Returns:A string in the chosen RDF format.
types

IRI list of the RDFS classes the resource is instance of.

update(full_dict, allow_new_type=False, allow_type_removal=False)[source]

Updates the resource from a flat dict.

By flat, we mean that sub-resources are only represented by their IRIs: there is no nested sub-object structure.

This dict is supposed to be exhaustive, so absent value is removed. Some sub-resources may thus be deleted like if there were a cascade deletion.

Parameters:
  • full_dict – Flat dict containing the attribute values to update.
  • allow_new_type

    If True, new types can be added. Please keep in mind that type change can:

    • Modify the behavior of the resource by changing its model list.
    • Interfere with the SPARQL requests using instance tests.

    If enabled, this may represent a major security concern. Defaults to False.

  • allow_type_removal – If True, new types can be removed. Same security concerns than above. Defaults to False.
Returns:

The Resource object itself.

update_from_graph(subgraph, initial=False, allow_new_type=False, allow_type_removal=False)[source]

Similar to full_update() but with a RDF graph instead of a Python dict.

Parameters:
  • subgraphrdflib.Graph object containing the full description of the resource.
  • initialTrue when the subgraph comes from the data_graph and is thus used to load Resource object from the triple store. Defaults to False.
  • allow_new_type – If True, new types can be added. Defaults to False. See full_update() for explanations about the security concerns.
  • allow_type_removal – If True, new types can be removed. Same security concerns than above. Defaults to False.
Returns:

The Resource object itself.

Module contents
oldman.core.session package
Submodules
oldman.core.session.session module
class oldman.core.session.session.Session[source]

Bases: object

TODO: explain

close()[source]

TODO: describe

delete(resource)[source]

TODO: describe

flush(is_end_user=True)[source]

TODO: describe

get(iri, types=None, eager_with_reversed_attributes=True)[source]

See oldman.store.datastore.DataStore.get().

receive_reference(reference, object_resource=None, object_iri=None)[source]

Not for end-users!

receive_reference_removal_notification(reference)[source]

Not for end-users!

oldman.core.session.tracker module
class oldman.core.session.tracker.BasicResourceTracker[source]

Bases: oldman.core.session.tracker.ResourceTracker

add(resource)[source]
add_all(resources)[source]
find(iri)[source]

TODO: re-implement

forget_resources_to_delete()[source]
get_dependencies(resource)[source]
mark_to_delete(resource)[source]
modified_resources

TODO: re-implement it

receive_reference(reference, object_resource=None, object_iri=None)[source]

TODO: better implement it

receive_reference_removal_notification(reference)[source]
resources_to_delete
class oldman.core.session.tracker.ResourceTracker[source]

Bases: object

add(resource)[source]
add_all(resources)[source]
find(iri)[source]

Inherited. See YYYY

forget_resources_to_delete()[source]
get_dependencies(resource)[source]
mark_to_delete(resource)[source]
modified_resources

TODO: explain Excludes resources to be deleted.

receive_reference(reference, object_resource=None, object_iri=None)[source]
receive_reference_removal_notification(reference)[source]
resources_to_delete
Module contents
oldman.core.utils package
Submodules
oldman.core.utils.crud module
oldman.core.utils.crud.create_blank_nodes(session, graph, bnode_subjects, hashless_iri=None, collection_iri=None)[source]

TODO: comment

oldman.core.utils.crud.create_regular_resources(manager, graph, subjects, hashless_iri=None, collection_iri=None)[source]

“TODO: comment

oldman.core.utils.crud.extract_subjects(graph)[source]
oldman.core.utils.sparql module
oldman.core.utils.sparql.build_query_part(verb_and_vars, subject_term, lines)[source]

Builds a SPARQL query.

Parameters:
  • verb_and_vars – SPARQL verb and variables.
  • subject_term – Common subject term.
  • lines – Lines to insert into the WHERE block.
Returns:

A SPARQL query.

oldman.core.utils.sparql.build_update_query_part(verb, subject, lines)[source]

Builds a SPARQL Update query.

Parameters:
  • verb – SPARQL verb.
  • subject – Common subject term.
  • lines – Lines to insert into the WHERE block.
Returns:

A SPARQL Update query.

oldman.core.utils.sparql.parse_graph_safely(graph, *args, **kwargs)[source]

Skolemizes the input source if the graph uses a rdflib.plugins.stores.sparqlstore.SPARQLUpdateStore object.

Parameters:
  • graphrdflib.graph.Graph object.
  • args – Argument list to transmit to rdflib.graph.Graph.parse().
  • kwargs – Argument dict to transmit to rdflib.graph.Graph.parse().
Returns:

The updated rdflib.graph.Graph object.

Module contents
oldman.core.validation package
Submodules
oldman.core.validation.value_format module
class oldman.core.validation.value_format.AnyValueFormat[source]

Bases: oldman.core.validation.value_format.ValueFormat

Accepts any value.

check_value(value)[source]

See oldman.validation.value_format.ValueFormat.check_value().

class oldman.core.validation.value_format.EmailValueFormat[source]

Bases: oldman.core.validation.value_format.TypedValueFormat

Checks that the value is an email address.

check_value(value)[source]

See oldman.validation.value_format.ValueFormat.check_value().

class oldman.core.validation.value_format.HexBinaryFormat[source]

Bases: oldman.core.validation.value_format.TypedValueFormat

Checks that the value is a hexadecimal string.

check_value(value)[source]

See oldman.validation.value_format.ValueFormat.check_value().

to_python(rdf_term)[source]

Returns a hexstring.

class oldman.core.validation.value_format.IRIValueFormat[source]

Bases: oldman.core.validation.value_format.ValueFormat

Checks that the value is an IRI.

check_value(value)[source]

See oldman.validation.value_format.ValueFormat.check_value().

class oldman.core.validation.value_format.NegativeTypedValueFormat(types)[source]

Bases: oldman.core.validation.value_format.TypedValueFormat

Checks that the value is a negative number.

check_value(value)[source]

See oldman.validation.value_format.ValueFormat.check_value().

class oldman.core.validation.value_format.NonNegativeTypedValueFormat(types)[source]

Bases: oldman.core.validation.value_format.TypedValueFormat

Checks that the value is a non-negative number.

check_value(value)[source]

See oldman.validation.value_format.ValueFormat.check_value().

class oldman.core.validation.value_format.NonPositiveTypedValueFormat(types)[source]

Bases: oldman.core.validation.value_format.TypedValueFormat

Checks that the value is a non-positive number.

check_value(value)[source]

See oldman.validation.value_format.ValueFormat.check_value().

class oldman.core.validation.value_format.PositiveTypedValueFormat(types)[source]

Bases: oldman.core.validation.value_format.TypedValueFormat

Checks that the value is a positive number.

check_value(value)[source]

See oldman.validation.value_format.ValueFormat.check_value().

class oldman.core.validation.value_format.TypedValueFormat(types)[source]

Bases: oldman.core.validation.value_format.ValueFormat

Checks that the value is of a given type.

Parameters:types – Supported Python types.
check_value(value)[source]

See oldman.validation.value_format.ValueFormat.check_value().

class oldman.core.validation.value_format.ValueFormat[source]

Bases: object

A ValueFormat object checks the values and converts rdflib.term.Identifier objects into Python objects.

check_value(value)[source]

Raises a ValueFormatError exception if the value is wrongly formatted.

Parameters:value – Python value to check.
to_python(rdf_term)[source]

Converts a rdflib.term.Identifier object into a regular Python value.

By default, uses the RDFlib toPython() method.

Parameters:rdf_termrdflib.term.Identifier object.
Returns:Regular Python object.
exception oldman.core.validation.value_format.ValueFormatError[source]

Bases: exceptions.Exception

Invalid format detected.

Module contents
Submodules
oldman.core.common module
oldman.core.common.is_blank_node(iri)[source]

Tests if id is a locally skolemized IRI.

External skolemized blank nodes are not considered as blank nodes.

Parameters:iri – IRI of the resource.
Returns:True if is a blank node.
oldman.core.common.is_temporary_blank_node(iri)[source]
oldman.core.exception module
exception oldman.core.exception.AlreadyAllocatedModelError[source]

Bases: oldman.core.exception.ModelGenerationError

The class IRI or the short name of a new model is already allocated.

exception oldman.core.exception.ModelGenerationError[source]

Bases: oldman.core.exception.OMError

Error when generating a new model.

exception oldman.core.exception.OMAccessError[source]

Bases: oldman.core.exception.OMUserError

Error when accessing objects.

exception oldman.core.exception.OMAlreadyDeclaredDatatypeError[source]

Bases: oldman.core.exception.OMAttributeDefError

At least two different datatypes for the same attribute.

You may check the possible datatype inherited from the property (rdfs:range) and the one specified in the JSON-LD context.

exception oldman.core.exception.OMAlreadyGeneratedAttributeError[source]

Bases: oldman.core.exception.OMInternalError

Attribute generation occurs only once per SupportedProperty.

You should not try to add metadata or regenerate after that.

exception oldman.core.exception.OMAttributeAccessError[source]

Bases: oldman.core.exception.OMAccessError

When such an attribute cannot be identified (is not supported or no model has been found).

exception oldman.core.exception.OMAttributeDefError[source]

Bases: oldman.core.exception.OMSchemaError

Inconsistency in the definition of a model class attribute.

exception oldman.core.exception.OMAttributeTypeCheckError[source]

Bases: oldman.core.exception.OMEditError

The value assigned to the attribute has wrong type.

exception oldman.core.exception.OMBadRequestException[source]

Bases: oldman.core.exception.OMControllerException

TODO: describe

Error: 400

exception oldman.core.exception.OMClassInstanceError[source]

Bases: oldman.core.exception.OMAccessError

The object is not an instance of the expected RDFS class.

exception oldman.core.exception.OMControllerException[source]

Bases: exceptions.Exception

TODO: describe

exception oldman.core.exception.OMDifferentHashlessIRIError[source]

Bases: oldman.core.exception.OMIriError, oldman.core.exception.OMEditError

When creating or updating an object with a different hashless IRI is forbidden.

Blank nodes are not concerned.

exception oldman.core.exception.OMEditError[source]

Bases: oldman.core.exception.OMUserError

Runtime errors, occuring when editing or creating an object.

exception oldman.core.exception.OMError[source]

Bases: exceptions.Exception

Root of exceptions generated by the oldman package expected HTTP ones.

exception oldman.core.exception.OMExpiredMethodDeclarationTimeSlotError[source]

Bases: oldman.core.exception.ModelGenerationError

All methods must be declared before creating a first model.

exception oldman.core.exception.OMForbiddenOperationException[source]

Bases: oldman.core.exception.OMControllerException

No chance TODO: improve

exception oldman.core.exception.OMForbiddenSkolemizedIRIError[source]

Bases: oldman.core.exception.OMEditError

When updating a skolemized IRI from the local domain is forbidden.

exception oldman.core.exception.OMHashIriError[source]

Bases: oldman.core.exception.OMAccessError

A hash IRI has been given instead of a hash-less IRI.

exception oldman.core.exception.OMInternalError[source]

Bases: oldman.core.exception.OMError

Do not expect it.

exception oldman.core.exception.OMIriError[source]

Bases: oldman.core.exception.OMRuntimeError

Root class for problems with an IRI (generation, validation).

exception oldman.core.exception.OMMethodNotAllowedException[source]

Bases: oldman.core.exception.OMControllerException

405

exception oldman.core.exception.OMNotAcceptableException[source]

Bases: oldman.core.exception.OMControllerException

406 Not Acceptable

TODO: indicate the content-type

exception oldman.core.exception.OMObjectNotFoundError[source]

Bases: oldman.core.exception.OMAccessError

When the object is not found.

exception oldman.core.exception.OMPropertyDefError[source]

Bases: oldman.core.exception.OMSchemaError

Inconsistency in the definition of a supported property.

exception oldman.core.exception.OMPropertyDefTypeError[source]

Bases: oldman.core.exception.OMPropertyDefError

A RDF property cannot be both an ObjectProperty and a DatatypeProperty.

exception oldman.core.exception.OMReadOnlyAttributeError[source]

Bases: oldman.core.exception.OMEditError

End-users are not allowed to edit this attribute.

exception oldman.core.exception.OMRequiredAuthenticationException[source]

Bases: oldman.core.exception.OMControllerException

Try again TODO: improve

exception oldman.core.exception.OMRequiredHashlessIRIError[source]

Bases: oldman.core.exception.OMEditError

No hash-less IRI has been given.

exception oldman.core.exception.OMRequiredPropertyError[source]

Bases: oldman.core.exception.OMEditError

A required property has no value.

exception oldman.core.exception.OMReservedAttributeNameError[source]

Bases: oldman.core.exception.OMAttributeDefError

Some attribute names are reserved and should not be included in the JSON-LD context.

exception oldman.core.exception.OMResourceNotFoundException[source]

Bases: oldman.core.exception.OMControllerException

TODO: describe

exception oldman.core.exception.OMRuntimeError[source]

Bases: oldman.core.exception.OMError

Error at runtime after the initialization.

exception oldman.core.exception.OMSPARQLError[source]

Bases: oldman.core.exception.OMAccessError

Invalid SPARQL query given.

exception oldman.core.exception.OMSPARQLParseError[source]

Bases: oldman.core.exception.OMInternalError

Invalid SPARQL request.

exception oldman.core.exception.OMSchemaError[source]

Bases: oldman.core.exception.ModelGenerationError

Error in the schema graph and/or the JSON-LD context.

exception oldman.core.exception.OMStoreError[source]

Bases: oldman.core.exception.OMRuntimeError

Error detected in the stored data.

exception oldman.core.exception.OMTemporaryIriError[source]

Bases: oldman.core.exception.OMEditError

When saving a Resource that has an attribute that points to a temporary IRI.

exception oldman.core.exception.OMUnauthorizedTypeChangeError[source]

Bases: oldman.core.exception.OMEditError

When updating a resource with new types without explicit authorization.

exception oldman.core.exception.OMUndeclaredClassNameError[source]

Bases: oldman.core.exception.ModelGenerationError

The name of the model class should be defined in the JSON-LD context.

exception oldman.core.exception.OMUniquenessError[source]

Bases: oldman.core.exception.OMEditError

Attribute uniqueness violation.

Example: IRI illegal reusing.

exception oldman.core.exception.OMUnsupportedUserIRIError[source]

Bases: oldman.core.exception.OMIriError, oldman.core.exception.OMEditError

The IRI provided by the user is not supported.

exception oldman.core.exception.OMUserError[source]

Bases: oldman.core.exception.OMRuntimeError

Error when accessing or editing objects.

exception oldman.core.exception.OMWrongResourceError[source]

Bases: oldman.core.exception.OMEditError

Not updating the right object.

exception oldman.core.exception.UnsupportedDataStorageFeatureException[source]

Bases: oldman.core.exception.OMStoreError

Feature not supported by the data store.

oldman.core.id module
class oldman.core.id.OMId(iri, is_permanent)[source]

TODO: explain why an ID object and not a simple IRI. An ID can be temporary.

Immutable data structure.

fragment

TODO: explain

hashless_iri

TODO: explain

iri
is_blank_node

TODO: explain

is_permanent
class oldman.core.id.PermanentId(iri)[source]

Bases: oldman.core.id.OMId

TODO: explain

class oldman.core.id.TemporaryId(suggested_hashless_iri=None, suggested_iri_fragment=None, collection_iri=None, can_remain_bnode=True)[source]

Bases: oldman.core.id.OMId

TODO: describe

can_remain_bnode

Returns True if is currently a blank node and may remain it before being stored.

collection_iri
suggested_fragment

TODO: explain

suggested_hashless_iri

TODO: explain

oldman.core.id.generate_iri_with_uuid_fragment(hashless_iri)[source]

TODO: describe

oldman.core.id.generate_uuid_iri(prefix=u'http://localhost/.well-known/genid/', fragment=None)[source]

TODO: describe

oldman.core.vocabulary module
oldman.vocabulary

RDF vocabulary used by OldMan. Some of it is specific to OldMan.

TODO: replace these URNs by URLs.

Parent model prioritization

In RDF, a class is often the child of multiple classes. When the code inherited from these classes (common practise in Object-Oriented Programming) is conflicting, arbitration is necessary.

In this library, we provide a RDF vocabulary to declare priorities for each parent of a given child class. A priority statement is declared as follows:

?cls <urn:oldman:model:ordering:hasPriority> [
    <urn:oldman:model:ordering:class> ?parent1 ;
    <urn:oldman:model:ordering:priority> 2
].

By default, when no priority is declared for a pair (child, parent), its priority value is set to 0.

oldman.core.vocabulary.NEXT_NUMBER_IRI = 'urn:oldman:nextNumber'

Used to increment IRIs.

Module contents
oldman.storage package
Subpackages
oldman.storage.hydra package
Submodules
oldman.storage.hydra.schema_adapter module
class oldman.storage.hydra.schema_adapter.HydraSchemaAdapter[source]

Bases: object

Updates some Hydra patterns in the schema graph:

update_schema_graph(graph)[source]
Module contents
oldman.storage.model package
Subpackages
oldman.storage.model.conversion package
Submodules
oldman.storage.model.conversion.converter module
class oldman.storage.model.conversion.converter.DirectMappingModelConverter(client_to_store_mappings)[source]

Bases: oldman.storage.model.conversion.converter.ModelConverter

from_client_to_store(client_resource, store_resource, conversion_manager, xstore_session)[source]
from_store_to_client(store_resource, client_resource, conversion_manager, client_tracker, client_factory)[source]
class oldman.storage.model.conversion.converter.EquivalentModelConverter(client_model, store_model)[source]

Bases: oldman.storage.model.conversion.converter.DirectMappingModelConverter

TODO: describe

class oldman.storage.model.conversion.converter.ModelConverter[source]

Bases: object

TODO: find a better name and explain

from_client_to_store(client_resource, store_resource, conversion_manager, xstore_session)[source]
from_store_to_client(store_resource, client_resource, conversion_manager, client_tracker, client_factory)[source]
oldman.storage.model.conversion.entry module
class oldman.storage.model.conversion.entry.ClientToStoreEntryExchanger(conversion_manager, store, client_resource, store_resource, xstore_session)[source]

Bases: oldman.storage.model.conversion.entry.EntryExchanger

target_subject_resource
target_tracker
class oldman.storage.model.conversion.entry.EntryExchanger(client_resource, store_resource)[source]

Bases: object

TODO: explain

exchange(source_attribute, target_attribute)[source]
target_subject_resource
target_tracker
class oldman.storage.model.conversion.entry.StoreToClientEntryExchanger(conversion_manager, client_resource, store_resource, client_session, client_factory)[source]

Bases: oldman.storage.model.conversion.entry.EntryExchanger

target_subject_resource
target_tracker
oldman.storage.model.conversion.manager module
class oldman.storage.model.conversion.manager.ModelConversionManager[source]

Bases: object

TODO: describe and find a better name.

convert_client_to_store_resource(client_resource, store, xstore_session)[source]

TODO: explain

convert_store_to_client_resource(store_resource, client_factory, client_tracker, update_local_client_resource=False)[source]
Parameters:
  • store_resource
  • client_factory
  • client_tracker
  • update_local_client_resource – FOR OTHER updates than the IRI!
Returns:

convert_store_to_client_resources(store_resources, resource_finder, resource_factory)[source]

TODO: describe

register_model_converter(client_model, store_model, data_store, model_converter)[source]
Module contents
Submodules
oldman.storage.model.manager module
class oldman.storage.model.manager.StoreModelManager(schema_graph=None, attr_extractor=None)[source]

Bases: oldman.core.model.manager.ModelManager

create_model(class_name_or_iri, context_iri_or_payload, store, iri_prefix=None, iri_fragment=None, iri_generator=None, untyped=False, incremental_iri=False, is_default=False, context_file_path=None)[source]

Creates a StoreModel object.

TODO: remove data_store from the constructor!

To create it, they are three elements to consider:

  1. Its class IRI which can be retrieved from class_name_or_iri;
  2. Its JSON-LD context for mapping OMAttribute values to RDF triples;
  3. The IriGenerator object that generates IRIs from new Resource objects.

The IriGenerator object is either:

  • directly given: iri_generator;
  • created from the parameters iri_prefix, iri_fragment and incremental_iri.
Parameters:
  • class_name_or_iri – IRI or JSON-LD term of a RDFS class.
  • context_iri_or_payloaddict, list or IRI that represents the JSON-LD context .
  • iri_generatorIriGenerator object. If given, other iri_* parameters are ignored.
  • iri_prefix – Prefix of generated IRIs. Defaults to None. If is None and no iri_generator is given, a BlankNodeIriGenerator is created.
  • iri_fragment – IRI fragment that is added at the end of generated IRIs. For instance, “me” adds “#me” at the end of the new IRI. Defaults to None. Has no effect if iri_prefix is not given.
  • incremental_iri – If True an IncrementalIriGenerator is created instead of a RandomPrefixedIriGenerator. Defaults to False. Has no effect if iri_prefix is not given.
  • context_file_path – TODO: describe.
oldman.storage.model.model module
class oldman.storage.model.model.StoreModel(name, class_iri, ancestry_iris, context, om_attributes, id_generator, local_context=None)[source]

Bases: oldman.core.model.model.Model

Parameters:
  • name – Model name. Usually corresponds to a JSON-LD term or to a class IRI.
  • class_iri – IRI of the RDFS class represented by this Model object.
  • ancestry_iris – ancestry of the attribute class_iri. Each instance of class_iri is also instance of these classes.
  • context – An IRI, a list or a dict that describes the JSON-LD context. See http://www.w3.org/TR/json-ld/#the-context for more details.
  • om_attributesdict of OMAttribute objects. Keys are their names.
  • id_generatorIriGenerator object that generates IRIs from new Resource objects.
  • methodsdict of Python functions that takes as first argument a Resource object. Keys are the method names. Defaults to {}. TODO: see if is still needed.
  • local_context – TODO: describe.
generate_permanent_id(previous_id)[source]

Generates a new OMId object.

Used by the StoreResource class but an end-user should not need to call it.

Returns:A new OMId object.
reset_counter()[source]

Resets the counter of the ID generator.

Please use it only for test purposes.

Module contents
oldman.storage.store package
Submodules
oldman.storage.store.cache module
class oldman.storage.store.cache.ResourceCache(cache_region)[source]

Bases: object

A ResourceCache object caches Resource objects.

It interfaces a dogpile.cache.region.CacheRegion front-end object. If not None, cache_region must be already configured, i.e. mapped to a back-end (like Memcache or Redis). See the official list of back-ends supported by dogpile.cache.

When cache_region is None, no effective caching is done. However, methods get_resource(), set_resource() and remove_resource() can still safely be called. They just have no effect.

Parameters:cache_regiondogpile.cache.region.CacheRegion object. This object must already be configured. Defaults to None (no cache).
cache_region

dogpile.cache.region.CacheRegion object. May be None.

change_cache_region(cache_region)[source]

Replaces the cache_region attribute.

Parameters:cache_regiondogpile.cache.region.CacheRegion object. May be None.
get_resource(iri, store_session)[source]

Gets a Resource object from the cache.

Parameters:iri – IRI of the resource.
Returns:Resource object or None if not found.
invalidate_cache()[source]

See dogpile.cache.region.CacheRegion.invalidate().

Cache invalidation

Please note that this method is not supported by some dogpile.cache.api.CacheBackend objects. In such a case, this method has no effect so entries must be removed explicitly from their keys.

is_active()[source]
Returns:True if the cache_region is active.
remove_resource(resource)[source]

Removes a Resource object from the cache.

Indempotent (no problem if the Resource object is not the cache). Does nothing if cache_region is None.

Parameters:resourceResource object to remove from the cache.
remove_resource_from_iri(iri)[source]

remove_resource() is usually preferred.

Indempotent and does nothing if cache_region is None.

Parameters:iri – IRI of the resource to remove from the cache.
set_resource(resource)[source]

Adds or updates a Resource object in the cache.

Its key is its ìd.

Parameters:resourceResource object to add to the cache (or update).
oldman.storage.store.http module
class oldman.storage.store.http.HttpStore(schema_graph=None, cache_region=None, http_session=None)[source]

Bases: oldman.storage.store.store.Store

Read only. No search feature.

oldman.storage.store.sparql module
class oldman.storage.store.sparql.SparqlStore(data_graph, schema_graph=None, model_manager=None, union_graph=None, cache_region=None)[source]

Bases: oldman.storage.store.store.Store

A SPARQLStore is a Store object relying on a SPARQL 1.1 endpoint (Query and Update).

Parameters:
  • data_graphrdflib.graph.Graph object where all the non-schema resources are stored by default.
  • union_graph – Union of all the named graphs of a rdflib.ConjunctiveGraph or a rdflib.Dataset. Super-set of data_graph and may also include schema_graph. Defaults to data_graph. Read-only.
  • cache_regiondogpile.cache.region.CacheRegion object. This object must already be configured. Defaults to None (no cache). See ResourceCache for further details.

TODO: complete

check_and_repair_counter(class_iri)[source]

Checks the counter of a given RDFS class and repairs (inits) it if needed.

Parameters:class_iri – RDFS class IRI.
exists(id)[source]
extract_prefixes(other_graph)[source]

Adds the RDF prefix (namespace) information from an other graph to the namespace of the data_graph. :param other_graph: rdflib.graph.Graph that some prefix information.

generate_instance_number(class_iri)[source]

Needed for generating incremental IRIs.

reset_instance_counter(class_iri)[source]

Reset the counter related to a given RDFS class.

For test purposes only.

Parameters:class_iri – RDFS class IRI.
sparql_filter(store_session, query)[source]

Finds the Resource objects matching a given query.

Parameters:query – SPARQL SELECT query where the first variable assigned corresponds to the IRIs of the resources that will be returned.
Returns:A generator of Resource objects.
oldman.storage.store.store module
class oldman.storage.store.store.Store(model_manager, cache_region=None, accept_iri_generation_configuration=True, support_sparql=False)[source]

Bases: object

A Store object manages CRUD operations on StoreResource objects.

In the future, non-CRUD operations may also be supported.

Manages the cache (ResourceCache object) of StoreResource object.

Parameters:
  • model_manager – TODO: describe!!!
  • cache_regiondogpile.cache.region.CacheRegion object. This object must already be configured. Defaults to None (no cache). See ResourceCache for further details.
  • accept_iri_generation_configuration – If False, the IRI generator cannot be configured by the user: it is imposed by the data store. Default to False.
check_and_repair_counter(class_iri)[source]

Checks the counter of a given RDFS class and repairs (inits) it if needed.

Parameters:class_iri – RDFS class IRI.
create_model(class_name_or_iri, context_iri_or_payload, iri_generator=None, iri_prefix=None, iri_fragment=None, incremental_iri=False, context_file_path=None)[source]

TODO: comment. Convenience function

exists(resource_iri)[source]

Tests if the IRI of the resource is present in the data_store.

May raise an UnsupportedDataStorageFeatureException exception.

Parameters:resource_iri – IRI of the Resource object.
Returns:True if exists.
filter(store_session, types=None, hashless_iri=None, limit=None, eager=True, pre_cache_properties=None, **kwargs)[source]

Finds the Resource objects matching the given criteria.

The kwargs dict can contains:

  1. regular attribute key-values ;
  2. the special attribute iri. If given, get() is called.

TODO: UPDATE THE COMMENT!

Parameters:
  • types – IRIs of the RDFS classes filtered resources must be instance of. Defaults to None.
  • hashless_iri – Hash-less IRI of filtered resources. Defaults to None.
  • limit – Upper bound on the number of solutions returned (e.g. SPARQL LIMIT). Positive integer. Defaults to None.
  • eager – If True loads all the Resource objects within the minimum number of queries (e.g. one single SPARQL query). Defaults to True.
  • pre_cache_properties – List of RDF ObjectProperties to pre-cache eagerly. Their values (Resource objects) are loaded and added to the cache. Defaults to []. If given, eager must be True. Disabled if there is no cache.
Returns:

A generator (if lazy) or a list (if eager) of Resource objects.

first(store_session, types=None, hashless_iri=None, eager_with_reversed_attributes=True, pre_cache_properties=None, **kwargs)[source]

Gets the first Resource object matching the given criteria.

The kwargs dict can contains regular attribute key-values.

TODO: UPDATE THE COMMENT!

Parameters:
  • types – IRIs of the RDFS classes filtered resources must be instance of. Defaults to None.
  • hashless_iri – Hash-less IRI of filtered resources. Defaults to None.
  • eager_with_reversed_attributes – Allow to Look eagerly for reversed RDF properties. May cause some overhead for some Resource objects that do not have reversed attributes. Defaults to True.
  • pre_cache_properties – List of RDF ObjectProperties to pre-cache eagerly. Their values (Resource objects) are loaded and added to the cache. Defaults to []. If given, eager must be True. Disabled if there is no cache.
Returns:

A Resource object or None if no resource has been found.

flush(resources_to_update, resources_to_delete, is_end_user)[source]

TODO: explain :param new_resources: :param resources_to_update: :param resources_to_delete: :return:

generate_instance_number(class_iri)[source]

Generates a new incremented number for a given RDFS class IRI.

May raise an UnsupportedDataStorageFeatureException exception.

Parameters:class_iri – RDFS class IRI.
Returns:Incremented number.
get(store_session, iri, types=None, eager_with_reversed_attributes=True)[source]

Gets the Resource object having the given IRI.

The kwargs dict can contains regular attribute key-values.

When types are given, they are then checked. An OMClassInstanceError is raised if the resource is not instance of these classes.

Parameters:
  • iri – IRI of the resource. Defaults to None.
  • types – IRIs of the RDFS classes filtered resources must be instance of. Defaults to None.
Returns:

A StoreResource object or None if no resource has been found.

classmethod get_store(name)[source]

Gets a DataStore object by its name.

Parameters:name – store name.
Returns:A ModelManager object.
model_manager

The ModelManager object.

TODO: update

Necessary for creating new StoreResource objects and accessing to Model objects.

name

Randomly generated name. Useful for serializing resources.

reset_instance_counter(class_iri)[source]

Reset the counter related to a given RDFS class.

For test purposes only.

Parameters:class_iri – RDFS class IRI.
resource_cache

ResourceCache object.

sparql_filter(store_session, query)[source]

Finds the Resource objects matching a given query.

Raises an UnsupportedDataStorageFeatureException exception if the SPARQL protocol is not supported by the concrete data_store.

Parameters:query – SPARQL SELECT query where the first variable assigned corresponds to the IRIs of the resources that will be returned.
Returns:A generator of Resource objects.
support_sparql_filtering()[source]

Returns True if the datastore supports SPARQL queries (no update).

Note that in such a case, the sparql_filter() method is expected to be implemented.

Module contents
Submodules
oldman.storage.id_generation module
class oldman.storage.id_generation.BlankNodePermanentIDGenerator(hostname=u'localhost')[source]

Bases: oldman.storage.id_generation.PrefixedUUIDPermanentIDGenerator

Generates skolem IRIs that denote blank nodes.

Parameters:hostname – Defaults to “localhost”.
class oldman.storage.id_generation.IncrementalIriGenerator(prefix, store, class_iri, fragment=None)[source]

Bases: oldman.storage.id_generation.PermanentIDGenerator

Generates IRIs with short numbers.

Beautiful but slow in concurrent settings. The number generation implies a critical section and a sequence of two SPARQL requests, which represents a significant bottleneck.

Parameters:
  • prefix – IRI prefix.
  • store – TODO: describe.
  • graphrdflib.Graph object where to store the counter.
  • class_iri – IRI of the RDFS class of which new Resource objects are instance of. Usually corresponds to the class IRI of the Model object that owns this generator.
  • fragment – IRI fragment to append to the hash-less IRI. Defaults to None.
generate_permanent_id(ignored_tmp_id)[source]

See oldman.iri.permanent.PermanentIDGenerator.generate_permanent_id().

reset_counter()[source]

For test purposes only

class oldman.storage.id_generation.PermanentIDGenerator(is_generating_blank_nodes)[source]

Bases: object

An PermanentIDGenerator object generates the Resource objects.

generate_permanent_id(temporary_id)[source]

Generates an ID.

Returns:A PermanentID.
is_generating_blank_nodes

TODO: remove

class oldman.storage.id_generation.PrefixedUUIDPermanentIDGenerator(prefix, fragment=None, is_generating_blank_nodes=False)[source]

Bases: oldman.storage.id_generation.PermanentIDGenerator

Uses a prefix, a fragment and a unique UUID1 number to generate IRIs.

Recommended generator because UUID1 is robust and fast (no DB access).

Parameters:
  • prefix – IRI prefix.
  • fragment – IRI fragment to append to the hash-less IRI. Defaults to None.
generate_permanent_id(ignored_tmp_id)[source]

See oldman.iri.permanent.PermanentIDGenerator.generate_permanent_id().

class oldman.storage.id_generation.UUIDFragmentPermanentIDGenerator[source]

Bases: oldman.storage.id_generation.PermanentIDGenerator

Generates an hashed IRI from a hash-less IRI.

Its fragment is a unique UUID1 number.

generate_permanent_id(temporary_id)[source]

See oldman.iri.permanent.PermanentIDGenerator.generate_permanent_id().

oldman.storage.resource module
class oldman.storage.resource.StoreResource(previous_id, model_manager, store, session, types=None, is_new=True, **kwargs)[source]

Bases: oldman.core.resource.resource.Resource

StoreResource: resource manipulated by the data store.

End-users should not manipulate it.

Is serializable (pickable).

Parameters:
  • previous_id – TODO: describe (maybe a temporary one).
  • model_managerModelManager object. Gives access to its models.
  • storeStore object. Store that has authority on this resource.
  • kwargs – Other parameters considered by the Resource constructor and values indexed by their attribute names.
classmethod load_from_graph(model_manager, store, session, iri, subgraph, is_new=True)[source]

Loads a new StoreResource object from a sub-graph.

TODO: update the comments.

Parameters:
  • model_managerStoreModelManager object.
  • iri – IRI of the resource.
  • subgraphrdflib.Graph object containing triples about the resource.
  • is_new – When is True and id given, checks that the IRI is not already existing in the union_graph. Defaults to True.
Returns:

The StoreResource object created.

prepare_deletion()[source]
reattach(xstore_session)[source]
store
oldman.storage.session module
class oldman.storage.session.CrossStoreSession[source]

Bases: oldman.core.session.session.Session

load_from_graph(id, resource_graph, store)[source]
new(id, store, types=None, hashless_iri=None, collection_iri=None, is_new=True, former_types=None, **kwargs)[source]

Creates a new Resource object without saving it in the data_store.

The kwargs dict can contains regular attribute key-values that will be assigned to OMAttribute objects.

TODO: update this doc

Parameters:
  • id – TODO: explain
  • types – IRIs of RDFS classes the resource is instance of. Defaults to None. Note that these IRIs are used to find the models of the resource (see find_models_and_types() for more details).
  • hashless_iri – hash-less IRI that MAY be considered when generating an IRI for the new resource. Defaults to None. Ignored if id is given. Must be None if collection_iri is given.
  • collection_iri – IRI of the controller to which this resource belongs. This information is used to generate a new IRI if no id is given. The IRI generator may ignore it. Defaults to None. Must be None if hashless_iri is given.
Returns:

A new Resource object.

tracker
class oldman.storage.session.DefaultCrossStoreSession(store_selector)[source]

Bases: oldman.storage.session.CrossStoreSession

TODO: explain because the name can be counter-intuitive

close()[source]

Does nothing

delete(store_resource)[source]

TODO: describe.

Wait for the next flush() to remove the resource from the store.

flush(is_end_user=True)[source]

TODO: re-implement it

get(iri, types=None, eager_with_reversed_attributes=True)[source]
load_from_graph(id, resource_graph, store)[source]
new(id, store, types=None, is_new=True, former_types=None, **kwargs)[source]
receive_reference(reference, object_resource=None, object_iri=None)[source]
receive_reference_removal_notification(reference)[source]
tracker
oldman.storage.session.cluster_by_store(resources)[source]
oldman.storage.session.cluster_by_store_and_status(resources_to_update, resources_to_delete)[source]
Module contents

Module contents

OldMan

Object Linked Data Mapper (OLDM)

oldman.create_mediator(data_stores, schema_graph=None, attr_extractor=None, oper_extractor=None, mediator_class=<class 'oldman.client.mediation.default.DefaultMediator'>)[source]

TODO: describe

Module Index, Index and Search Page.