API¶
Introduction¶
This part of the documentation covers the the interface for creating an searching graphs using the fornax package. For the full documentation of the module api see fornax.api module.
All of the functionality in fornax
can be accessed via the follwoing three classes.
Connection
is used to manage a connection to a SQL database.
GraphHandle
and QueryHandle
are used to create, insert
update and delete graphs and queries.
Connection API¶
Fornax stores and queries graphs using a database via a database connection.
Connection
manages the lifecycle of this database connection,
the creation of database schema (if required)
and any cleanup once the connection is closed.
-
class
fornax.api.
Connection
(url, **kwargs)[source] Create a new database connection. If the database is empty
Connection
will create any missing schema.Currrently sqlite and postgresql are activly supported as backend databases.
In addition to the open/close syntax, Connection supports the context manager syntax where the context is treaded as a transaction. Any changes will be automatically rolled back in the event of an exception:
with Connection("postgres:://user/0.0.0.0./mydb") as conn: graph = fornax.GraphHandle.create(conn)
Parameters: url (str) – dialect[+driver]://user:password@host/dbname[?key=value..] -
close
()[source] Close the fornax database connection and free any connections in the connection pool
-
open
()[source] Open the fornax database connection and create any absent tables and indicies
-
Graph API¶
Since Graphs are persisted in a database they are not represented
directly by any object.
Rather, graphs are accessed via a graph handle which permits the user
to manipulate graphs via a Connection
instance.
-
class
fornax.api.
GraphHandle
(connection: fornax.api.Connection, graph_id: int)[source] Create a handle to an existing graph with id graph_id accessed via connection.
Parameters: - connection (Connection) – fornax database connection
- graph_id (int) – unique id for an existing graph
-
add_edges
(sources: Iterable, targets: Iterable, **kwargs)[source] Append edges to a graph representing relationships between nodes
Parameters: - sources (typing.Iterable) – node id_src
- targets (typing.Iterable) – node id_src
Keyword arguments can be used to attach metadata to the edges. For example to add three edges with a relationship attribute friend or foe:
graph_handle.add_edges( sources=[0, 1, 2], targets=[1, 2, 0], relationship=['friend', 'friend', 'foe'] )
Keyword arguments can be used to attach any arbitrary JSON serialisable data to edges.
Note
The following reserved keywords are not reserved and will raise an exception
- start
- end
- type
- weight
-
add_nodes
(**kwargs)[source] Append nodes to a graph
Parameters: id_src (Iterable) – An iterable of unique hashable identifiers, default None Keyword arguments can be used to attached arbitrary JSON serialised metadata to each node:
# create 3 nodes with ids: 0, 1, 2 # and names 'Anne', 'Ben', 'Charles' graph_handle.add_nodes(names=['Anne', 'Ben', 'Charles'])
By default, each node will be assigned a sequential integer id starting from 0. A custom id can be assigned using the id_src keyword provided that all of the ids are hashable:
# create 3 nodes with ids: 'Anne', 'Ben', 'Charles' # and no explicit name field graph_handle.add_nodes(id_src=['Anne', 'Ben', 'Charles'])
Note
id is a reserved keyword argument which will raise an exception
-
classmethod
create
(connection: fornax.api.Connection)[source] Create a new empty graph via connection and return a GraphHandle to it
Parameters: connection (Connection) – a fornax database connection Returns: GraphHandle to a new graph Return type: GraphHandle
-
delete
()[source] Delete this graph.
Delete the graph accessed through graph handle and all of the associated nodes and edges.
-
graph_id
Get the unique id for this graph
Graph id’s are automaticly assigned at creation time.
-
classmethod
read
(connection: fornax.api.Connection, graph_id: int)[source] Create a new GraphHandle to an existing graph with unique identifier graph_id
Parameters: - connection (Connection) – a fornax database connection
- graph_id (int) – unique identifier for an existing graph
Returns: A new graph handle to an existing graph
Return type:
Query API¶
Like Graphs, queries exist in a database and a accessed via a handle.
Queries are executed using the QueryHandle.execute()
method.
A query brings together three important concenpts.
A target graph is the graph which is going to be searched.
A query graph is the subgraph that is being seached for in the target graph.
matches are label similarities between nodes in the query graph and target graph with a weight where \(0 \lt weight \lt= 1\). Users are free to caculate label similarity scores however they like. Fornax only needs to know about non zero weights between matches.
Once a query has been created and executed it will return the n subgraphs in the target graph which are most similar to the query graph based on the similarity score between nodes and their surrounding neighbourhoods.
Note
Nodes in the target graph will only be returned from a query if they have a non zero similarity score to at least one node in the query graph.
-
class
fornax.api.
QueryHandle
(connection: fornax.api.Connection, query_id: int)[source] Create a handle to an existing query via connection with unique id query_id.
Parameters: - connection (Connection) – a fornax database connection
- query_id (int) – unique id for an existing query
-
add_matches
(sources: Iterable[int], targets: Iterable[int], weights: Iterable[float], **kwargs)[source] Add matches between the query graph and the target graph
Parameters: - sources (typing.Iterable[int]) – Iterable of src_id in the query graph
- targets (typing.Iterable[int]) – Iterable of src_id in the target graph
- weights (typing.Iterable[float]) – Iterable of weights between 0 and 1
For example, to add matches between
- node 0 in the query graph and node 0 in the target graph with weight .9
- node 0 in the query graph and node 1 in the target graph with weight .1
then:
query.add_matches([0, 0], [0, 1], [.9, .1])
Note
Adding weights that compare equal to zero will raise an exception.
-
classmethod
create
(connection: fornax.api.Connection, query_graph: fornax.api.GraphHandle, target_graph: fornax.api.GraphHandle)[source] Create a new query and return a QueryHandle for it
Parameters: - connection (Connection) – a fornax database connection
- query_graph (GraphHandle) – subgraph to find target graph
- target_graph (GraphHandle) – Graph to be searched
Returns: new QueryHandle
Return type:
-
delete
()[source] Delete this query and any associated matches
-
execute
(n=5, hopping_distance=2, max_iters=10)[source] Execute a fuzzy subgraph matching query finding the top n subgraph matches between the query graph and the target graph.
Parameters: - n (int, optional) – number of subgraph matches to return
- hopping_distance (int, optional) – lengthscale hyperparameter, defaults to 2
- max_iters (int, optional) – maximum number of optimisation iterations
Returns: query result
Return type: dict
-
query_graph
() → fornax.api.GraphHandle[source] Get a QueryHandle for the query graph
Returns: query graph Return type: GraphHandle
-
classmethod
read
(connection: fornax.api.Connection, query_id: int)[source] Create a new QueryHandle to an existing query with unique id query_id via connection.
Parameters: - connection (Connection) – a fornax database connection
- query_id (int) – unique identifier for a query
Returns: new QueryHandle
Return type:
-
target_graph
() → fornax.api.GraphHandle[source] Get a QueryHandle for the target graph
Returns: target graph Return type: GraphHandle