Skip to content

Commit

Permalink
Added Networkx Support in python driver (#1716)
Browse files Browse the repository at this point in the history
Co-authored-by: munmud <[email protected]>
  • Loading branch information
supracd and Munmud authored Apr 10, 2024
1 parent 0eef91d commit 80d847a
Show file tree
Hide file tree
Showing 10 changed files with 1,148 additions and 2 deletions.
1 change: 1 addition & 0 deletions .github/workflows/python-driver.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,5 @@ jobs:
- name: Test
run: |
python test_age_py.py -db "postgres" -u "postgres" -pass "agens"
python test_networkx.py -db "postgres" -u "postgres" -pass "agens"
python -m unittest -v test_agtypes.py
71 changes: 71 additions & 0 deletions drivers/python/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,74 @@ SET search_path = ag_catalog, "$user", public;

### License
Apache-2.0 License


## Networkx
### Netowkx Unit test
```
python test_networkx.py \
-host "127.0.0.1" \
-db "postgres" \
-u "postgres" \
-pass "agens" \
-port 5432
```
Here the following value required
- `-host` : host name (optional)
- `-db` : database name
- `-u` : user name
- `-pass` : password
- `-port` : port (optional)

### Networkx to AGE
Insert From networkx directed graph into an Age database.
#### Parameters

- `connection` (psycopg2.connect): Connection object to the Age database.

- `G` (networkx.DiGraph): Networkx directed graph to be converted and inserted.

- `graphName` (str): Name of the age graph.

#### Returns

None

#### Example

```python

# Create a Networkx DiGraph
G = nx.DiGraph()
G.add_node(1)
G.add_node(2)
G.add_edge(1, 2)

# Convert and insert the graph into the Age database
graphName = "sample_graph"
networkx_to_age(connection, G, graphName)
```



### AGE to Netowkx

Converts data from a Apache AGE graph database into a Networkx directed graph.

#### Parameters

- `connection` (psycopg2.connect): Connection object to the PostgreSQL database.
- `graphName` (str): Name of the graph.
- `G` (None | nx.DiGraph): Optional Networkx directed graph. If provided, the data will be added to this graph.
- `query` (str | None): Optional Cypher query to retrieve data from the database.

#### Returns

- `nx.DiGraph`: Networkx directed graph containing the converted data.

#### Example

```python
# Call the function to convert data into a Networkx graph
graph = age_to_networkx(connection, graphName="MyGraph" )
```
17 changes: 17 additions & 0 deletions drivers/python/age/networkx/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.

from .networkx_to_age import networkx_to_age
from .age_to_networkx import age_to_networkx
92 changes: 92 additions & 0 deletions drivers/python/age/networkx/age_to_networkx.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.

from age import *
import psycopg2
import networkx as nx
from age.models import Vertex, Edge, Path
from .lib import *


def age_to_networkx(connection: psycopg2.connect,
graphName: str,
G: None | nx.DiGraph = None,
query: str | None = None
) -> nx.DiGraph:
"""
@params
---------------------
connection - (psycopg2.connect) Connection object
graphName - (str) Name of the graph
G - (networkx.DiGraph) Networkx directed Graph [optional]
query - (str) Cypher query [optional]
@returns
------------
Networkx directed Graph
"""

# Check if the age graph exists
checkIfGraphNameExistInAGE(connection, graphName)

# Create an empty directed graph
if G == None:
G = nx.DiGraph()

def addNodeToNetworkx(node):
"""Add Nodes in Networkx"""
G.add_node(node.id,
label=node.label,
properties=node.properties)

def addEdgeToNetworkx(edge):
"""Add Edge in Networkx"""
G.add_edge(edge.start_id,
edge.end_id,
label=edge.label,
properties=edge.properties)

def addPath(path):
"""Add Edge in Networkx"""
for x in path:
if (type(x) == Path):
addPath(x)
for x in path:
if (type(x) == Vertex):
addNodeToNetworkx(x)
for x in path:
if (type(x) == Edge):
addEdgeToNetworkx(x)

# Setting up connection to work with Graph
age.setUpAge(connection, graphName)

if (query == None):
addAllNodesIntoNetworkx(connection, graphName, G)
addAllEdgesIntoNetworkx(connection, graphName, G)
else:
with connection.cursor() as cursor:
cursor.execute(query)
rows = cursor.fetchall()
for row in rows:
for x in row:
if type(x) == Path:
addPath(x)
elif type(x) == Edge:
addEdgeToNetworkx(x)
elif type(x) == Vertex:
addNodeToNetworkx(x)
return G
Loading

0 comments on commit 80d847a

Please sign in to comment.