This is the operational core of ORDF. In the normal course of events, an application will,
- Instantiate a Handler object, which is usually a singleton.
- Register one or more handler implementations for reading or writing.
- Use the get() and put() methods to respectively retrieve and save Graphs.
- Use context() to save Graphs within the context of a ordf.vocab.changeset.ChangeSet.
See the documentation for HandlerPlugin for how handler the implementation works.
Initialise a handler based on the configuration dictionary. Typically config will be a section of a configuration file parsed with ConfigParser either directly or accessed via pylons.config
The type of handler to be created, the reading and writing plugins and their initialisation arguments can all be specified:
[app:main]
## handler class to use
ordf.handler = ordf.handler.Handler
## if a handler has a connect() method, it is run with arguments
## following. this is used e.g. for ordf.handler.queue.RabbitHandler
ordf.connect.queue = readerqueue
## reader plugins
ordf.readers = pairtree
## writer plugins
ordf.writers = pairtree,fourstore,xapian,rabbit
## arguments for the back-ends
pairtree.args = /some/where/data/pairtree
fourstore.args = kbname,soft_limit=-1
xapian.args = 127.0.0.1:44332
rabbit.connect.exchange = foo
Each storage module added to the handler (as a readoer or as a writer) will have a “handler” attribute set by this function that refers back to the handler. In this way storage/index modules that require access to the handler (currently only FuXiReasoner) have it.
Likewise, the handler will have the name of the storage module set as an attribute. e.g.:
.. code-block:: python
getattr(handler, “xapian”)
will return the instance of the xapian storage module. In this way application code can treat the handler instance as a singleton and access the various back-ends simply. It is then possible to call specialised search or other methods as needed.
Handle reading and writing of RDF Graphs
Storage back-ends are registered to an instance of this class for reading and writing. It distributes read and write (:meth:get and :meth:put) operations over these back ends.
Both the write case and some more complex read operations are intimately tied to the use of ordf.changeset.ChangeSet to which this class is the main entry point - it would be unusual, for example, to create a ChangeSet directly.
## initialise some storage
null_storage = HandlerPlugin()
## create the handler
handler = Handler()
## register the storage
handler.register_reader(null_storage)
handler.register_writer(null_storage)
## a read operation: retrieve a graph from storage
handler.get(graph_identifier)
## a write operation: saving with a change context
ctx = handler.context("username", "change reason")
ctx.add(some_graph)
ctx.commit()
If using the :func:init_handler function instead of constructing the handler by hand (which is recommended) then for each storage module will have a “handler” attribute set by that function that refers back to the handler.
Likewise, the handler will have the name of the storage module set as an attribute. e.g.:
.. code-block:: python
getattr(handler, “xapian”)
will return the instance of the xapian storage module.
Register a writer back-end.
Parameters: |
|
---|
Register a writer back-end.
Parameters are as for :meth:register_reader
Iterates over all of the registered write handlers and calls their get method.
The first back-end to return a non-None value wins and this value is returned.
The get methods are called wwith the given positional and keyword arguments.
Iterates over all of the registered write handlers and calls their put method.
The put methods are called with the given positional and keyword arguments.
Return an instance of :class:ChangeContext bound to this handler
Parameters: |
|
---|
return the history of the graph
Parameters: | identifier – a Graph or identifier |
---|---|
Returns: | generator of changesets for the given graph, most recent first. Values yielded by the generator will be either instances of :class:ordf.changeset.ChangeSet or lists in the case of multiple parents. This latter is not well tested. |
Instances of this class implement read and/or write operations on storage and indices.
This is an interface specification for subclassing and null implementation.
The :meth:find class method is used to create handler implementations that may live in various modules. To do this it makes use of the pkg_resources.EntryPoint mechanism. For example, looking at ORDF’s setup.py you can find the entrypoints for the handler implementations that are bundled with this software:
[ordf.handler]
pairtree=ordf.handler.pt:PairTree
rdflib=ordf.handler.rdf:RDFLib
fourstore=ordf.handler.rdf:FourStore
xapian=ordf.handler.xap:Xapian
rabbit=ordf.handler.queue:Rabbit
Search in the pkg_resources.EntryPoint named [ordf.handler] for a concrete subclass implementing this interface.
Parameters: | name – the name of the plugin to find |
---|
If a result is found but is not a subclass of HandlerPlugin a ValueError is raised. If no result is found, an ImportError is raised.
Takes care of constructing changesets and distributes the results
Not to be instantiated directly. Returned from the Handler.context() method.
Typical usage:
ctx = handler.context(...)
ctx.add(graph)
ctx.add(another)
ctx.commit()
Commit any pending changes in this context and distribute them via the handler.
This method actually constructs the ordf.changeset.ChangeSet instance. This ChangeSet is initialised with any positional and keyword arguments that were passed to the present class on creation.
It then iterates over any graphs that have been added with :meth:add and requests the previous version from the Handler.get(). The differences between the previous and current versions are added to the changeset.
Now, ChangeSet in hand, we call the Handler.put() for the changeset and then for each of the new versions of the graphs in turn.