Mercurial > repos > shellac > sam_consensus_v3
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 & 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 |