Skip to content

Commit b5ec096

Browse files
author
Nicholas Car
authored
Merge pull request #1686 from RDFLib/default_prefixes
Bind prefixes choices
2 parents f014e98 + 808aa09 commit b5ec096

File tree

16 files changed

+467
-187
lines changed

16 files changed

+467
-187
lines changed

docs/developers.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ here, we will not reject a PR just because it does not.
6969

7070
Tests
7171
-----
72-
Any new functionality being added to RDFLib _must_ have unit tests and
72+
Any new functionality being added to RDFLib *must* have unit tests and
7373
should have doc tests supplied.
7474

7575
Typically, you should add your functionality and new tests to a branch of

docs/docs.rst

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,15 @@ These docs are generated with Sphinx.
1010
Sphinx makes it very easy to pull in doc-strings from modules,
1111
classes, methods, etc. When writing doc-strings, special reST fields
1212
can be used to annotate parameters, return-types, etc. This makes for
13-
pretty API docs. More information about sphinx can be found `here <https://www.sphinx-doc.org/en/master/usage/restructuredtext/domains.html>`_.
13+
pretty API docs. See `here <https://www.sphinx-doc.org/en/master/usage/restructuredtext/domains.html#info-field-lists>`_
14+
for the Shinx documentation about these fields.
1415

1516
Building
1617
--------
1718

18-
To build you must have the ``sphinx`` and some additional package installed.
19-
20-
The documentation's full set of requirements is listed in the ``sphinx-requirements.txt`` file within the :file:`docs/` directory.
19+
To build you must have the ``sphinx`` and some additional package installed.
20+
The full set of requirements is listed in the ``sphinx-requirements.txt`` file
21+
within the :file:`docs/` directory.
2122

2223
To install the requirements for building documentation run:
2324

@@ -26,15 +27,18 @@ To install the requirements for building documentation run:
2627
pip install -r docs/sphinx-requirements.txt
2728
2829
29-
Once you have all the requirements installed you can run this command in the rdflib root directory:
30+
Once you have all the requirements installed you can run this command in the
31+
rdflib root directory:
3032

3133
.. code-block:: bash
3234
3335
python setup.py build_sphinx
3436
35-
Docs will be generated in :file:`build/sphinx/html/` and API documentation, generated from doc-strings, will be placed in :file:`docs/apidocs/`.
37+
Docs will be generated in :file:`build/sphinx/html/` and API documentation,
38+
generated from doc-strings, will be placed in :file:`docs/apidocs/`.
3639

37-
There is also a `tox <https://tox.wiki/en/latest/>`_ environment for building documentation:
40+
There is also a `tox <https://tox.wiki/en/latest/>`_ environment for building
41+
documentation:
3842

3943
.. code-block:: bash
4044

docs/gettingstarted.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,13 @@ who hasn't worked with RDF before.*
4545
The primary interface that RDFLib exposes for working with RDF is a
4646
:class:`~rdflib.graph.Graph`.
4747

48-
RDFLib graphs are un-sorted containers; they have ordinary ``set``
48+
RDFLib graphs are un-sorted containers; they have ordinary Python ``set``
4949
operations (e.g. :meth:`~rdflib.Graph.add` to add a triple) plus
5050
methods that search triples and return them in arbitrary order.
5151

5252
RDFLib graphs also redefine certain built-in Python methods in order
53-
to behave in a predictable way: they `emulate container types
54-
<http://docs.python.org/release/2.5.2/ref/sequence-types.html>`_ and
53+
to behave in a predictable way. They do this by `emulating container types
54+
<https://docs.python.org/3.7/reference/datamodel.html#emulating-container-types>`_ and
5555
are best thought of as a set of 3-item tuples ("triples", in RDF-speak):
5656

5757
.. code-block:: text

docs/index.rst

Lines changed: 5 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,19 @@ RDFLib is a pure Python package for working with `RDF <http://www.w3.org/RDF/>`_
88

99
* **Parsers & Serializers**
1010

11-
* for RDF/XML, N3, NTriples, N-Quads, Turtle, TriX, JSON-LD, RDFa and Microdata
11+
* for RDF/XML, N3, NTriples, N-Quads, Turtle, TriX, JSON-LD, HexTuples, RDFa and Microdata
1212

1313

1414
* **Store implementations**
1515

16-
* for in-memory and persistent RDF storage, including remote SPARQL endpoints
16+
* memory stores
17+
* persistent, on-disk stores, using databases such as BerkeleyDB
18+
* remote SPARQL endpoints
1719

1820
* **Graph interface**
1921

2022
* to a single graph
21-
* or a conjunctive graph (multiple Named Graphs)
22-
* or a dataset of graphs
23+
* or to multiple Named Graphs within a dataset
2324

2425
* **SPARQL 1.1 implementation**
2526

@@ -108,29 +109,3 @@ the tag ``[rdflib]``. A list of existing ``[rdflib]`` tagged questions is kept t
108109
You might also like to join rdflib's dev mailing list: `<https://groups.google.com/group/rdflib-dev>`__
109110

110111
The chat is available at `gitter <https://gitter.im/RDFLib/rdflib>`_ or via matrix `#RDFLib_rdflib:gitter.im <https://matrix.to/#/#RDFLib_rdflib:gitter.im>`_.
111-
112-
113-
114-
Glossary
115-
--------
116-
117-
Here are a few RDF and Python terms referred to in this documentation. They are linked to wherever they occur.
118-
119-
.. glossary::
120-
121-
functional property
122-
Properties than can only occur once for a resource, i.e. for any relation (triple, in RDF) ``x p y``,
123-
if ``p`` is functional, for any individual ``x``, there can be at most one individual ``y``.
124-
125-
OWL
126-
The OWL 2 Web Ontology Language, informally OWL 2 or just OWL, is an ontology language for the Semantic Web
127-
with formally defined meaning. OWL 2 ontologies provide classes, properties, individuals, and data values and
128-
are stored as Semantic Web documents. OWL 2 ontologies can be used along with information written in RDF, and
129-
OWL 2 ontologies themselves are primarily exchanged as RDF documents. See the `RDF 1.1 Concepts and Abstract
130-
Syntax <https://www.w3.org/TR/rdf11-concepts/>`_ for more info.
131-
132-
RDF
133-
The Resource Description Framework (RDF) is a framework for representing information in the Web. RDF data is
134-
stored in graphs that are sets of subject-predicate-object triples, where the elements may be IRIs, blank nodes,
135-
or datatyped literals. See the `OWL 2 Web Ontology Language
136-
Document Overview <http://www.w3.org/TR/owl-overview/>`_ for more info.

docs/namespaces_and_bindings.rst

Lines changed: 88 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -10,37 +10,103 @@ The :mod:`rdflib.namespace` defines the :class:`rdflib.namespace.Namespace` clas
1010

1111
from rdflib import Namespace
1212

13-
n = Namespace("http://example.org/")
14-
n.Person # as attribute
15-
# = rdflib.term.URIRef("http://example.org/Person")
13+
EX = Namespace("http://example.org/")
14+
EX.Person # a Python attribute for EX. This example is equivalent to rdflib.term.URIRef("http://example.org/Person")
1615

17-
n['first%20name'] # as item - for things that are not valid python identifiers
18-
# = rdflib.term.URIRef("http://example.org/first%20name")
16+
# use dict notation for things that are not valid Python identifiers, e.g.:
17+
n['first%20name'] # as rdflib.term.URIRef("http://example.org/first%20name")
1918

20-
Note that if a name string is valid for use in an RDF namespace but not valid as a Python identifier, such as '1234', it must be addressed with the "item" syntax (using the "attribute" syntax will raise a Syntax Error).
19+
These two styles of namespace creation - object attribute and dict - are equivalent and are made available just to allow for valid
20+
RDF namespaces and URIs that are not valid Python identifiers. This isn't just for syntactic things like spaces, as per
21+
the example of ``first%20name`` above, but also for Python reserved words like ``class`` or ``while``, so for the URI
22+
``http://example.org/class``, create it with ``EX['class']``, not ``EX.class``.
2123

22-
The ``namespace`` module also defines many common namespaces such as RDF, RDFS, OWL, FOAF, SKOS, PROF, etc.
24+
Common Namespaces
25+
-----------------
2326

24-
Namespaces can also be associated with prefixes, in a :class:`rdflib.namespace.NamespaceManager`, i.e. using ``foaf`` for ``http://xmlns.com/foaf/0.1/``. Each RDFLib graph has a :attr:`~rdflib.graph.Graph.namespace_manager` that keeps a list of namespace to prefix mappings. The namespace manager is populated when reading in RDF, and these prefixes are used when serialising RDF, or when parsing SPARQL queries. Additional prefixes can be bound with the :meth:`rdflib.graph.bind` method.
27+
The ``namespace`` module defines many common namespaces such as RDF, RDFS, OWL, FOAF, SKOS, PROF, etc. The list of the
28+
namespaces provided grows with user contributions to RDFLib.
2529

26-
NamespaceManager
27-
----------------
30+
These Namespaces, and any others that users define, can also be associated with prefixes using the :class:`rdflib.namespace.NamespaceManager`, e.g. using ``foaf`` for ``http://xmlns.com/foaf/0.1/``.
2831

32+
Each RDFLib graph has a :attr:`~rdflib.graph.Graph.namespace_manager` that keeps a list of namespace to prefix mappings. The namespace manager is populated when reading in RDF, and these prefixes are used when serialising RDF, or when parsing SPARQL queries. Prefixes can be bound with the :meth:`rdflib.graph.bind` method::
2933

30-
Each graph comes with a `NamespaceManager`__ instance in the `namespace_manager` field; you can use the `bind` method of this instance to bind a prefix to a namespace URI::
34+
from rdflib import Graph, Namespace
35+
from rdflib.namespace import FOAF
36+
37+
EX = Namespace("http://example.org/")
38+
39+
g = Graph()
40+
g.bind("foaf", FOAF) # bind an RDFLib-provided namespace to a prefix
41+
g.bind("ex", EX) # bind a user-declared namespace to a prefix
42+
3143

32-
myGraph.namespace_manager.bind('prefix', URIRef('scheme:my-namespace-uri:'))
33-
myGraph.namespace_manager.bind('owl', OWL_NS, override=False)
44+
The :meth:`rdflib.graph.bind` method is actually supplied by the :class:`rdflib.namespace.NamespaceManager` class - see next.
3445

35-
It has a method to normalize a given url :
46+
NamespaceManager
47+
----------------
3648

37-
myGraph.namespace_manager.normalizeUri(t)
49+
Each RDFLib graph comes with a :class:`rdflib.namespace.NamespaceManager` instance in the `namespace_manager` field; you can use the `bind` method of this instance to bind a prefix to a namespace URI,
50+
as above, however note that the `NamespaceManager` automatically performs some bindings according to a selected strategy.
51+
52+
Namespace binding strategies are indicated with the `bind_namespaces` input parameter to `NamespaceManager` instances
53+
and may be set via ``Graph`` also::
54+
55+
from rdflib import Graph
56+
from rdflib.namespace import NamespaceManager
57+
58+
g = Graph(bind_namespaces="rdflib") # bind via Graph
59+
60+
g2 = Graph()
61+
nm = NamespaceManager(g2, bind_namespaces="rdflib") # bind via NamespaceManager
62+
63+
64+
Valid strategies are:
65+
66+
* core:
67+
* binds several core RDF prefixes only
68+
* owl, rdf, rdfs, xsd, xml from the NAMESPACE_PREFIXES_CORE object
69+
* this is default
70+
* rdflib:
71+
* binds all the namespaces shipped with RDFLib as DefinedNamespace instances
72+
* all the core namespaces and all the following: brick, csvw, dc, dcat
73+
* dcmitype, cdterms, dcam, doap, foaf, geo, odrl, org, prof, prov, qb, sdo
74+
* sh, skos, sosa, ssn, time, vann, void
75+
* see the NAMESPACE_PREFIXES_RDFLIB object in :class:`rdflib.namespace` for up-to-date list
76+
* none:
77+
* binds no namespaces to prefixes
78+
* note this is NOT default behaviour
79+
* cc:
80+
* using prefix bindings from prefix.cc which is a online prefixes database
81+
* not implemented yet - this is aspirational
82+
83+
Re-binding
84+
^^^^^^^^^^
85+
86+
Note that regardless of the strategy employed, prefixes for namespaces can be overwritten with users preferred prefixes,
87+
for example::
88+
89+
from rdflib import Graph
90+
from rdflib.namespace import GEO # imports GeoSPARQL's namespace
91+
92+
g = Graph(bind_namespaces="rdflib") # binds GeoSPARQL's namespace to prefix 'geo'
93+
94+
g.bind('geosp', GEO, override=True)
95+
96+
97+
98+
`NamespaceManager` also has a method to normalize a given url::
99+
100+
from rdflib.namespace import NamespaceManager
101+
102+
nm = NamespaceManager(Graph())
103+
nm.normalizeUri(t)
38104

39105

40106
For simple output, or simple serialisation, you often want a nice
41-
readable representation of a term. All terms have a
42-
``.n3(namespace_manager = None)`` method, which will return a suitable
43-
N3 format::
107+
readable representation of a term. All RDFLib terms have a
108+
``.n3()`` method, which will return a suitable N3 format and into which you can supply a NamespaceManager instance
109+
to provide prefixes, i.e. ``.n3(namespace_manager=some_nm)``::
44110

45111
>>> from rdflib import Graph, URIRef, Literal, BNode
46112
>>> from rdflib.namespace import FOAF, NamespaceManager
@@ -59,16 +125,15 @@ N3 format::
59125
>>> l.n3()
60126
'"2"^^<http://www.w3.org/2001/XMLSchema#integer>'
61127
62-
>>> l.n3(g.namespace_manager)
128+
>>> l.n3(NamespaceManager(Graph(), bind_namespaces="core"))
63129
'"2"^^xsd:integer'
64130
65-
The namespace manage also has a useful method compute_qname
66-
g.namespace_manager.compute_qname(x) which takes an url and decomposes it into the parts::
131+
The namespace manage also has a useful method ``compute_qname``
132+
``g.namespace_manager.compute_qname(x)`` (or just ``g.compute_qname(x)``) which takes a URI and decomposes it into the parts::
67133

68134
self.assertEqual(g.compute_qname(URIRef("http://foo/bar#baz")),
69135
("ns2", URIRef("http://foo/bar#"), "baz"))
70136
71-
__ http://rdflib.net/rdflib-2.4.0/html/public/rdflib.syntax.NamespaceManager.NamespaceManager-class.html
72137

73138

74139
Namespaces in SPARQL Queries
@@ -78,7 +143,7 @@ The ``initNs`` argument supplied to :meth:`~rdflib.graph.Graph.query` is a dicti
78143
If you pass no ``initNs`` argument, the namespaces registered with the graphs namespace_manager are used::
79144

80145
from rdflib.namespace import FOAF
81-
graph.query('SELECT * WHERE { ?p a foaf:Person }', initNs={ 'foaf': FOAF })
146+
graph.query('SELECT * WHERE { ?p a foaf:Person }', initNs={'foaf': FOAF})
82147

83148

84149
In order to use an empty prefix (e.g. ``?a :knows ?b``), use a ``PREFIX`` directive with no prefix in the SPARQL query to set a default namespace:

0 commit comments

Comments
 (0)