diff --git a/raphtory/src/python/graph/edge.rs b/raphtory/src/python/graph/edge.rs index 277b52837..dd280eaf1 100644 --- a/raphtory/src/python/graph/edge.rs +++ b/raphtory/src/python/graph/edge.rs @@ -385,18 +385,33 @@ impl PyMutableEdge { /// This function allows for the addition of property updates to an edge within the graph. The updates are time-stamped, meaning they are applied at the specified time. /// /// Parameters: - /// t (TimeInput): The timestamp at which the updates should be applied. - /// properties (PropInput, optional): A dictionary of properties to update. - /// layer (str, optional): The layer you want these properties to be added on to. - #[pyo3(signature = (t, properties=None, layer=None))] + /// t (TimeInput): The timestamp at which the updates should be applied. + /// properties (PropInput, optional): A dictionary of properties to update. + /// layer (str, optional): The layer you want these properties to be added on to. + /// secondary_index (int, optional): The optional integer which will be used as a secondary index + /// + /// Returns: + /// None: This function does not return a value, if the operation is successful. + /// + /// Raises: + /// GraphError: If the operation fails. + #[pyo3(signature = (t, properties=None, layer=None, secondary_index=None))] fn add_updates( &self, t: PyTime, properties: Option>, layer: Option<&str>, + secondary_index: Option, ) -> Result<(), GraphError> { - self.edge - .add_updates(t, properties.unwrap_or_default(), layer) + match secondary_index { + None => self + .edge + .add_updates(t, properties.unwrap_or_default(), layer), + Some(secondary_index) => { + self.edge + .add_updates((t, secondary_index), properties.unwrap_or_default(), layer) + } + } } /// Mark the edge as deleted at the specified time. diff --git a/raphtory/src/python/graph/graph.rs b/raphtory/src/python/graph/graph.rs index d7b7495c7..9f0de6f68 100644 --- a/raphtory/src/python/graph/graph.rs +++ b/raphtory/src/python/graph/graph.rs @@ -140,7 +140,7 @@ impl PyGraphEncoder { #[pymethods] impl PyGraph { #[new] - #[pyo3(signature=(num_shards=None))] + #[pyo3(signature = (num_shards = None))] pub fn py_new(num_shards: Option) -> (Self, PyGraphView) { let graph = match num_shards { None => Graph::new(), @@ -177,22 +177,35 @@ impl PyGraph { /// id (str|int): The id of the node. /// properties (PropInput, optional): The properties of the node. /// node_type (str, optional): The optional string which will be used as a node type + /// secondary_index (int, optional): The optional integer which will be used as a secondary index /// /// Returns: /// MutableNode: The added node. /// /// Raises: /// GraphError: If the operation fails. - #[pyo3(signature = (timestamp, id, properties = None, node_type = None))] + #[pyo3( + signature = (timestamp, id, properties = None, node_type = None, secondary_index = None) + )] pub fn add_node( &self, timestamp: PyTime, id: GID, properties: Option>, node_type: Option<&str>, + secondary_index: Option, ) -> Result, GraphError> { - self.graph - .add_node(timestamp, id, properties.unwrap_or_default(), node_type) + match secondary_index { + None => self + .graph + .add_node(timestamp, id, properties.unwrap_or_default(), node_type), + Some(secondary_index) => self.graph.add_node( + (timestamp, secondary_index), + id, + properties.unwrap_or_default(), + node_type, + ), + } } /// Creates a new node with the given id and properties to the graph. It fails if the node already exists. @@ -202,22 +215,34 @@ impl PyGraph { /// id (str|int): The id of the node. /// properties (PropInput, optional): The properties of the node. /// node_type (str, optional): The optional string which will be used as a node type + /// secondary_index (int, optional): The optional integer which will be used as a secondary index /// /// Returns: /// MutableNode: The created node. /// /// Raises: /// GraphError: If the operation fails. - #[pyo3(signature = (timestamp, id, properties = None, node_type = None))] + #[pyo3(signature = (timestamp, id, properties = None, node_type = None, secondary_index = None))] pub fn create_node( &self, timestamp: PyTime, id: GID, properties: Option>, node_type: Option<&str>, + secondary_index: Option, ) -> Result, GraphError> { - self.graph - .create_node(timestamp, id, properties.unwrap_or_default(), node_type) + match secondary_index { + None => { + self.graph + .create_node(timestamp, id, properties.unwrap_or_default(), node_type) + } + Some(secondary_index) => self.graph.create_node( + (timestamp, secondary_index), + id, + properties.unwrap_or_default(), + node_type, + ), + } } /// Adds properties to the graph. @@ -225,18 +250,26 @@ impl PyGraph { /// Arguments: /// timestamp (TimeInput): The timestamp of the temporal property. /// properties (PropInput): The temporal properties of the graph. + /// secondary_index (int, optional): The optional integer which will be used as a secondary index /// /// Returns: /// None: This function does not return a value, if the operation is successful. /// /// Raises: /// GraphError: If the operation fails. + #[pyo3(signature = (timestamp, properties, secondary_index = None))] pub fn add_property( &self, timestamp: PyTime, properties: HashMap, + secondary_index: Option, ) -> Result<(), GraphError> { - self.graph.add_properties(timestamp, properties) + match secondary_index { + None => self.graph.add_properties(timestamp, properties), + Some(secondary_index) => self + .graph + .add_properties((timestamp, secondary_index), properties), + } } /// Adds static properties to the graph. @@ -281,13 +314,14 @@ impl PyGraph { /// dst (str|int): The id of the destination node. /// properties (PropInput, optional): The properties of the edge, as a dict of string and properties. /// layer (str, optional): The layer of the edge. + /// secondary_index (int, optional): The optional integer which will be used as a secondary index /// /// Returns: /// MutableEdge: The added edge. /// /// Raises: /// GraphError: If the operation fails. - #[pyo3(signature = (timestamp, src, dst, properties = None, layer = None))] + #[pyo3(signature = (timestamp, src, dst, properties = None, layer = None, secondary_index = None))] pub fn add_edge( &self, timestamp: PyTime, @@ -295,9 +329,20 @@ impl PyGraph { dst: GID, properties: Option>, layer: Option<&str>, + secondary_index: Option, ) -> Result, GraphError> { - self.graph - .add_edge(timestamp, src, dst, properties.unwrap_or_default(), layer) + match secondary_index { + None => self + .graph + .add_edge(timestamp, src, dst, properties.unwrap_or_default(), layer), + Some(secondary_index) => self.graph.add_edge( + (timestamp, secondary_index), + src, + dst, + properties.unwrap_or_default(), + layer, + ), + } } /// Import a single node into the graph. @@ -557,7 +602,7 @@ impl PyGraph { /// Raises: /// GraphError: If the operation fails. #[pyo3( - signature = (df,time, id, node_type = None, node_type_col = None, properties = None, constant_properties = None, shared_constant_properties = None) + signature = (df, time, id, node_type = None, node_type_col = None, properties = None, constant_properties = None, shared_constant_properties = None) )] fn load_nodes_from_pandas<'py>( &self, @@ -744,7 +789,9 @@ impl PyGraph { /// /// Raises: /// GraphError: If the operation fails. - #[pyo3(signature = (df, id, node_type=None, node_type_col=None, constant_properties = None, shared_constant_properties = None))] + #[pyo3( + signature = (df, id, node_type = None, node_type_col = None, constant_properties = None, shared_constant_properties = None) + )] fn load_node_props_from_pandas( &self, df: &Bound, @@ -781,7 +828,9 @@ impl PyGraph { /// /// Raises: /// GraphError: If the operation fails. - #[pyo3(signature = (parquet_path, id, node_type=None,node_type_col=None, constant_properties = None, shared_constant_properties = None))] + #[pyo3( + signature = (parquet_path, id, node_type = None, node_type_col = None, constant_properties = None, shared_constant_properties = None) + )] fn load_node_props_from_parquet( &self, parquet_path: PathBuf, diff --git a/raphtory/src/python/graph/graph_with_deletions.rs b/raphtory/src/python/graph/graph_with_deletions.rs index 1ea4aeb18..36dcee852 100644 --- a/raphtory/src/python/graph/graph_with_deletions.rs +++ b/raphtory/src/python/graph/graph_with_deletions.rs @@ -116,22 +116,33 @@ impl PyPersistentGraph { /// id (str | int): The id of the node. /// properties (dict): The properties of the node. /// node_type (str) : The optional string which will be used as a node type + /// secondary_index (int, optional): The optional integer which will be used as a secondary index /// /// Returns: /// None: This function does not return a value, if the operation is successful. /// /// Raises: /// GraphError: If the operation fails. - #[pyo3(signature = (timestamp, id, properties = None, node_type = None))] + #[pyo3(signature = (timestamp, id, properties = None, node_type = None, secondary_index = None))] pub fn add_node( &self, timestamp: PyTime, id: GID, properties: Option>, node_type: Option<&str>, + secondary_index: Option, ) -> Result, GraphError> { - self.graph - .add_node(timestamp, id, properties.unwrap_or_default(), node_type) + match secondary_index { + None => self + .graph + .add_node(timestamp, id, properties.unwrap_or_default(), node_type), + Some(secondary_index) => self.graph.add_node( + (timestamp, secondary_index), + id, + properties.unwrap_or_default(), + node_type, + ), + } } /// Creates a new node with the given id and properties to the graph. It fails if the node already exists. @@ -141,22 +152,34 @@ impl PyPersistentGraph { /// id (str | int): The id of the node. /// properties (dict): The properties of the node. /// node_type (str) : The optional string which will be used as a node type + /// secondary_index (int, optional): The optional integer which will be used as a secondary index /// /// Returns: /// MutableNode /// /// Raises: /// GraphError: If the operation fails. - #[pyo3(signature = (timestamp, id, properties = None, node_type = None))] + #[pyo3(signature = (timestamp, id, properties = None, node_type = None, secondary_index = None))] pub fn create_node( &self, timestamp: PyTime, id: GID, properties: Option>, node_type: Option<&str>, + secondary_index: Option, ) -> Result, GraphError> { - self.graph - .create_node(timestamp, id, properties.unwrap_or_default(), node_type) + match secondary_index { + None => { + self.graph + .create_node(timestamp, id, properties.unwrap_or_default(), node_type) + } + Some(secondary_index) => self.graph.create_node( + (timestamp, secondary_index), + id, + properties.unwrap_or_default(), + node_type, + ), + } } /// Adds properties to the graph. @@ -164,18 +187,26 @@ impl PyPersistentGraph { /// Arguments: /// timestamp (TimeInput): The timestamp of the temporal property. /// properties (dict): The temporal properties of the graph. + /// secondary_index (int, optional): The optional integer which will be used as a secondary index /// /// Returns: /// None: This function does not return a value, if the operation is successful. /// /// Raises: /// GraphError: If the operation fails. - pub fn add_property( + #[pyo3(signature = (timestamp, properties, secondary_index = None))] + pub fn add_properties( &self, timestamp: PyTime, properties: HashMap, + secondary_index: Option, ) -> Result<(), GraphError> { - self.graph.add_properties(timestamp, properties) + match secondary_index { + None => self.graph.add_properties(timestamp, properties), + Some(secondary_index) => self + .graph + .add_properties((timestamp, secondary_index), properties), + } } /// Adds static properties to the graph. @@ -220,13 +251,14 @@ impl PyPersistentGraph { /// dst (str | int): The id of the destination node. /// properties (dict): The properties of the edge, as a dict of string and properties /// layer (str): The layer of the edge. + /// secondary_index (int, optional): The optional integer which will be used as a secondary index /// /// Returns: /// None: This function does not return a value, if the operation is successful. /// /// Raises: /// GraphError: If the operation fails. - #[pyo3(signature = (timestamp, src, dst, properties = None, layer = None))] + #[pyo3(signature = (timestamp, src, dst, properties = None, layer = None, secondary_index = None))] pub fn add_edge( &self, timestamp: PyTime, @@ -234,9 +266,20 @@ impl PyPersistentGraph { dst: GID, properties: Option>, layer: Option<&str>, + secondary_index: Option, ) -> Result, GraphError> { - self.graph - .add_edge(timestamp, src, dst, properties.unwrap_or_default(), layer) + match secondary_index { + None => self + .graph + .add_edge(timestamp, src, dst, properties.unwrap_or_default(), layer), + Some(secondary_index) => self.graph.add_edge( + (timestamp, secondary_index), + src, + dst, + properties.unwrap_or_default(), + layer, + ), + } } /// Deletes an edge given the timestamp, src and dst nodes and layer (optional) @@ -246,21 +289,29 @@ impl PyPersistentGraph { /// src (str | int): The id of the source node. /// dst (str | int): The id of the destination node. /// layer (str): The layer of the edge. (optional) + /// secondary_index (int, optional): The optional integer which will be used as a secondary index /// /// Returns: /// The deleted edge /// /// Raises: /// GraphError: If the operation fails. - #[pyo3(signature = (timestamp, src, dst, layer=None))] + #[pyo3(signature = (timestamp, src, dst, layer=None, secondary_index = None))] pub fn delete_edge( &self, timestamp: PyTime, src: GID, dst: GID, layer: Option<&str>, + secondary_index: Option, ) -> Result, GraphError> { - self.graph.delete_edge(timestamp, src, dst, layer) + match secondary_index { + None => self.graph.delete_edge(timestamp, src, dst, layer), + Some(secondary_index) => { + self.graph + .delete_edge((timestamp, secondary_index), src, dst, layer) + } + } } //FIXME: This is reimplemented here to get mutable views. If we switch the underlying graph to enum dispatch, this won't be necessary! diff --git a/raphtory/src/python/graph/node.rs b/raphtory/src/python/graph/node.rs index 9bd320199..f7cc7aa16 100644 --- a/raphtory/src/python/graph/node.rs +++ b/raphtory/src/python/graph/node.rs @@ -371,15 +371,28 @@ impl PyMutableNode { /// This function allows for the addition of property updates to a node within the graph. The updates are time-stamped, meaning they are applied at the specified time. /// /// Parameters: - /// t (TimeInput): The timestamp at which the updates should be applied. - /// properties (PropInput): A dictionary of properties to update. Each key is a string representing the property name, and each value is of type Prop representing the property value. If None, no properties are updated. - #[pyo3(signature = (t, properties=None))] + /// t (TimeInput): The timestamp at which the updates should be applied. + /// properties (PropInput): A dictionary of properties to update. Each key is a string representing the property name, and each value is of type Prop representing the property value. If None, no properties are updated. + /// secondary_index (int, optional): The optional integer which will be used as a secondary index + /// + /// Returns: + /// None: This function does not return a value, if the operation is successful. + /// + /// Raises: + /// GraphError: If the operation fails. + #[pyo3(signature = (t, properties=None, secondary_index=None))] pub fn add_updates( &self, t: PyTime, properties: Option>, + secondary_index: Option, ) -> Result<(), GraphError> { - self.node.add_updates(t, properties.unwrap_or_default()) + match secondary_index { + None => self.node.add_updates(t, properties.unwrap_or_default()), + Some(secondary_index) => self + .node + .add_updates((t, secondary_index), properties.unwrap_or_default()), + } } /// Add constant properties to a node in the graph.