Skip to content

resource

The Resource class wraps a Graph and a resource reference (i.e. a URIRef or BNode) to support a resource-oriented way of working with a graph.

It contains methods directly corresponding to those methods of the Graph interface that relate to reading and writing data. The difference is that a Resource also binds a resource identifier, making it possible to work without tracking both the graph and a current subject. This makes for a “resource oriented” style, as compared to the triple orientation of the Graph API.

Resulting generators are also wrapped so that any resource reference values (URIRef and BNode) are in turn wrapped as Resources. (Note that this behaviour differs from the corresponding methods in Graph, where no such conversion takes place.)

Basic Usage Scenario

Start by importing things we need and define some namespaces:

>>> from rdflib import *
>>> FOAF = Namespace("http://xmlns.com/foaf/0.1/")
>>> CV = Namespace("http://purl.org/captsolo/resume-rdf/0.2/cv#")

Load some RDF data:

>>> graph = Graph().parse(format='n3', data='''
... @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
... @prefix xsd: <http://www.w3.org/2001/XMLSchema#>.
... @prefix foaf: <http://xmlns.com/foaf/0.1/> .
... @prefix cv: <http://purl.org/captsolo/resume-rdf/0.2/cv#> .
...
... @base <http://example.org/> .
...
... </person/some1#self> a foaf:Person;
...     rdfs:comment "Just a Python & RDF hacker."@en;
...     foaf:depiction </images/person/some1.jpg>;
...     foaf:homepage <http://example.net/>;
...     foaf:name "Some Body" .
...
... </images/person/some1.jpg> a foaf:Image;
...     rdfs:label "some 1"@en;
...     rdfs:comment "Just an image"@en;
...     foaf:thumbnail </images/person/some1-thumb.jpg> .
...
... </images/person/some1-thumb.jpg> a foaf:Image .
...
... [] a cv:CV;
...     cv:aboutPerson </person/some1#self>;
...     cv:hasWorkHistory [ cv:employedIn </#company>;
...             cv:startDate "2009-09-04"^^xsd:date ] .
... ''')

Create a Resource:

>>> person = Resource(
...     graph, URIRef("http://example.org/person/some1#self"))

Retrieve some basic facts:

>>> person.identifier
rdflib.term.URIRef('http://example.org/person/some1#self')

>>> person.value(FOAF.name)
rdflib.term.Literal('Some Body')

>>> person.value(RDFS.comment)
rdflib.term.Literal('Just a Python & RDF hacker.', lang='en')

Resources can be sliced (like graphs, but the subject is fixed):

>>> for name in person[FOAF.name]:
...     print(name)
Some Body
>>> person[FOAF.name : Literal("Some Body")]
True

Resources as unicode are represented by their identifiers as unicode:

>>> %(unicode)s(person)  #doctest: +SKIP
'Resource(http://example.org/person/some1#self'

Resource references are also Resources, so you can easily get e.g. a qname for the type of a resource, like:

>>> person.value(RDF.type).qname()
'foaf:Person'

Or for the predicates of a resource:

>>> sorted(
...     p.qname() for p in person.predicates()
... )  #doctest: +NORMALIZE_WHITESPACE +SKIP
['foaf:depiction', 'foaf:homepage',
 'foaf:name', 'rdf:type', 'rdfs:comment']

Follow relations and get more data from their Resources as well:

>>> for pic in person.objects(FOAF.depiction):
...     print(pic.identifier)
...     print(pic.value(RDF.type).qname())
...     print(pic.value(FOAF.thumbnail).identifier)
http://example.org/images/person/some1.jpg
foaf:Image
http://example.org/images/person/some1-thumb.jpg
>>> for cv in person.subjects(CV.aboutPerson):
...     work = list(cv.objects(CV.hasWorkHistory))[0]
...     print(work.value(CV.employedIn).identifier)
...     print(work.value(CV.startDate))
http://example.org/#company
2009-09-04

It’s just as easy to work with the predicates of a resource:

>>> for s, p in person.subject_predicates():
...     print(s.value(RDF.type).qname())
...     print(p.qname())
...     for s, o in p.subject_objects():
...         print(s.value(RDF.type).qname())
...         print(o.value(RDF.type).qname())
cv:CV
cv:aboutPerson
cv:CV
foaf:Person

This is useful for e.g. inspection:

>>> thumb_ref = URIRef("http://example.org/images/person/some1-thumb.jpg")
>>> thumb = Resource(graph, thumb_ref)
>>> for p, o in thumb.predicate_objects():
...     print(p.qname())
...     print(o.qname())
rdf:type
foaf:Image

Schema Example

With this artificial schema data:

>>> graph = Graph().parse(format='n3', data='''
... @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
... @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
... @prefix owl: <http://www.w3.org/2002/07/owl#> .
... @prefix v: <http://example.org/def/v#> .
...
... v:Artifact a owl:Class .
...
... v:Document a owl:Class;
...     rdfs:subClassOf v:Artifact .
...
... v:Paper a owl:Class;
...     rdfs:subClassOf v:Document .
...
... v:Choice owl:oneOf (v:One v:Other) .
...
... v:Stuff a rdf:Seq; rdf:_1 v:One; rdf:_2 v:Other .
...
... ''')

From this class:

>>> artifact = Resource(graph, URIRef("http://example.org/def/v#Artifact"))

we can get at subclasses:

>>> subclasses = list(artifact.transitive_subjects(RDFS.subClassOf))
>>> [c.qname() for c in subclasses]
['v:Artifact', 'v:Document', 'v:Paper']

and superclasses from the last subclass:

>>> [c.qname() for c in subclasses[-1].transitive_objects(RDFS.subClassOf)]
['v:Paper', 'v:Document', 'v:Artifact']

Get items from the Choice:

>>> choice = Resource(graph, URIRef("http://example.org/def/v#Choice"))
>>> [it.qname() for it in choice.value(OWL.oneOf).items()]
['v:One', 'v:Other']

On add, other resources are auto-unboxed:

>>> paper = Resource(graph, URIRef("http://example.org/def/v#Paper"))
>>> paper.add(RDFS.subClassOf, artifact)
>>> artifact in paper.objects(RDFS.subClassOf) # checks Resource instance
True
>>> (paper._identifier, RDFS.subClassOf, artifact._identifier) in graph
True

Technical Details

Comparison is based on graph and identifier:

>>> g1 = Graph()
>>> t1 = Resource(g1, URIRef("http://example.org/thing"))
>>> t2 = Resource(g1, URIRef("http://example.org/thing"))
>>> t3 = Resource(g1, URIRef("http://example.org/other"))
>>> t4 = Resource(Graph(), URIRef("http://example.org/other"))

>>> t1 is t2
False

>>> t1 == t2
True
>>> t1 != t2
False

>>> t1 == t3
False
>>> t1 != t3
True

>>> t3 != t4
True

>>> t3 < t1 and t1 > t3
True
>>> t1 >= t1 and t1 >= t3
True
>>> t1 <= t1 and t3 <= t1
True

>>> t1 < t1 or t1 < t3 or t3 > t1 or t3 > t3
False

Hash is computed from graph and identifier:

>>> g1 = Graph()
>>> t1 = Resource(g1, URIRef("http://example.org/thing"))

>>> hash(t1) == hash(Resource(g1, URIRef("http://example.org/thing")))
True

>>> hash(t1) == hash(Resource(Graph(), t1.identifier))
False
>>> hash(t1) == hash(Resource(Graph(), URIRef("http://example.org/thing")))
False

The Resource class is suitable as a base class for mapper toolkits. For example, consider this utility for accessing RDF properties via qname-like attributes:

>>> class Item(Resource):
...
...     def __getattr__(self, p):
...         return list(self.objects(self._to_ref(*p.split('_', 1))))
...
...     def _to_ref(self, pfx, name):
...         return URIRef(self._graph.store.namespace(pfx) + name)

It works as follows:

>>> graph = Graph().parse(format='n3', data='''
... @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
... @prefix foaf: <http://xmlns.com/foaf/0.1/> .
...
... @base <http://example.org/> .
... </person/some1#self>
...     foaf:name "Some Body";
...     foaf:depiction </images/person/some1.jpg> .
... </images/person/some1.jpg> rdfs:comment "Just an image"@en .
... ''')

>>> person = Item(graph, URIRef("http://example.org/person/some1#self"))

>>> print(person.foaf_name[0])
Some Body

The mechanism for wrapping references as resources cooperates with subclasses. Therefore, accessing referenced resources automatically creates new Item objects:

>>> isinstance(person.foaf_depiction[0], Item)
True

>>> print(person.foaf_depiction[0].rdfs_comment[0])
Just an image

Classes:

  • Resource

    A Resource is a wrapper for a graph and a resource identifier.

__all__ module-attribute

__all__ = ['Resource']

Resource

Resource(graph, subject)

A Resource is a wrapper for a graph and a resource identifier.

Methods:

Attributes:

Source code in rdflib/resource.py
def __init__(self, graph, subject):
    self._graph = graph
    self._identifier = subject

graph property

graph

identifier property

identifier

__eq__

__eq__(other)
Source code in rdflib/resource.py
def __eq__(self, other):
    return (
        isinstance(other, Resource)
        and self._graph == other._graph
        and self._identifier == other._identifier
    )

__ge__

__ge__(other)
Source code in rdflib/resource.py
def __ge__(self, other):
    return not self < other

__getitem__

__getitem__(item)
Source code in rdflib/resource.py
def __getitem__(self, item):
    if isinstance(item, slice):
        if item.step:
            raise TypeError(
                "Resources fix the subject for slicing, and can only be sliced by predicate/object. "
            )
        p, o = item.start, item.stop
        if isinstance(p, Resource):
            p = p._identifier
        if isinstance(o, Resource):
            o = o._identifier
        if p is None and o is None:
            return self.predicate_objects()
        elif p is None:
            return self.predicates(o)
        elif o is None:
            return self.objects(p)
        else:
            return (self.identifier, p, o) in self._graph
    elif isinstance(item, (Node, Path)):
        return self.objects(item)
    else:
        raise TypeError(
            "You can only index a resource by a single rdflib term, a slice of rdflib terms, not %s (%s)"
            % (item, type(item))
        )

__gt__

__gt__(other)
Source code in rdflib/resource.py
def __gt__(self, other):
    return not (self < other or self == other)

__hash__

__hash__()
Source code in rdflib/resource.py
def __hash__(self):
    return hash(Resource) ^ hash(self._graph) ^ hash(self._identifier)

__iter__

__iter__()
Source code in rdflib/resource.py
def __iter__(self):
    return self._resource_triples(
        self._graph.triples((self.identifier, None, None))
    )

__le__

__le__(other)
Source code in rdflib/resource.py
def __le__(self, other):
    return self < other or self == other

__lt__

__lt__(other)
Source code in rdflib/resource.py
def __lt__(self, other):
    if isinstance(other, Resource):
        return self._identifier < other._identifier
    else:
        return False

__ne__

__ne__(other)
Source code in rdflib/resource.py
def __ne__(self, other):
    return not self == other

__repr__

__repr__()
Source code in rdflib/resource.py
def __repr__(self):
    return "Resource(%s,%s)" % (self._graph, self._identifier)

__setitem__

__setitem__(item, value)
Source code in rdflib/resource.py
def __setitem__(self, item, value):
    self.set(item, value)

__str__

__str__()
Source code in rdflib/resource.py
def __str__(self):
    return "Resource(%s)" % self._identifier

__unicode__

__unicode__()
Source code in rdflib/resource.py
def __unicode__(self):
    return str(self._identifier)

add

add(p, o)
Source code in rdflib/resource.py
def add(self, p, o):
    if isinstance(o, Resource):
        o = o._identifier

    self._graph.add((self._identifier, p, o))

items

items()
Source code in rdflib/resource.py
def items(self):
    return self._resources(self._graph.items(self._identifier))

objects

objects(predicate=None)
Source code in rdflib/resource.py
def objects(self, predicate=None):
    return self._resources(self._graph.objects(self._identifier, predicate))

predicate_objects

predicate_objects()
Source code in rdflib/resource.py
def predicate_objects(self):
    return self._resource_pairs(self._graph.predicate_objects(self._identifier))

predicates

predicates(o=None)
Source code in rdflib/resource.py
def predicates(self, o=None):
    if isinstance(o, Resource):
        o = o._identifier

    return self._resources(self._graph.predicates(self._identifier, o))

qname

qname()
Source code in rdflib/resource.py
def qname(self):
    return self._graph.qname(self._identifier)

remove

remove(p, o=None)
Source code in rdflib/resource.py
def remove(self, p, o=None):
    if isinstance(o, Resource):
        o = o._identifier

    self._graph.remove((self._identifier, p, o))

set

set(p, o)
Source code in rdflib/resource.py
def set(self, p, o):
    if isinstance(o, Resource):
        o = o._identifier

    self._graph.set((self._identifier, p, o))

subject_objects

subject_objects()
Source code in rdflib/resource.py
def subject_objects(self):
    return self._resource_pairs(self._graph.subject_objects(self._identifier))

subject_predicates

subject_predicates()
Source code in rdflib/resource.py
def subject_predicates(self):
    return self._resource_pairs(self._graph.subject_predicates(self._identifier))

subjects

subjects(predicate=None)
Source code in rdflib/resource.py
def subjects(self, predicate=None):  # rev
    return self._resources(self._graph.subjects(predicate, self._identifier))

transitive_objects

transitive_objects(predicate, remember=None)
Source code in rdflib/resource.py
def transitive_objects(self, predicate, remember=None):
    return self._resources(
        self._graph.transitive_objects(self._identifier, predicate, remember)
    )

transitive_subjects

transitive_subjects(predicate, remember=None)
Source code in rdflib/resource.py
def transitive_subjects(self, predicate, remember=None):
    return self._resources(
        self._graph.transitive_subjects(predicate, self._identifier, remember)
    )

value

value(p=value, o=None, default=None, any=True)
Source code in rdflib/resource.py
def value(self, p=RDF.value, o=None, default=None, any=True):
    if isinstance(o, Resource):
        o = o._identifier

    return self._cast(self._graph.value(self._identifier, p, o, default, any))