Skip to content

Commit 8b679da

Browse files
committed
Integrate NetworkView into workflow steps. Update docs.
1 parent 366ed59 commit 8b679da

16 files changed

Lines changed: 1000 additions & 428 deletions

docs/examples/network_view.md

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
# NetworkView Example
2+
3+
This example demonstrates how to use `NetworkView` for temporary exclusion simulation and concurrent network analysis without modifying the base network.
4+
5+
## Basic Usage
6+
7+
```python
8+
from ngraph.network import Network, Node, Link
9+
from ngraph.network_view import NetworkView
10+
11+
# Create a network
12+
net = Network()
13+
net.add_node(Node("A"))
14+
net.add_node(Node("B"))
15+
net.add_node(Node("C"))
16+
net.add_link(Link("A", "B", capacity=100.0))
17+
net.add_link(Link("B", "C", capacity=100.0))
18+
19+
# Create a view with node A excluded
20+
view = NetworkView.from_excluded_sets(
21+
net,
22+
excluded_nodes=["A"],
23+
excluded_links=[]
24+
)
25+
26+
# Analyze capacity with exclusion
27+
flow = view.max_flow("^A$", "^C$", mode="combine")
28+
print(f"Flow with A excluded: {flow}") # Will be 0.0
29+
30+
# Original network is unchanged
31+
assert not net.nodes["A"].disabled
32+
```
33+
34+
## Workflow Integration
35+
36+
### CapacityProbe with Exclusions
37+
38+
```yaml
39+
workflow:
40+
- step_type: CapacityProbe
41+
name: "probe_with_exclusions"
42+
source_path: "^spine.*"
43+
sink_path: "^leaf.*"
44+
excluded_nodes: ["spine1", "spine2"]
45+
excluded_links: ["link123"]
46+
```
47+
48+
### NetworkStats with Exclusions
49+
50+
```python
51+
from ngraph.workflow.network_stats import NetworkStats
52+
53+
# Get statistics with temporary exclusions
54+
stats = NetworkStats(
55+
name="filtered_stats",
56+
excluded_nodes=["node1", "node2"],
57+
excluded_links=["link1"]
58+
)
59+
stats.run(scenario)
60+
```
61+
62+
## Concurrent Analysis
63+
64+
```python
65+
# Create multiple views for concurrent analysis
66+
view1 = NetworkView.from_excluded_sets(net, excluded_nodes=["A"])
67+
view2 = NetworkView.from_excluded_sets(net, excluded_nodes=["B"])
68+
view3 = NetworkView.from_excluded_sets(net, excluded_nodes=["C"])
69+
70+
# Run concurrent analyses
71+
results = []
72+
for view in [view1, view2, view3]:
73+
flow = view.max_flow("^A$", "^C$", mode="combine")
74+
results.append(flow)
75+
76+
# Each view operates independently
77+
print(f"Results: {results}")
78+
```
79+
80+
## CapacityEnvelopeAnalysis Integration
81+
82+
The `CapacityEnvelopeAnalysis` workflow step now uses `NetworkView` internally:
83+
84+
```python
85+
from ngraph.workflow.capacity_envelope_analysis import CapacityEnvelopeAnalysis
86+
87+
# This uses NetworkView internally for each Monte Carlo iteration
88+
envelope = CapacityEnvelopeAnalysis(
89+
source_path="^spine.*",
90+
sink_path="^leaf.*",
91+
failure_policy="random_failures",
92+
iterations=1000,
93+
parallelism=8 # Safe concurrent execution
94+
)
95+
```
96+
97+
## Key Benefits
98+
99+
1. **Immutability**: Base network remains unchanged during analysis
100+
2. **Concurrency**: Multiple views can analyze the same network simultaneously
101+
3. **Performance**: Selective caching provides ~30x speedup for repeated operations
102+
4. **Consistency**: Combines scenario-disabled and analysis-excluded elements seamlessly
103+
104+
## Best Practices
105+
106+
1. Use `NetworkView` for all temporary exclusion analysis
107+
2. Use `Network.disable_node()` only for persistent scenario configuration
108+
3. Create new NetworkView instances for each analysis - they're lightweight
109+
4. Leverage parallelism - NetworkView enables safe concurrent analysis

docs/reference/api-full.md

Lines changed: 71 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ For a curated, example-driven API guide, see **[api.md](api.md)**.
1010
> - **[CLI Reference](cli.md)** - Command-line interface
1111
> - **[DSL Reference](dsl.md)** - YAML syntax guide
1212
13-
**Generated from source code on:** July 05, 2025 at 19:29 UTC
13+
**Generated from source code on:** July 05, 2025 at 20:14 UTC
1414

1515
**Modules auto-discovered:** 51
1616

@@ -317,25 +317,41 @@ FailureManager class for running Monte Carlo failure simulations.
317317

318318
### FailureManager
319319

320-
Applies FailurePolicy to a Network, runs traffic placement, and (optionally)
321-
repeats multiple times for Monte Carlo experiments.
320+
Applies a FailurePolicy to a Network to determine exclusions, then uses a
321+
NetworkView to simulate the impact of those exclusions on traffic.
322+
323+
This class is the orchestrator for failure analysis. It does not modify the
324+
base Network. Instead, it:
325+
1. Uses a FailurePolicy to calculate which nodes/links should be excluded.
326+
2. Creates a NetworkView with those exclusions.
327+
3. Runs traffic placement against the view using a TrafficManager.
328+
329+
The use of NetworkView ensures:
330+
- Base network remains unmodified during analysis
331+
- Concurrent Monte Carlo simulations can run safely in parallel
332+
- Clear separation between scenario-disabled elements (persistent) and
333+
analysis-excluded elements (temporary)
334+
335+
For concurrent analysis, prefer using NetworkView directly rather than
336+
FailureManager when you need fine-grained control over exclusions.
322337

323338
Attributes:
324-
network (Network): The underlying network to mutate (enable/disable nodes/links).
325-
traffic_matrix_set (TrafficMatrixSet): Traffic matrices to place after failures.
339+
network (Network): The underlying network (not modified).
340+
traffic_matrix_set (TrafficMatrixSet): Traffic matrices to place after exclusions.
326341
failure_policy_set (FailurePolicySet): Set of named failure policies.
327-
matrix_name (Optional[str]): Name of specific matrix to use, or None for default.
342+
matrix_name (Optional[str]): The specific traffic matrix to use from the set.
328343
policy_name (Optional[str]): Name of specific failure policy to use, or None for default.
329-
default_flow_policy_config: The default flow policy for any demands lacking one.
344+
default_flow_policy_config (Optional[FlowPolicyConfig]): Default flow placement
345+
policy if not specified elsewhere.
330346

331347
**Methods:**
332348

333-
- `apply_failures(self) -> 'None'`
334-
- Apply the current failure policy to self.network (in-place).
349+
- `get_failed_entities(self) -> 'Tuple[List[str], List[str]]'`
350+
- Get the nodes and links that are designated for exclusion by the current policy.
335351
- `run_monte_carlo_failures(self, iterations: 'int', parallelism: 'int' = 1) -> 'Dict[str, Any]'`
336-
- Repeatedly applies (randomized) failures to the network and accumulates
352+
- Repeatedly runs failure scenarios and accumulates traffic placement results.
337353
- `run_single_failure_scenario(self) -> 'List[TrafficResult]'`
338-
- Applies failures to the network, places the demands, and returns per-demand results.
354+
- Runs one iteration of a failure scenario.
339355

340356
---
341357

@@ -573,6 +589,11 @@ Attributes:
573589

574590
A container for network nodes and links.
575591

592+
Network represents the scenario-level topology with persistent state (nodes/links
593+
that are disabled in the scenario configuration). For temporary exclusion of
594+
nodes/links during analysis (e.g., failure simulation), use NetworkView instead
595+
of modifying the Network's disabled states.
596+
576597
Attributes:
577598
nodes (Dict[str, Node]): Mapping from node name -> Node object.
578599
links (Dict[str, Link]): Mapping from link ID -> Link object.
@@ -677,7 +698,11 @@ Returns:
677698

678699
## ngraph.network_view
679700

680-
NetworkView class for read-only filtered access to Network objects.
701+
NetworkView provides a read-only view of a Network with temporary exclusions.
702+
703+
This module implements a lightweight view pattern for Network objects, allowing
704+
temporary exclusion of nodes and links without modifying the underlying network.
705+
This is useful for what-if analysis, including failure simulations.
681706

682707
### NetworkView
683708

@@ -694,10 +719,10 @@ concurrently, each with different exclusion sets.
694719
Example:
695720
```python
696721
# Create view excluding specific nodes for failure analysis
697-
view = NetworkView.from_failure_sets(
722+
view = NetworkView.from_excluded_sets(
698723
base_network,
699-
failed_nodes=["node1", "node2"],
700-
failed_links=["link1"]
724+
excluded_nodes=["node1", "node2"],
725+
excluded_links=["link1"]
701726
)
702727

703728
# Run analysis on filtered topology
@@ -717,8 +742,8 @@ Attributes:
717742

718743
**Methods:**
719744

720-
- `from_failure_sets(base: "'Network'", failed_nodes: 'Iterable[str]' = (), failed_links: 'Iterable[str]' = ()) -> "'NetworkView'"`
721-
- Create a NetworkView with specified failure exclusions.
745+
- `from_excluded_sets(base: "'Network'", excluded_nodes: 'Iterable[str]' = (), excluded_links: 'Iterable[str]' = ()) -> "'NetworkView'"`
746+
- Create a NetworkView with specified exclusions.
722747
- `is_link_hidden(self, link_id: 'str') -> 'bool'`
723748
- Check if a link is hidden in this view.
724749
- `is_node_hidden(self, name: 'str') -> 'bool'`
@@ -1118,7 +1143,7 @@ that TrafficDemand's `demand` value (unless no valid node pairs exist, in which
11181143
case no demands are created).
11191144

11201145
Attributes:
1121-
network (Network): The underlying network object.
1146+
network (Union[Network, NetworkView]): The underlying network or view object.
11221147
traffic_matrix_set (TrafficMatrixSet): Traffic matrices containing demands.
11231148
matrix_name (Optional[str]): Name of specific matrix to use, or None for default.
11241149
default_flow_policy_config (FlowPolicyConfig): Default FlowPolicy if
@@ -1130,29 +1155,29 @@ Attributes:
11301155

11311156
**Attributes:**
11321157

1133-
- `network` (Network)
1134-
- `traffic_matrix_set` (TrafficMatrixSet)
1135-
- `matrix_name` (Optional)
1158+
- `network` (Union[Network, 'NetworkView'])
1159+
- `traffic_matrix_set` ('TrafficMatrixSet')
1160+
- `matrix_name` (Optional[str])
11361161
- `default_flow_policy_config` (FlowPolicyConfig) = 1
1137-
- `graph` (Optional)
1138-
- `demands` (List) = []
1139-
- `_td_to_demands` (Dict) = {}
1162+
- `graph` (Optional[StrictMultiDiGraph])
1163+
- `demands` (List[Demand]) = []
1164+
- `_td_to_demands` (Dict[str, List[Demand]]) = {}
11401165

11411166
**Methods:**
11421167

1143-
- `build_graph(self, add_reverse: bool = True) -> None`
1168+
- `build_graph(self, add_reverse: 'bool' = True) -> 'None'`
11441169
- Builds or rebuilds the internal StrictMultiDiGraph from self.network.
1145-
- `expand_demands(self) -> None`
1170+
- `expand_demands(self) -> 'None'`
11461171
- Converts each TrafficDemand in the active matrix into one or more
1147-
- `get_flow_details(self) -> Dict[Tuple[int, int], Dict[str, object]]`
1172+
- `get_flow_details(self) -> 'Dict[Tuple[int, int], Dict[str, object]]'`
11481173
- Summarizes flows from each Demand's FlowPolicy.
1149-
- `get_traffic_results(self, detailed: bool = False) -> List[ngraph.traffic_manager.TrafficResult]`
1174+
- `get_traffic_results(self, detailed: 'bool' = False) -> 'List[TrafficResult]'`
11501175
- Returns traffic demand summaries.
1151-
- `place_all_demands(self, placement_rounds: Union[int, str] = 'auto', reoptimize_after_each_round: bool = False) -> float`
1176+
- `place_all_demands(self, placement_rounds: 'Union[int, str]' = 'auto', reoptimize_after_each_round: 'bool' = False) -> 'float'`
11521177
- Places all expanded demands in ascending priority order using multiple
1153-
- `reset_all_flow_usages(self) -> None`
1178+
- `reset_all_flow_usages(self) -> 'None'`
11541179
- Removes flow usage from the graph for each Demand's FlowPolicy
1155-
- `summarize_link_usage(self) -> Dict[str, float]`
1180+
- `summarize_link_usage(self) -> 'Dict[str, float]'`
11561181
- Returns the total flow usage per edge in the graph.
11571182

11581183
### TrafficResult
@@ -2232,6 +2257,8 @@ Capacity probing workflow component.
22322257

22332258
A workflow step that probes capacity (max flow) between selected groups of nodes.
22342259

2260+
Supports optional exclusion simulation using NetworkView without modifying the base network.
2261+
22352262
YAML Configuration:
22362263
```yaml
22372264
workflow:
@@ -2243,6 +2270,8 @@ YAML Configuration:
22432270
probe_reverse: false # Also compute flow in reverse direction
22442271
shortest_path: false # Use shortest paths only
22452272
flow_placement: "PROPORTIONAL" # "PROPORTIONAL" or "EQUAL_BALANCED"
2273+
excluded_nodes: ["node1", "node2"] # Optional: Nodes to exclude for analysis
2274+
excluded_links: ["link1"] # Optional: Links to exclude for analysis
22462275
```
22472276

22482277
Attributes:
@@ -2254,6 +2283,8 @@ Attributes:
22542283
probe_reverse: If True, also compute flow in the reverse direction (sink→source).
22552284
shortest_path: If True, only use shortest paths when computing flow.
22562285
flow_placement: Handling strategy for parallel equal cost paths (default PROPORTIONAL).
2286+
excluded_nodes: Optional list of node names to exclude (temporary exclusion).
2287+
excluded_links: Optional list of link IDs to exclude (temporary exclusion).
22572288

22582289
**Attributes:**
22592290

@@ -2265,6 +2296,8 @@ Attributes:
22652296
- `probe_reverse` (bool) = False
22662297
- `shortest_path` (bool) = False
22672298
- `flow_placement` (FlowPlacement) = 1
2299+
- `excluded_nodes` (Iterable[str]) = ()
2300+
- `excluded_links` (Iterable[str]) = ()
22682301

22692302
**Methods:**
22702303

@@ -2283,22 +2316,28 @@ Workflow step for basic node and link statistics.
22832316

22842317
Compute basic node and link statistics for the network.
22852318

2319+
Supports optional exclusion simulation using NetworkView without modifying the base network.
2320+
22862321
Attributes:
22872322
include_disabled (bool): If True, include disabled nodes and links in statistics.
22882323
If False, only consider enabled entities. Defaults to False.
2324+
excluded_nodes: Optional list of node names to exclude (temporary exclusion).
2325+
excluded_links: Optional list of link IDs to exclude (temporary exclusion).
22892326

22902327
**Attributes:**
22912328

22922329
- `name` (str)
22932330
- `seed` (Optional[int])
22942331
- `include_disabled` (bool) = False
2332+
- `excluded_nodes` (Iterable[str]) = ()
2333+
- `excluded_links` (Iterable[str]) = ()
22952334

22962335
**Methods:**
22972336

22982337
- `execute(self, scenario: "'Scenario'") -> 'None'`
22992338
- Execute the workflow step with automatic logging.
23002339
- `run(self, scenario: 'Scenario') -> 'None'`
2301-
- Collect capacity and degree statistics.
2340+
- Compute and store network statistics.
23022341

23032342
---
23042343

0 commit comments

Comments
 (0)