Source code for kosmos.topology.net

from collections.abc import Iterable
from dataclasses import dataclass, field

from kosmos.topology.link import Link, LinkId
from kosmos.topology.node import Node, NodeId
from kosmos.topology.typing import LinkReference, NodeReference


[docs] @dataclass class Network: """Network that stores nodes and links.""" _nodes: dict[NodeId, Node] = field(default_factory=dict) _links: dict[LinkId, Link] = field(default_factory=dict) _node_links: dict[NodeId, list[Link]] = field(default_factory=dict)
[docs] def add_node(self, node: Node) -> None: """Add a node to the network. Args: node (Node): Node instance to insert. """ if node.id in self._nodes: msg = f"Node '{node.id.value}' already exists." raise ValueError(msg) self._nodes[node.id] = node self._node_links.setdefault(node.id, [])
[docs] def get_node(self, node_id: NodeId | str) -> Node | None: """Node by id. Args: node_id (NodeId | str): Identifier of the node. Returns: Node | None: The node if present, else None. """ if isinstance(node_id, str): return self._nodes.get(NodeId(node_id)) return self._nodes.get(node_id)
[docs] def nodes(self) -> Iterable[Node]: """Iterate over all nodes. Returns: Iterable[Node]: Iterator over nodes. """ return self._nodes.values()
[docs] def validate_node(self, node: NodeReference) -> Node: """Get the node for a node reference if it is valid, else raise. Args: node (NodeReference): The node or its id. Returns: Node: The valid node. """ node_id = self._get_valid_node_id(node) return self._nodes.get(node_id)
def _get_valid_node_id(self, node: NodeReference) -> NodeId: """Get the NodeId for a node reference if the node is present in the network, else raise. Args: node (NodeReference): The node or its id. Returns: NodeId: The node id. """ if isinstance(node, Node) and node not in self.nodes(): msg = f"Node {node} with id '{node.id}' is not present in the network." raise ValueError(msg) node_id = ( node.id if isinstance(node, Node) else NodeId(node) if isinstance(node, str) else node ) if node_id not in self._nodes: msg = f"Node with id '{node_id}' is not present in the network." raise ValueError(msg) return node_id def _get_valid_link_id(self, link: LinkReference) -> LinkId: """Get the LinkId for a link reference if the link is present in the network, else raise. Args: link (LinkReference): The link or its id. Returns: LinkId: The link id. """ if isinstance(link, Link) and link not in self.links(): msg = f"Link {link} with id '{link.id}' is not present in the network." raise ValueError(msg) link_id = ( link.id if isinstance(link, Link) else LinkId(link) if isinstance(link, str) else link ) if link_id not in self._links: msg = f"Link with id '{link_id}' is not present in the network." raise ValueError(msg) return link_id