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 ` and the :mod:`Query syntax trees (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 ` command, checked and extended by the :class:`Graph `, and ultimately stored by a :class:`Triple Store backend `. 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 ` defines the URI base class, :class:`Namespace ` provides shortcuts to generate URIs, and :mod:`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 ` manages the graph as a whole, and offers methods to get a specific set of Nodes. In turn, the :class:`Nodes class ` 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 ` 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/