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