diff --git a/.gitignore b/.gitignore index abf1fc09ca..991f01c70b 100644 --- a/.gitignore +++ b/.gitignore @@ -13,8 +13,8 @@ comparison-benchmark/python/data/* .ipynb_checkpoints _autosummary examples/docker/lotr/lotr -examples/py/enron/emails.csv -examples/py/enron/lib/ +examples/python/enron/emails.csv +examples/python/enron/lib/ docs/source/_rustdoc/ docs/logs/ /docs/lib/ diff --git a/docs/requirements.in b/docs/requirements.in new file mode 100644 index 0000000000..fa2f0caaac --- /dev/null +++ b/docs/requirements.in @@ -0,0 +1 @@ +sphinx_autosummary_accessors \ No newline at end of file diff --git a/docs/requirements.txt b/docs/requirements.txt deleted file mode 100644 index 6d2dea4bcc..0000000000 --- a/docs/requirements.txt +++ /dev/null @@ -1,86 +0,0 @@ -aiohttp==3.9.5 -aiosignal==1.3.1 -appnope==0.1.3 -asttokens==2.4.0 -async-timeout==4.0.3 -attrs==23.1.0 -autodocsumm==0.2.11 -backcall==0.2.0 -backoff==2.2.1 -bleach==6.0.0 -botocore==1.31.53 -certifi==2024.6.2 -contourpy==1.1.1 -cycler==0.11.0 -decorator==5.1.1 -defusedxml==0.7.1 -docopt==0.6.2 -exceptiongroup==1.1.3 -executing==1.2.0 -fastjsonschema==2.18.0 -fonttools==4.53.0 -frozenlist==1.4.0 -gql==3.4.1 -graphql-core==3.2.3 -ipython==8.15.0 -jedi==0.19.0 -jmespath==1.0.1 -jsonpickle==3.0.2 -jsonschema==4.19.1 -jsonschema-specifications==2023.7.1 -jupyter_client==8.3.1 -jupyter_core==5.3.1 -jupyterlab-pygments==0.2.2 -kiwisolver==1.4.5 -matplotlib==3.8.0 -matplotlib-inline==0.1.6 -maturin==1.2.3 -mistune==3.0.1 -multidict==6.0.4 -nbclient==0.8.0 -nbconvert==7.8.0 -nbformat==5.9.2 -nbsphinx==0.9.3 -networkx==3.1 -numpy==1.26.0 -numpydoc==1.5.0 -pandas==2.1.1 -pandocfilters==1.5.0 -parso==0.8.3 -pexpect==4.8.0 -pickleshare==0.7.5 -Pillow==10.3.0 -pipreqs==0.4.13 -platformdirs==3.10.0 -prompt-toolkit==3.0.39 -ptyprocess==0.7.0 -pure-eval==0.2.2 -pyarrow==14.0.1 -pydata-sphinx-theme==0.14.1 -pyparsing==3.1.1 -python-dateutil==2.8.2 -pyvis==0.3.2 -pyzmq==25.1.1 -referencing==0.30.2 -requests-toolbelt==0.10.1 -rpds-py==0.10.3 -six==1.16.0 -sphinx-automodapi==0.16.0 -sphinx-autosummary-accessors==2023.4.0 -sphinx-copybutton==0.5.2 -sphinx-favicon==1.0.1 -sphinx_design==0.5.0 -stack-data==0.6.2 -tinycss2==1.2.1 -tomli==2.0.1 -tornado==6.4.1 -traitlets==5.10.0 -typing_extensions==4.8.0 -tzdata==2023.3 -urllib3==2.2.1 -wcwidth==0.2.6 -webencodings==0.5.1 -websockets==10.4 -yarg==0.1.9 -yarl==1.9.2 -sphinx-notfound-page==1.0.0 \ No newline at end of file diff --git a/examples/free-queries/python/main.py b/examples/free-queries/python/main.py deleted file mode 100644 index e65428a23c..0000000000 --- a/examples/free-queries/python/main.py +++ /dev/null @@ -1,155 +0,0 @@ -from raphtory import Graph, PersistentGraph -from raphtory.algorithms import dijkstra_single_source_shortest_paths -import tempfile - -def main(): - # Create an instance of a Graph - graph = Graph() - - # Add nodes to the graph with properties - graph.add_node( - 1, "hamza", properties={"value": 60, "value_f": 31.3, "value_str": "abc123"} - ) - graph.add_node( - 2, - "ben", - properties={"value": 59, "value_f": 11.4, "value_str": "test test test"}, - ) - graph.add_node( - 3, - "haaroon", - properties={ - "value": 199, - "value_f": 52.6, - "value_str": "I wanna rock right now", - }, - ) - - # Add edges between nodes with properties - graph.add_edge( - 2, - "haaroon", - "hamza", - properties={"value": 60, "value_f": 31.3, "value_str": "abc123"}, - ) - graph.add_edge( - 1, - "ben", - "hamza", - properties={"value": 59, "value_f": 11.4, "value_str": "test test test"}, - ) - graph.add_edge( - 3, - "ben", - "haaroon", - properties={ - "value": 199, - "value_f": 52.6, - "value_str": "I wanna rock right now", - }, - ) - - # Add constant properties to a node - graph.node('ben').add_constant_properties({'static prop': 123}) - assert graph.node('ben').properties.get('static prop') == 123 - - # Update/Add properties of a node - props_t2 = {"value2": 100, "value_f": 15.0} - graph.node("ben").add_updates(7, props_t2) - assert graph.node("ben").properties.get('value2') == 100 - - # Update properties of an edge - props_t2 = { - "value": 200, - "value_str": "I wanna spock right now", - } - graph.edge('ben', 'haaroon').add_updates(7, props_t2) - assert graph.edge('ben', 'haaroon').properties.get('value') == 200 - - # Create an index for the graph - index = graph.index() - - # Name tests - assert len(index.search_nodes("name:ben")) == 1 - assert len(index.search_nodes("name:ben OR name:hamza")) == 2 - assert len(index.search_nodes("name:ben AND name:hamza")) == 0 - assert len(index.search_nodes("name: IN [ben, hamza]")) == 2 - - # Property tests - assert len(index.search_nodes("value:<120 OR value_f:>30")) == 3 - assert len(index.search_nodes("value:[0 TO 60]")) == 2 - assert len(index.search_nodes("value:[0 TO 60}")) == 1 # } == exclusive - assert len(index.search_nodes("value:>59 AND value_str:abc123")) == 1 - - # edge tests - assert len(index.search_edges("from:ben")) == 2 - assert len(index.search_edges("from:ben OR from:haaroon")) == 3 - assert len(index.search_edges("to:haaroon AND from:ben")) == 1 - assert len(index.search_edges("to: IN [ben, hamza]")) == 2 - - # edge prop tests - assert len(index.search_edges("value:<120 OR value_f:>30")) == 3 - assert len(index.search_edges("value:[0 TO 60]")) == 2 - assert len(index.search_edges("value:[0 TO 60}")) == 1 # } == exclusive - assert len(index.search_edges("value:>59 AND value_str:abc123")) == 1 - - # Collect the out-neighbours of nodes - out_neighbours = graph.nodes.out_neighbours.name.collect() - out_neighbours = (set(n) for n in out_neighbours) - out_neighbours = dict(zip(graph.nodes.name, out_neighbours)) - assert out_neighbours == {'hamza': set(), 'ben': {'haaroon', 'hamza'}, 'haaroon': {'hamza'}} - - # Collect the out-out-neighbours (two hops away) of nodes - out_out_neighbours = graph.nodes.out_neighbours.out_neighbours.name.collect() - assert out_out_neighbours == [[], ['hamza'], []] - - # Save the graph to a file and load it back - tmpdirname = tempfile.TemporaryDirectory() - graph_path = tmpdirname.name + '/graph.bin' - graph.save_to_file(graph_path) - - # Add a new node to the loaded graph, save it, and load it back - g1 = graph.load_from_file(graph_path) - assert g1.node('ben').name == 'ben' - g1.add_node(4, 'shivam') - graph_path = tmpdirname.name + "/graph2.bin" - g1.save_to_file(graph_path) - g2 = graph.load_from_file(graph_path) - assert g2.node('shivam').name == 'shivam' - - # Create an instance of a Graph with deletions - graph = PersistentGraph() - - # Add nodes with deletions and properties - graph.add_node(0, 1, {"type": "wallet", "cost": 99.5}) - graph.add_node(-1, 2, {"type": "wallet", "cost": 10.0}) - graph.add_node(6, 3, {"type": "wallet", "cost": 76.0}) - - edges = [(1, 1, 2, 4.0), (2, 1, 3, 4.0), (-1, 2, 1, 2.0), (0, 1, 1, 3.0), (7, 3, 2, 6.0), (1, 1, 1, 2.0)] - - # Add edges with deletions and properties - for e in edges: - graph.add_edge(e[0], e[1], e[2], {"prop1": 1, "prop2": 9.8, "prop3": "test", "weight": e[3]}) - graph.edge(edges[0][1], edges[0][2]).add_constant_properties({"static": "test"}) - graph.delete_edge(10, edges[0][1], edges[0][2]) - - # Assert that an edge has been deleted - assert graph.edge(edges[0][1], edges[0][2]).is_deleted() == True - - # Find nodes with a specific properties - nodes = graph.find_nodes({"cost": 99.5}) - assert nodes[0].properties.get('cost') == 99.5 - - # Find edges with a specific properties - edges = graph.find_edges({"prop1": 1}) - assert edges[0].properties.get('prop1') == 1 - - # Collect all edges of a node - all_edges = graph.node(1).edges - assert all_edges.src.name.collect() == ['1', '2', '1', '1'] - - # Run Dijkstra's algorithm for single-source shortest paths - assert dijkstra_single_source_shortest_paths(graph, 1, [2]) == {'2': (4.0, ['1', '2'])} - -if __name__ == "__main__": - main() diff --git a/examples/free-queries/python/tests/test_graph.py b/examples/free-queries/python/tests/test_graph.py deleted file mode 100644 index 43da124bee..0000000000 --- a/examples/free-queries/python/tests/test_graph.py +++ /dev/null @@ -1,208 +0,0 @@ -import tempfile -import pytest -from raphtory import Graph, PersistentGraph -from raphtory.algorithms import dijkstra_single_source_shortest_paths -from typing import TypeVar, Callable -import os -import time - - -B = TypeVar('B') - -def measure(name: str, f: Callable[..., B], *args, print_result: bool = True) -> B: - start_time = time.time() - result = f(*args) - elapsed_time = time.time() - start_time - - time_unit = "s" - elapsed_time_display = elapsed_time - if elapsed_time < 1: - time_unit = "ms" - elapsed_time_display *= 1000 - - if print_result: - print(f"Running {name}: time: {elapsed_time_display:.3f}{time_unit}, result: {result}") - else: - print(f"Running {name}: time: {elapsed_time_display:.3f}{time_unit}") - - return result - - -def build_graph(): - # Create an instance of a Graph - graph = Graph() - - # Add nodes to the graph with properties - graph.add_node( - 1, "hamza", properties={"value": 60, "value_f": 31.3, "value_str": "abc123"} - ) - graph.add_node( - 2, - "ben", - properties={"value": 59, "value_f": 11.4, "value_str": "test test test"}, - ) - graph.add_node( - 3, - "haaroon", - properties={ - "value": 199, - "value_f": 52.6, - "value_str": "I wanna rock right now", - }, - ) - - # Add edges between nodes with properties - graph.add_edge( - 2, - "haaroon", - "hamza", - properties={"value": 60, "value_f": 31.3, "value_str": "abc123"}, - ) - graph.add_edge( - 1, - "ben", - "hamza", - properties={"value": 59, "value_f": 11.4, "value_str": "test test test"}, - ) - graph.add_edge( - 3, - "ben", - "haaroon", - properties={ - "value": 199, - "value_f": 52.6, - "value_str": "I wanna rock right now", - }, - ) - - return graph - -def build_graph_with_deletions(): - # Create an instance of a Graph with deletions - graph = PersistentGraph() - - # Add nodes with deletions and properties - graph.add_node(0, 1, {"type": "wallet", "cost": 99.5}) - graph.add_node(-1, 2, {"type": "wallet", "cost": 10.0}) - graph.add_node(6, 3, {"type": "wallet", "cost": 76.0}) - - edges = [(1, 1, 2, 4.0), (2, 1, 3, 4.0), (-1, 2, 1, 2.0), (0, 1, 1, 3.0), (7, 3, 2, 6.0), (1, 1, 1, 2.0)] - - # Add edges with deletions and properties - for e in edges: - graph.add_edge(e[0], e[1], e[2], {"prop1": 1, "prop2": 9.8, "prop3": "test", "weight": e[3]}) - graph.edge(edges[0][1], edges[0][2]).add_constant_properties({"static": "test"}) - graph.delete_edge(10, edges[0][1], edges[0][2]) - - return graph - - -def test_graph(): - print() - graph = measure("Build graph", build_graph, print_result=False) - - # Add constant properties to a node - measure("Add static property", graph.node('ben').add_constant_properties, {'static prop': 123}, print_result=False) - assert measure("Get static property", graph.node('ben').properties.get, 'static prop', print_result=False) == 123 - - # Update/Add properties of a node - props_t2 = {"value2": 100, "value_f": 15.0} - measure("Update node property", graph.node("ben").add_updates, 7, props_t2, print_result=False) - assert measure("Get temporal property", graph.node("ben").properties.get, 'value2', print_result=False) == 100 - - # Update properties of an edge - props_t2 = { - "value": 200, - "value_str": "I wanna spock right now", - } - measure("Update edge property", graph.edge('ben', 'haaroon').add_updates, 7, props_t2, print_result=False) - assert measure("Get edge property", graph.edge('ben', 'haaroon').properties.get, 'value', print_result=False) == 200 - - # Create an index for the graph - index = graph.index() - - # Name tests - assert len(measure("Search nodes= name:ben", index.search_nodes, "name:ben", print_result=False)) == 1 - assert len(measure("Search nodes= name:ben OR name:hamza", index.search_nodes, "name:ben OR name:hamza", print_result=False)) == 2 - assert len(measure("Search nodes= name:ben AND name:hamza", index.search_nodes, "name:ben AND name:hamza", print_result=False)) == 0 - assert len(measure("Search nodes= name: IN [ben, hamza]", index.search_nodes, "name: IN [ben, hamza]", print_result=False)) == 2 - - # Property tests - assert len(measure("Search nodes= value:<120 OR value_f:>30", index.search_nodes, "value:<120 OR value_f:>30", print_result=False)) == 3 - assert len(measure("Search nodes= value:[0 TO 60]", index.search_nodes, "value:[0 TO 60]", print_result=False)) == 2 - assert len(measure("Search nodes= value:[0 TO 60}", index.search_nodes, "value:[0 TO 60}", print_result=False)) == 1 # } == exclusive - assert len(measure("Search nodes= value:>59 AND value_str:abc123", index.search_nodes, "value:>59 AND value_str:abc123", print_result=False)) == 1 - - # edge tests - assert len(measure("Search nodes= from:ben", index.search_edges, "from:ben", print_result=False)) == 2 - assert len(measure("Search nodes= from:ben OR from:haaroon", index.search_edges, "from:ben OR from:haaroon", print_result=False)) == 3 - assert len(measure("Search nodes= to:haaroon AND from:ben", index.search_edges, "to:haaroon AND from:ben", print_result=False)) == 1 - assert len(measure("Search nodes= to: IN [ben, hamza]", index.search_edges, "to: IN [ben, hamza]", print_result=False)) == 2 - - # edge prop tests - assert len(measure("Search nodes= value:<120 OR value_f:>30", index.search_edges, "value:<120 OR value_f:>30", print_result=False)) == 3 - assert len(measure("Search nodes= value:[0 TO 60]", index.search_edges, "value:[0 TO 60]", print_result=False)) == 2 - assert len(measure("Search nodes= value:[0 TO 60}", index.search_edges, "value:[0 TO 60}", print_result=False)) == 1 # } == exclusive - assert len(measure("Search nodes= value:>59 AND value_str:abc123", index.search_edges, "value:>59 AND value_str:abc123", print_result=False)) == 1 - - # Collect the out-neighbours of nodes - out_neighbours = measure("Get out neighbours", graph.nodes.out_neighbours.name.collect, print_result=False) - out_neighbours = (set(n) for n in out_neighbours) - out_neighbours = dict(zip(graph.nodes.name, out_neighbours)) - assert out_neighbours == {'hamza': set(), 'ben': {'haaroon', 'hamza'}, 'haaroon': {'hamza'}} - - # Collect the out-out-neighbours (two hops away) of nodes - out_out_neighbours = measure("Get out neighbours of out neighbours", graph.nodes.out_neighbours.out_neighbours.name.collect, print_result=False) - assert out_out_neighbours == [[], ['hamza'], []] - - # Save the graph to a file and load it back - tmpdirname = tempfile.TemporaryDirectory() - graph_path = tmpdirname.name + '/graph.bin' - measure("Save graph to disk", graph.save_to_file, graph_path, print_result=False) - - # Add a new node to the loaded graph, save it, and load it back - g1 = measure("Load graph from disk", graph.load_from_file, graph_path, print_result=False) - assert g1.node('ben').name == 'ben' - g1.add_node(4, 'shivam') - graph_path = tmpdirname.name + "/graph2.bin" - g1.save_to_file(graph_path) - g2 = graph.load_from_file(graph_path) - assert g2.node('shivam').name == 'shivam' - - # Create an instance of a Graph with deletions - graph = PersistentGraph() - - # Add nodes with deletions and properties - graph.add_node(0, 1, {"type": "wallet", "cost": 99.5}) - graph.add_node(-1, 2, {"type": "wallet", "cost": 10.0}) - graph.add_node(6, 3, {"type": "wallet", "cost": 76.0}) - - edges = [(1, 1, 2, 4.0), (2, 1, 3, 4.0), (-1, 2, 1, 2.0), (0, 1, 1, 3.0), (7, 3, 2, 6.0), (1, 1, 1, 2.0)] - - # Add edges with deletions and properties - for e in edges: - graph.add_edge(e[0], e[1], e[2], {"prop1": 1, "prop2": 9.8, "prop3": "test", "weight": e[3]}) - graph.edge(edges[0][1], edges[0][2]).add_constant_properties({"static": "test"}) - graph.delete_edge(10, edges[0][1], edges[0][2]) - - # Assert that an edge has been deleted - assert graph.edge(edges[0][1], edges[0][2]).is_deleted() == True - - # Find nodes with specific properties - nodes = measure("Find nodes with specific properties", graph.find_nodes, {"cost": 99.5}, print_result=False) - assert nodes[0].properties.get('cost') == 99.5 - - # Find edges with specific properties - edges = measure("Find edges with specific properties", graph.find_edges, {"prop1": 1}, print_result=False) - assert edges[0].properties.get('prop1') == 1 - - # Collect all edges of a node - all_edges = graph.node(1).edges - assert all_edges.src.name.collect() == ['1', '2', '1', '1'] - - # Run Dijkstra's algorithm for single-source shortest paths - assert measure("Shortest path", dijkstra_single_source_shortest_paths, graph, 1, [2], print_result=False) == {'2': (2.0, ['1', '2'])} - - -def test_graph_with_deletions(): - measure("Build graph with deletions", build_graph_with_deletions, print_result=False) diff --git a/examples/py/enron/embedding-cache b/examples/python/enron/embedding-cache similarity index 100% rename from examples/py/enron/embedding-cache rename to examples/python/enron/embedding-cache diff --git a/examples/py/enron/enron-vectors.ipynb b/examples/python/enron/enron-vectors.ipynb similarity index 100% rename from examples/py/enron/enron-vectors.ipynb rename to examples/python/enron/enron-vectors.ipynb diff --git a/examples/py/enron/nx.html b/examples/python/enron/nx.html similarity index 100% rename from examples/py/enron/nx.html rename to examples/python/enron/nx.html diff --git a/python/pyproject.toml b/python/pyproject.toml index 4ca585a222..8fc65ade21 100644 --- a/python/pyproject.toml +++ b/python/pyproject.toml @@ -13,8 +13,8 @@ classifiers = [ dependencies = [ "pyvis >= 0.3.2", "networkx >= 2.6.3", - "pandas >= 2.0.3", - "pyarrow >= 12.0.1", + "pandas >= 2.2.2", + "pyarrow >= 16.1.0", "requests >= 2.31.0", "gql[all] == 3.5.0", "matplotlib >= 3.4.3", diff --git a/python/python/raphtory/__init__.py b/python/python/raphtory/__init__.py index b656e51b2d..5d05bb2d2a 100644 --- a/python/python/raphtory/__init__.py +++ b/python/python/raphtory/__init__.py @@ -10,7 +10,7 @@ try: sys.modules["raphtory.disk_graph"] = disk_graph except Exception as e: - print(e) + pass from .nullmodels import * from .plottingutils import * diff --git a/raphtory/src/graph_loader/example/sx_superuser_graph.rs b/raphtory/src/graph_loader/example/sx_superuser_graph.rs index 5b145e0fb3..503046f336 100644 --- a/raphtory/src/graph_loader/example/sx_superuser_graph.rs +++ b/raphtory/src/graph_loader/example/sx_superuser_graph.rs @@ -46,7 +46,6 @@ //! ``` use crate::{ - core::utils::hashing::calculate_hash, graph_loader::{fetch_file, source::csv_loader::CsvLoader}, prelude::*, }; diff --git a/raphtory/src/python/types/macros/trait_impl/node_state.rs b/raphtory/src/python/types/macros/trait_impl/node_state.rs index 0fcfcbf63f..b0f4a7881a 100644 --- a/raphtory/src/python/types/macros/trait_impl/node_state.rs +++ b/raphtory/src/python/types/macros/trait_impl/node_state.rs @@ -1,3 +1,4 @@ +#![allow(non_local_definitions)] use crate::{ core::{entities::nodes::node_ref::NodeRef, ArcStr}, db::{ diff --git a/requirements.in b/requirements.in deleted file mode 100644 index 3de9828cb3..0000000000 --- a/requirements.in +++ /dev/null @@ -1,14 +0,0 @@ -numpy -pandas -matplotlib -tqdm -raphtory -requests==2.32.0 -pyvis -seaborn -scipy -Scrapy -networkx -altair -langchain -sentence_transformers \ No newline at end of file