Core concepts



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.


  1. Edit its properties:

    >>> # We assume that a model has been created for the RDFS class schema:Person.
    >>> alice = Resource(resource_manager, types=[""])
    >>> = "Alice"
    >>> print
    >>> print
    >>> alice.add_type("")
    >>> print alice.types
    [u'', u'']
  2. Persist its new values in the triplestore:
  3. Call inherited methods:

  4. Serialize to JSON, JSON-LD or any other RDF format:

    >>> alice.to_jsonld()
      "@context": "",
      "id": "http://localhost/person/3#me",
      "name": "Alice",
      "types": [
    >>> alice.to_rdf(format="turtle")
    @prefix schema: <> .
    @prefix xsd: <> .
    <http://localhost/persons/3#me> a schema:Person, schema:Researcher ;
                foaf:name "Alice"^^xsd:string .


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.


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.


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.


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.