aboutsummaryrefslogtreecommitdiffstats
path: root/doc/source/architecture.rst
blob: 4cca49a80d90721d09f75aaea7347873e97dde52 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87

Architecture
============

The BSFS stack can be coarsely divided into four parts (see the image below).

* Envelope: Essentials and utils used throughout the whole codebase.
* Front: End-user applications and APIs.
* Center: The core interfaces and functionality.
* Back: The triple store backends.

Details of these components are given in the sections below.


.. image:: _static/arch_light.png
   :class: only-light

.. image:: _static/arch_dark.png
   :class: only-dark


Envelope
--------

Most notably, the envelope covers the :class:`Schema <bsfs.schema.schema.Schema>` and the :mod:`Query syntax trees (AST) <bsfs.query.ast>`.
Both of them essential for all parts of the BSFS stack.
For example, the schema is specified by the user via the :func:`Migrate <bsfs.apps.migrate.main>` command, checked and extended by the :class:`Graph <bsfs.graph.graph.Graph>`, and ultimately stored by a :class:`Triple Store backend <bsfs.triple_store.base.TripleStoreBase>`.
Similarly, the Query AST may be provided by a caller and is translated to a database query by a backend.
In addition, the envelope also contains some classes to handle URIs: 
:class:`URI <bsfs.utils.uri.URI>` defines the URI base class,
:class:`Namespace <bsfs.namespace.Namespace>` provides shortcuts to generate URIs, and
:mod:`UUID <bsfs.utils.uuid>` is used to generate unique URIs.


Front
-----

The front consists of exposed interfaces such as end-user applications or APIs,
and all utils needed to offer this functionality.
See :mod:`bsfs.apps` and :mod:`bsfs.front`.


Center
------

The heart of BSFS is grouped around the :mod:`bsfs.graph` module.
These classes provide the interface to navigate and manipulate the file graph
in a safe and programmer friendly manner.
Some of them are indirectly exposed through the higher-level APIs.

The two core design principles of BSFS are the focus on nodes and batch processing.
They are realized in the the Graph and Nodes classes.
The :class:`Graph class <bsfs.graph.graph.Graph>` manages the graph as a whole,
and offers methods to get a specific set of Nodes.
In turn, the :class:`Nodes class <bsfs.graph.nodes.Nodes>` represents such a set of nodes,
and performs operations on the whole node set at once.
Besides, the :mod:`bsfs.graph` module also comes with some syntactic sugar.

Example::

    # Open a file graph.
    from bsfs import Open, ns
    graph = Open(...)
    # Get all nodes of type File.
    nodes = graph.all(ns.bsfs.File)
    # Set the author of all nodes at once.
    nodes.set(ns.bse.author, 'Myself')
    # Retrieve the author of all nodes at once.
    set(nodes.get(ns.bse.author, node=False))
    # Same as above, but shorter.
    set(nodes.comment(node=False))


Back
----

There are various graph databases (e.g., `RDFLib`_, `Blazegraph`_, `Titan`_, etc.)
and it would be foolish to replicate the work that others have done.
Instead, we use third-party stores that take care of how to store and manage the data.
The :class:`Backend base class <bsfs.triple_store.base.TripleStoreBase>` defines the
interface to integrate any such third-party store to BSFS.
Besides storing the data, a triple store backend also need to track the current schema.


.. _RDFLib: https://rdflib.readthedocs.io/en/stable/index.html
.. _Blazegraph: https://blazegraph.com/
.. _Titan: http://titan.thinkaurelius.com/