Skip to main content

NetworkX Query Tool

Project description

networkx-query

Coverage Status Codacy BadgeScrutinizer Code Quality PyPI Version PyPI License

Versions following Semantic Versioning

Overview

NetworkX Query Tool

See documentation.

Installation

Install this library directly into an activated virtual environment:

$ pip install networkx-query

or add it to your Poetry project:

$ poetry add networkx-query

Usage

Searching nodes

import networkx as nx
from networkx_query import search_nodes, search_edges

g = nx.DiGraph()
g.add_node(1, product="chocolate")
g.add_node(2, product="milk")
g.add_node(3, product="coat")
g.add_edge(1, 2, action="shake")
g.add_edge(3, 2, action="produce")


for node_id in search_nodes(g, {"==": [("product",), "chocolate"]}):
    print(node_id)

>> 1

Searching edges

for edge_id in search_edges(g, {"eq": [("action",), "produce"]}):
    print(edge_id)

>> (3, 2)

Searching direct relation ship

With search_direct_relationships you can made a query which filter edges on their :

  • source node attributes
  • edge attributes
  • target node attributes

With this graph:

import networkx as nx
from networkx_query import search_direct_relationships

g = nx.DiGraph()
for i in range(30):
    g.add_node(i, data=i)

for i in range(10, 30):
    g.add_edge(i - 10, i, data=i)

We can filtering all edges with source node with data < 3:

list(search_direct_relationships(graph=g, source={"lt": ["data", 3]}))

[(0, 10), (1, 11), (2, 12)]

We can filtering all edges with:

  • source node with data < 8
  • edge with data > 15
list(search_direct_relationships(graph=g, source={"lt": ["data", 8]}, edge={"gt": ["data", 15]}))

>> [(6, 16), (7, 17)]

We can filtering all edges with:

  • source node with data > 9
  • edge with data > 15
  • target node with data < 22
search_direct_relationships(
            graph=g, source={"gt": ["data", 9]}, edge={"gt": ["data", 15]}, target={'lt': ["data", 22]}
        )
    )

>> [(10, 20), (11, 21)]

search_relationships

With :

    g = nx.DiGraph()
    g.add_node(1, product="a")
    g.add_node(2, product="b")
    g.add_node(3, product="c")
    g.add_node(4, product="d")

    g.add_edge(1, 2)
    g.add_edge(1, 3, weight=2)
    g.add_edge(1, 4)

    g.add_edge(2, 4)
    g.add_edge(3, 4)

You could find all path with multiple constraints:

    list(search_relationships(
            g,
            {"eq": [("product",), "a"]},
            PathCriteria(target={"eq": [("product",), "b"]}),
            PathCriteria(target={"eq": [("product",), "d"]}),
        )) 
    # output: [[1, 2, 4]]

     list(search_relationships(g, {"eq": [("product",), "a"]}, PathCriteria(target={"eq": [("product",), "c"]})))
     # outptu: [[1, 3]]

or something more complex:

    g.add_node(5, product="d")
    g.add_node(6, product="d")
    g.add_node(7, product="a")
    g.add_node(8, product="a")

    g.add_edge(7, 5, weight=2)
    g.add_edge(7, 6, weight=2)
    g.add_edge(8, 5, weight=2)

    list(
        search_relationships(
            g,
            {"eq": [("product",), "a"]},  # node 1, 7, 8
            PathCriteria(
                target={"eq": [("product",), "d"]}, edge={"eq": [("weight",), 2]}
            ),  # edge 1-3, 7-5, 7-6, 8-5  node 4, 5, 6 -> no 1, 3, 4
        )
    )
    # output: [[7, 5], [7, 6], [8, 5]]

    list(
        search_relationships(
            g,
            {"eq": [("product",), "a"]},  # node 1, 7, 8
            PathCriteria(target={}, edge={"eq": [("weight",), 2]}),  # edge 1-3, 7-5, 7-6, 8-5
            PathCriteria(target={"eq": [("product",), "d"]}),  # node 4, 5, 6 -> no 1, 3, 4
        )
    )
    # output: [[1, 3, 4]]

Note the usage of PathCriteria(target={}, .. to define a constraint based only on edge. {} act as a wildcard.

API

Actually, we have:

All this function are based on prepare_query which return an Evaluator.

Quickly, Evaluator are function with this signature: (context) -> bool, and Context is a dictionary like structure (with in and [] methods, and support contains or (iter and getitem)) With networkX, node and edge attributes are dictionary like, so implementation of this three methods are very simple.

Query language

We define a little json query language like json-query-language against nodes or edges attributes.

Expressions

Main expression syntax turn around this:

{
    operator_name : parameters
}

Basic matching expression

Test if a node/edge has an attribute named "my_property":

{
    "has" : "my_property"
}

Test if a node/edge has an attribute product : { "definition": { "name": xxx }} with xxx equals to "chocolate".

{
    "eq" : [ ("product", "definition", "name"), "chocolate"]
}

The tuple ("product", "definition", "name") is a path in attribut dictionnary. A Path is a single string or a tuple of string which represente a path in a tree (here a dictionary).

We support this operators:

Name Alias Parameters Description
has Path Check if path exists in context.
contains Path, str Check if an attribut path exists and contains specified value.
eq == Path, Any Check if an attribut path exists and equals specified value.
neq != Path, Any Check if an attribut path did not exists or not equals specified value.
gt > Path, Any Check if an attribut path exists and greather that specified value.
lt < Path, Any Check if an attribut path exists and lower that specified value.
gte >= Path, Any Check if an attribut path exists and greather or equals that specified value.
lte <= Path, Any Check if an attribut path exists and lower or equals that specified value.
in := Path, List[Any] Check if an attribut path exists and attribut value in specified values.

Boolean composition of matching expression

We support this operators:

Name Alias Parameters Description
and && list of query And operator.
or || list of query Or operator.
xor list of query xor operator.
nxor list of query nxor operator.
not ! query Not operator.

By default, a list of expressions is equivalent of an "AND" of this expressions.

Example:

{
    'not': {
        'has': ['group']
    },
    'has': 'application',
    'eq': [('_link', 'other', 'weight'), 2]
}

is equivalent to:

{
    'and': [
        {
            'not': [
                {
                    'has': ['group']
                }
            ]
        },
        {
            'has': ['application']
        },
        {
            'eq': [('_link', 'other', 'weight'), 2]
        }
    ]
}

Wished Features

  • add projection expression (a return like statement)
  • add join relation ship

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

networkx_query-2.1.3.tar.gz (16.4 kB view details)

Uploaded Source

Built Distribution

networkx_query-2.1.3-py3-none-any.whl (11.7 kB view details)

Uploaded Python 3

File details

Details for the file networkx_query-2.1.3.tar.gz.

File metadata

  • Download URL: networkx_query-2.1.3.tar.gz
  • Upload date:
  • Size: 16.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.5.18

File hashes

Hashes for networkx_query-2.1.3.tar.gz
Algorithm Hash digest
SHA256 4e0f5a2eac2d70de325b5448fb71ad126412d2fedad35a10f6cb18a898759719
MD5 6fe01afafc25a2cc8cf55dd333c2cc68
BLAKE2b-256 ca572f40cea29733ca74f8be0c1939f8a593a55fcea824ad5c14a021a279a572

See more details on using hashes here.

File details

Details for the file networkx_query-2.1.3-py3-none-any.whl.

File metadata

File hashes

Hashes for networkx_query-2.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 1c37d7463393f24666a701f143afc77fb1aa582d505e08405e53af8d67d67e2f
MD5 88e81d9a19e2ffa2ec918878aa04651c
BLAKE2b-256 25ab4277083f662d339db56935abbdc3978c58cd4f6ea400594dad0e2c9fd563

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page