comparison env/lib/python3.9/site-packages/rdflib/extras/describer.py @ 0:4f3585e2f14b draft default tip

"planemo upload commit 60cee0fc7c0cda8592644e1aad72851dec82c959"
author shellac
date Mon, 22 Mar 2021 18:12:50 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:4f3585e2f14b
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3 from __future__ import absolute_import
4 from __future__ import division
5 from __future__ import print_function
6
7
8 __doc__ = """
9 A Describer is a stateful utility for creating RDF statements in a
10 semi-declarative manner. It has methods for creating literal values, rel and
11 rev resource relations (somewhat resembling RDFa).
12
13 The `rel` and ``rev`` methods return a context manager which sets the current
14 about to the referenced resource for the context scope (for use with the
15 ``with`` statement).
16
17 Full example in the ``to_rdf`` method below::
18
19 >>> import datetime
20 >>> from rdflib.graph import Graph
21 >>> from rdflib.namespace import Namespace, RDFS, FOAF
22 >>>
23 >>> ORG_URI = "http://example.org/"
24 >>>
25 >>> CV = Namespace("http://purl.org/captsolo/resume-rdf/0.2/cv#")
26 >>>
27 >>> class Person(object):
28 ... def __init__(self):
29 ... self.first_name = u"Some"
30 ... self.last_name = u"Body"
31 ... self.username = "some1"
32 ... self.presentation = u"Just a Python & RDF hacker."
33 ... self.image = "/images/persons/" + self.username + ".jpg"
34 ... self.site = "http://example.net/"
35 ... self.start_date = datetime.date(2009, 9, 4)
36 ... def get_full_name(self):
37 ... return u" ".join([self.first_name, self.last_name])
38 ... def get_absolute_url(self):
39 ... return "/persons/" + self.username
40 ... def get_thumbnail_url(self):
41 ... return self.image.replace('.jpg', '-thumb.jpg')
42 ...
43 ... def to_rdf(self):
44 ... graph = Graph()
45 ... graph.bind('foaf', FOAF)
46 ... graph.bind('cv', CV)
47 ... lang = 'en'
48 ... d = Describer(graph, base=ORG_URI)
49 ... d.about(self.get_absolute_url()+'#person')
50 ... d.rdftype(FOAF.Person)
51 ... d.value(FOAF.name, self.get_full_name())
52 ... d.value(FOAF.givenName, self.first_name)
53 ... d.value(FOAF.familyName, self.last_name)
54 ... d.rel(FOAF.homepage, self.site)
55 ... d.value(RDFS.comment, self.presentation, lang=lang)
56 ... with d.rel(FOAF.depiction, self.image):
57 ... d.rdftype(FOAF.Image)
58 ... d.rel(FOAF.thumbnail, self.get_thumbnail_url())
59 ... with d.rev(CV.aboutPerson):
60 ... d.rdftype(CV.CV)
61 ... with d.rel(CV.hasWorkHistory):
62 ... d.value(CV.startDate, self.start_date)
63 ... d.rel(CV.employedIn, ORG_URI+"#company")
64 ... return graph
65 ...
66 >>> person_graph = Person().to_rdf()
67 >>> expected = Graph().parse(data='''<?xml version="1.0" encoding="utf-8"?>
68 ... <rdf:RDF
69 ... xmlns:foaf="http://xmlns.com/foaf/0.1/"
70 ... xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
71 ... xmlns:cv="http://purl.org/captsolo/resume-rdf/0.2/cv#"
72 ... xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#">
73 ... <foaf:Person rdf:about="http://example.org/persons/some1#person">
74 ... <foaf:name>Some Body</foaf:name>
75 ... <foaf:givenName>Some</foaf:givenName>
76 ... <foaf:familyName>Body</foaf:familyName>
77 ... <foaf:depiction>
78 ... <foaf:Image
79 ... rdf:about=
80 ... "http://example.org/images/persons/some1.jpg">
81 ... <foaf:thumbnail
82 ... rdf:resource=
83 ... "http://example.org/images/persons/some1-thumb.jpg"/>
84 ... </foaf:Image>
85 ... </foaf:depiction>
86 ... <rdfs:comment xml:lang="en">
87 ... Just a Python &amp; RDF hacker.
88 ... </rdfs:comment>
89 ... <foaf:homepage rdf:resource="http://example.net/"/>
90 ... </foaf:Person>
91 ... <cv:CV>
92 ... <cv:aboutPerson
93 ... rdf:resource="http://example.org/persons/some1#person">
94 ... </cv:aboutPerson>
95 ... <cv:hasWorkHistory>
96 ... <rdf:Description>
97 ... <cv:startDate
98 ... rdf:datatype="http://www.w3.org/2001/XMLSchema#date"
99 ... >2009-09-04</cv:startDate>
100 ... <cv:employedIn rdf:resource="http://example.org/#company"/>
101 ... </rdf:Description>
102 ... </cv:hasWorkHistory>
103 ... </cv:CV>
104 ... </rdf:RDF>
105 ... ''')
106 >>>
107 >>> from rdflib.compare import isomorphic
108 >>> isomorphic(person_graph, expected) #doctest: +SKIP
109 True
110 """
111
112 from contextlib import contextmanager
113 from rdflib.graph import Graph
114 from rdflib.namespace import RDF
115 from rdflib.term import BNode
116 from rdflib.term import Identifier
117 from rdflib.term import Literal
118 from rdflib.term import URIRef
119
120
121 class Describer(object):
122
123 def __init__(self, graph=None, about=None, base=None):
124 if graph is None:
125 graph = Graph()
126 self.graph = graph
127 self.base = base
128 self._subjects = []
129 self.about(about or None)
130
131 def about(self, subject, **kws):
132 """
133 Sets the current subject. Will convert the given object into an
134 ``URIRef`` if it's not an ``Identifier``.
135
136 Usage::
137
138 >>> d = Describer()
139 >>> d._current() #doctest: +ELLIPSIS
140 rdflib.term.BNode(...)
141 >>> d.about("http://example.org/")
142 >>> d._current()
143 rdflib.term.URIRef(u'http://example.org/')
144
145 """
146 kws.setdefault('base', self.base)
147 subject = cast_identifier(subject, **kws)
148 if self._subjects:
149 self._subjects[-1] = subject
150 else:
151 self._subjects.append(subject)
152
153 def value(self, p, v, **kws):
154 """
155 Set a literal value for the given property. Will cast the value to an
156 ``Literal`` if a plain literal is given.
157
158 Usage::
159
160 >>> from rdflib import URIRef
161 >>> from rdflib.namespace import RDF, RDFS
162 >>> d = Describer(about="http://example.org/")
163 >>> d.value(RDFS.label, "Example")
164 >>> d.graph.value(URIRef('http://example.org/'), RDFS.label)
165 rdflib.term.Literal(u'Example')
166
167 """
168 v = cast_value(v, **kws)
169 self.graph.add((self._current(), p, v))
170
171 def rel(self, p, o=None, **kws):
172 """Set an object for the given property. Will convert the given object
173 into an ``URIRef`` if it's not an ``Identifier``. If none is given, a
174 new ``BNode`` is used.
175
176 Returns a context manager for use in a ``with`` block, within which the
177 given object is used as current subject.
178
179 Usage::
180
181 >>> from rdflib import URIRef
182 >>> from rdflib.namespace import RDF, RDFS
183 >>> d = Describer(about="/", base="http://example.org/")
184 >>> _ctxt = d.rel(RDFS.seeAlso, "/about")
185 >>> d.graph.value(URIRef('http://example.org/'), RDFS.seeAlso)
186 rdflib.term.URIRef(u'http://example.org/about')
187
188 >>> with d.rel(RDFS.seeAlso, "/more"):
189 ... d.value(RDFS.label, "More")
190 >>> (URIRef('http://example.org/'), RDFS.seeAlso,
191 ... URIRef('http://example.org/more')) in d.graph
192 True
193 >>> d.graph.value(URIRef('http://example.org/more'), RDFS.label)
194 rdflib.term.Literal(u'More')
195
196 """
197
198 kws.setdefault('base', self.base)
199 p = cast_identifier(p)
200 o = cast_identifier(o, **kws)
201 self.graph.add((self._current(), p, o))
202 return self._subject_stack(o)
203
204 def rev(self, p, s=None, **kws):
205 """
206 Same as ``rel``, but uses current subject as *object* of the relation.
207 The given resource is still used as subject in the returned context
208 manager.
209
210 Usage::
211
212 >>> from rdflib import URIRef
213 >>> from rdflib.namespace import RDF, RDFS
214 >>> d = Describer(about="http://example.org/")
215 >>> with d.rev(RDFS.seeAlso, "http://example.net/"):
216 ... d.value(RDFS.label, "Net")
217 >>> (URIRef('http://example.net/'), RDFS.seeAlso,
218 ... URIRef('http://example.org/')) in d.graph
219 True
220 >>> d.graph.value(URIRef('http://example.net/'), RDFS.label)
221 rdflib.term.Literal(u'Net')
222
223 """
224 kws.setdefault('base', self.base)
225 p = cast_identifier(p)
226 s = cast_identifier(s, **kws)
227 self.graph.add((s, p, self._current()))
228 return self._subject_stack(s)
229
230 def rdftype(self, t):
231 """
232 Shorthand for setting rdf:type of the current subject.
233
234 Usage::
235
236 >>> from rdflib import URIRef
237 >>> from rdflib.namespace import RDF, RDFS
238 >>> d = Describer(about="http://example.org/")
239 >>> d.rdftype(RDFS.Resource)
240 >>> (URIRef('http://example.org/'),
241 ... RDF.type, RDFS.Resource) in d.graph
242 True
243
244 """
245 self.graph.add((self._current(), RDF.type, t))
246
247 def _current(self):
248 return self._subjects[-1]
249
250 @contextmanager
251 def _subject_stack(self, subject):
252 self._subjects.append(subject)
253 yield None
254 self._subjects.pop()
255
256
257 def cast_value(v, **kws):
258 if not isinstance(v, Literal):
259 v = Literal(v, **kws)
260 return v
261
262
263 def cast_identifier(ref, **kws):
264 ref = ref or BNode()
265 if not isinstance(ref, Identifier):
266 ref = URIRef(ref, **kws)
267 return ref