Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/developers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ here, we will not reject a PR just because it does not.

Tests
-----
Any new functionality being added to RDFLib _must_ have unit tests and
Any new functionality being added to RDFLib *must* have unit tests and
should have doc tests supplied.

Typically, you should add your functionality and new tests to a branch of
Expand Down
18 changes: 11 additions & 7 deletions docs/docs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,15 @@ These docs are generated with Sphinx.
Sphinx makes it very easy to pull in doc-strings from modules,
classes, methods, etc. When writing doc-strings, special reST fields
can be used to annotate parameters, return-types, etc. This makes for
pretty API docs. More information about sphinx can be found `here <https://www.sphinx-doc.org/en/master/usage/restructuredtext/domains.html>`_.
pretty API docs. See `here <https://www.sphinx-doc.org/en/master/usage/restructuredtext/domains.html#info-field-lists>`_
for the Shinx documentation about these fields.

Building
--------

To build you must have the ``sphinx`` and some additional package installed.

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

To install the requirements for building documentation run:

Expand All @@ -26,15 +27,18 @@ To install the requirements for building documentation run:
pip install -r docs/sphinx-requirements.txt


Once you have all the requirements installed you can run this command in the rdflib root directory:
Once you have all the requirements installed you can run this command in the
rdflib root directory:

.. code-block:: bash

python setup.py build_sphinx

Docs will be generated in :file:`build/sphinx/html/` and API documentation, generated from doc-strings, will be placed in :file:`docs/apidocs/`.
Docs will be generated in :file:`build/sphinx/html/` and API documentation,
generated from doc-strings, will be placed in :file:`docs/apidocs/`.

There is also a `tox <https://tox.wiki/en/latest/>`_ environment for building documentation:
There is also a `tox <https://tox.wiki/en/latest/>`_ environment for building
documentation:

.. code-block:: bash

Expand Down
6 changes: 3 additions & 3 deletions docs/gettingstarted.rst
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,13 @@ who hasn't worked with RDF before.*
The primary interface that RDFLib exposes for working with RDF is a
:class:`~rdflib.graph.Graph`.

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

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

.. code-block:: text
Expand Down
35 changes: 5 additions & 30 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,19 @@ RDFLib is a pure Python package for working with `RDF <http://www.w3.org/RDF/>`_

* **Parsers & Serializers**

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


* **Store implementations**

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

* **Graph interface**

* to a single graph
* or a conjunctive graph (multiple Named Graphs)
* or a dataset of graphs
* or to multiple Named Graphs within a dataset

* **SPARQL 1.1 implementation**

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

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>`_.



Glossary
--------

Here are a few RDF and Python terms referred to in this documentation. They are linked to wherever they occur.

.. glossary::

functional property
Properties than can only occur once for a resource, i.e. for any relation (triple, in RDF) ``x p y``,
if ``p`` is functional, for any individual ``x``, there can be at most one individual ``y``.

OWL
The OWL 2 Web Ontology Language, informally OWL 2 or just OWL, is an ontology language for the Semantic Web
with formally defined meaning. OWL 2 ontologies provide classes, properties, individuals, and data values and
are stored as Semantic Web documents. OWL 2 ontologies can be used along with information written in RDF, and
OWL 2 ontologies themselves are primarily exchanged as RDF documents. See the `RDF 1.1 Concepts and Abstract
Syntax <https://www.w3.org/TR/rdf11-concepts/>`_ for more info.

RDF
The Resource Description Framework (RDF) is a framework for representing information in the Web. RDF data is
stored in graphs that are sets of subject-predicate-object triples, where the elements may be IRIs, blank nodes,
or datatyped literals. See the `OWL 2 Web Ontology Language
Document Overview <http://www.w3.org/TR/owl-overview/>`_ for more info.
111 changes: 88 additions & 23 deletions docs/namespaces_and_bindings.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,37 +10,103 @@ The :mod:`rdflib.namespace` defines the :class:`rdflib.namespace.Namespace` clas

from rdflib import Namespace

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

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

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).
These two styles of namespace creation - object attribute and dict - are equivalent and are made available just to allow for valid
RDF namespaces and URIs that are not valid Python identifiers. This isn't just for syntactic things like spaces, as per
the example of ``first%20name`` above, but also for Python reserved words like ``class`` or ``while``, so for the URI
``http://example.org/class``, create it with ``EX['class']``, not ``EX.class``.

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

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.
The ``namespace`` module defines many common namespaces such as RDF, RDFS, OWL, FOAF, SKOS, PROF, etc. The list of the
namespaces provided grows with user contributions to RDFLib.

NamespaceManager
----------------
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/``.

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::

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::
from rdflib import Graph, Namespace
from rdflib.namespace import FOAF

EX = Namespace("http://example.org/")

g = Graph()
g.bind("foaf", FOAF) # bind an RDFLib-provided namespace to a prefix
g.bind("ex", EX) # bind a user-declared namespace to a prefix


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

It has a method to normalize a given url :
NamespaceManager
----------------

myGraph.namespace_manager.normalizeUri(t)
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,
as above, however note that the `NamespaceManager` automatically performs some bindings according to a selected strategy.

Namespace binding strategies are indicated with the `bind_namespaces` input parameter to `NamespaceManager` instances
and may be set via ``Graph`` also::

from rdflib import Graph
from rdflib.namespace import NamespaceManager

g = Graph(bind_namespaces="rdflib") # bind via Graph

g2 = Graph()
nm = NamespaceManager(g2, bind_namespaces="rdflib") # bind via NamespaceManager


Valid strategies are:

* core:
* binds several core RDF prefixes only
* owl, rdf, rdfs, xsd, xml from the NAMESPACE_PREFIXES_CORE object
* this is default
* rdflib:
* binds all the namespaces shipped with RDFLib as DefinedNamespace instances
* all the core namespaces and all the following: brick, csvw, dc, dcat
* dcmitype, cdterms, dcam, doap, foaf, geo, odrl, org, prof, prov, qb, sdo
* sh, skos, sosa, ssn, time, vann, void
* see the NAMESPACE_PREFIXES_RDFLIB object in :class:`rdflib.namespace` for up-to-date list
* none:
* binds no namespaces to prefixes
* note this is NOT default behaviour
* cc:
* using prefix bindings from prefix.cc which is a online prefixes database
* not implemented yet - this is aspirational

Re-binding
^^^^^^^^^^

Note that regardless of the strategy employed, prefixes for namespaces can be overwritten with users preferred prefixes,
for example::

from rdflib import Graph
from rdflib.namespace import GEO # imports GeoSPARQL's namespace

g = Graph(bind_namespaces="rdflib") # binds GeoSPARQL's namespace to prefix 'geo'

g.bind('geosp', GEO, override=True)



`NamespaceManager` also has a method to normalize a given url::

from rdflib.namespace import NamespaceManager

nm = NamespaceManager(Graph())
nm.normalizeUri(t)


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

>>> from rdflib import Graph, URIRef, Literal, BNode
>>> from rdflib.namespace import FOAF, NamespaceManager
Expand All @@ -59,16 +125,15 @@ N3 format::
>>> l.n3()
'"2"^^<http://www.w3.org/2001/XMLSchema#integer>'

>>> l.n3(g.namespace_manager)
>>> l.n3(NamespaceManager(Graph(), bind_namespaces="core"))
'"2"^^xsd:integer'

The namespace manage also has a useful method compute_qname
g.namespace_manager.compute_qname(x) which takes an url and decomposes it into the parts::
The namespace manage also has a useful method ``compute_qname``
``g.namespace_manager.compute_qname(x)`` (or just ``g.compute_qname(x)``) which takes a URI and decomposes it into the parts::

self.assertEqual(g.compute_qname(URIRef("http://foo/bar#baz")),
("ns2", URIRef("http://foo/bar#"), "baz"))

__ http://rdflib.net/rdflib-2.4.0/html/public/rdflib.syntax.NamespaceManager.NamespaceManager-class.html


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

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


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:
Expand Down
Loading