Package: networkx_query
networkx-queryVersions followingSemantic VersioningOverviewNetworkX Query ToolSeedocumentation.InstallationInstall this library directly into an activated virtual environment:$ pip install networkx-queryor add it to yourPoetryproject:$ poetry add networkx-queryUsageSearching nodesimportnetworkxasnxfromnetworkx_queryimportsearch_nodes,search_edgesg=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")fornode_idinsearch_nodes(g,{"==":[("product",),"chocolate"]}):print(node_id)>>1Searching edgesforedge_idinsearch_edges(g,{"eq":[("action",),"produce"]}):print(edge_id)>>(3,2)Searching direct relation shipWithsearch_direct_relationshipsyou can made a query which filter edges on their :source node attributesedge attributestarget node attributesWith this graph:importnetworkxasnxfromnetworkx_queryimportsearch_direct_relationshipsg=nx.DiGraph()foriinrange(30):g.add_node(i,data=i)foriinrange(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 < 8edge with data > 15list(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 > 9edge with data > 15target node with data < 22search_direct_relationships(graph=g,source={"gt":["data",9]},edge={"gt":["data",15]},target={'lt':["data",22]}))>>[(10,20),(11,21)]search_relationshipsWith :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, 8PathCriteria(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, 8PathCriteria(target={},edge={"eq":[("weight",),2]}),# edge 1-3, 7-5, 7-6, 8-5PathCriteria(target={"eq":[("product",),"d"]}),# node 4, 5, 6 -> no 1, 3, 4))# output: [[1, 3, 4]]Note the usage ofPathCriteria(target={}, ..to define a constraint based only on edge.{}act as a wildcard.APIActually, we have:search_edgessearch_nodessearch_direct_relationshipssearch_relationshipsAll this function are based onprepare_querywhich return an Evaluator.Quickly,Evaluatorare function with this signature: (context) -> bool, andContextis a dictionary like structure (with in and [] methods, and supportcontainsor  (iterandgetitem))
With networkX, node and edge attributes are dictionary like, so implementation of this three methods are very simple.Query languageWe define a little json query language likejson-query-languageagainst nodes or edges attributes.ExpressionsMain expression syntax turn around this:{
    operator_name : parameters
}Basic matching expressionTest 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:NameAliasParametersDescriptionhasPathCheck if path exists in context.containsPath, strCheck if an attribut path exists and contains specified value.eq==Path, AnyCheck if an attribut path exists and equals specified value.neq!=Path, AnyCheck if an attribut path did not exists or not equals specified value.gt>Path, AnyCheck if an attribut path exists and greather that specified value.lt<Path, AnyCheck if an attribut path exists and lower that specified value.gte>=Path, AnyCheck if an attribut path exists and greather or equals that specified value.lte<=Path, AnyCheck 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 expressionWe support this operators:NameAliasParametersDescriptionand&&list of queryAnd operator.or||list of queryOr operator.xorlist of queryxor operator.nxorlist of querynxor operator.not!queryNot 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 Featuresadd projection expression (a return like statement)add join relation ship