|
4 | 4 |
|
5 | 5 | [](https://github.com/networmix/NetGraph/actions/workflows/python-test.yml) |
6 | 6 |
|
7 | | -- [Introduction](#introduction) |
8 | | -- [Installation and Usage](#installation-and-usage) |
9 | | - - [Using the Docker Container with JupyterLab](#1-using-the-docker-container-with-jupyterlab) |
10 | | - - [Using the Python Package](#2-using-the-python-package) |
11 | | -- [Use Case Examples](#use-case-examples) |
12 | | - - [Calculate MaxFlow between two 3-tier Clos networks](#calculate-maxflow-between-two-3-tier-clos-networks) |
13 | | ---- |
| 7 | +NetGraph is a scenario-based network modeling and analysis framework written in Python. Design, simulate, and evaluate complex network topologies from small test cases to massive Data Center fabrics and WAN networks. |
14 | 8 |
|
15 | | -## Introduction |
16 | | - |
17 | | -NetGraph is a scenario-based network modeling and analysis framework written in Python. It allows you to design, simulate, and evaluate complex network topologies - ranging from small test cases to massive Data Center fabrics and WAN networks. |
18 | | - |
19 | | -You can load an entire scenario from a single YAML file (including topology, failure policies, traffic demands, multi-step workflows) and run it in just a few lines of Python. The results can then be explored, visualized, and refined — making NetGraph well-suited for iterative network design, traffic engineering experiments, and what-if scenario analysis in large-scale topologies. |
20 | | - |
21 | | -### Core Concepts |
22 | | - |
23 | | -- **Topology Language and Hierarchical Blueprints**: |
24 | | -NetGraph includes a domain-specific language for describing topologies via “blueprints.” These blueprints can be nested and reused, letting you define node groups and their interconnects in a hierarchical manner. Connectivity patterns (e.g., "mesh", "one_to_one") and complex expansions (e.g., dc[1-3, 5-6]) let you scale out large topologies with minimal repetition. |
25 | | - |
26 | | -- **Scenario-Based Workflows**: |
27 | | -A Scenario is the main entry point for building and running network analyses: it encapsulates the topology, failure policies, traffic demands, and workflow steps. A Scenario can be loaded from a YAML file or created programmatically, and it can be run in a single step or iteratively to explore different configurations. |
28 | | - |
29 | | -- **Low-Level Library**: |
30 | | -Under the hood, NetGraph provides robust primitives for building and analyzing network graphs, calculating flows, placing traffic demands, and enforcing traffic engineering policies. This library is used by the scenario-based workflows, but it can also be used independently. |
31 | | - |
32 | | ---- |
33 | | - |
34 | | -## Installation and Usage |
35 | | - |
36 | | -NetGraph can be used in two ways: |
37 | | -- **Using the Docker Container with JupyterLab**: This is the easiest way to get started with NetGraph, as it provides a pre-configured environment with JupyterLab and all dependencies installed. |
38 | | -- **Using the Python Package**: If you prefer to use NetGraph in your own Python environment, you can install the package using pip and use it in your Python code. |
39 | | - |
40 | | -### 1. Using the Docker Container with JupyterLab |
41 | | - |
42 | | -**Prerequisites:** |
43 | | - |
44 | | -- [Docker](https://docs.docker.com/get-docker/) installed on your machine. |
45 | | - |
46 | | -**Steps:** |
47 | | - |
48 | | -1. Clone the repository: |
49 | | - |
50 | | - ```bash |
51 | | - git clone https://github.com/networmix/NetGraph |
52 | | - ``` |
53 | | - |
54 | | -2. Build the Docker image: |
55 | | - |
56 | | - ```bash |
57 | | - cd NetGraph |
58 | | - ./run.sh build |
59 | | - ``` |
60 | | - |
61 | | -3. Start the container with JupyterLab server: |
62 | | - |
63 | | - ```bash |
64 | | - ./run.sh run |
65 | | - ``` |
66 | | - |
67 | | -4. Open the JupyterLab URL in your browser: |
68 | | - |
69 | | - ```bash |
70 | | - http://127.0.0.1:8788/ |
71 | | - ``` |
72 | | - |
73 | | -5. Jupyter will show the content of `notebooks` directory and you can start using the provided notebooks (e.g., open scenario_dc.ipynb) or create your own. |
74 | | - |
75 | | -**Note**: Docker is instructed to mount the content of `NetGraph` directory into the `/root/env` directory inside container, so any changes made to any files in the `NetGraph` directory will be reflected in the container and vice versa. The `ngraph` package is installed in the container in editable mode, so you can make changes to the code and leverage them immediately in JupyterLab. But don't forget to restart the JupyterLab kernel to see the changes. |
76 | | -
|
77 | | -To exit the JupyterLab server, press `Ctrl+C` in the terminal where the server is running. To stop the remaining Docker container, run: |
| 9 | +## Quick Start |
78 | 10 |
|
79 | 11 | ```bash |
80 | | -./run.sh stop |
| 12 | +pip install ngraph |
81 | 13 | ``` |
82 | 14 |
|
83 | | -### 2. Using the Python Package |
84 | | -
|
85 | | -**Prerequisites:** |
86 | | -
|
87 | | -- Python 3.10 or higher installed on your machine. |
| 15 | +```python |
| 16 | +from ngraph.scenario import Scenario |
88 | 17 |
|
89 | | -Note: Don't forget to use a virtual environment (e.g., `venv`) to avoid conflicts with other Python packages. See [Python Virtual Environments](https://docs.python.org/3/library/venv.html) for more information. |
| 18 | +scenario_yaml = """ |
| 19 | +network: |
| 20 | + groups: |
| 21 | + servers: |
| 22 | + node_count: 4 |
| 23 | + name_template: "server-{node_num}" |
| 24 | + switches: |
| 25 | + node_count: 2 |
| 26 | + name_template: "switch-{node_num}" |
| 27 | + adjacency: |
| 28 | + - source: /servers |
| 29 | + target: /switches |
| 30 | + pattern: mesh |
| 31 | +""" |
90 | 32 |
|
91 | | -**Steps:** |
| 33 | +scenario = Scenario.from_yaml(scenario_yaml) |
| 34 | +network = scenario.network |
| 35 | +print(f"Created network with {len(network.nodes)} nodes and {len(network.links)} links") |
| 36 | +``` |
92 | 37 |
|
93 | | -1. Install the package using pip: |
| 38 | +## Key Features |
94 | 39 |
|
95 | | - ```bash |
96 | | - pip install ngraph |
97 | | - ``` |
| 40 | +- **Scenario-Based Modeling**: Define complete network scenarios in YAML with topology, failures, traffic, and workflows |
| 41 | +- **Hierarchical Blueprints**: Reusable network templates with nested structures and bracket expansion |
| 42 | +- **Flow Analysis**: Calculate max flows, shortest paths, and capacity with ECMP/UCMP support |
| 43 | +- **Failure Simulation**: Model component failures and risk groups for availability analysis |
| 44 | +- **Traffic Engineering**: Define traffic demands with various placement policies |
| 45 | +- **Rich Visualization**: Explore network topology and analyze results interactively |
98 | 46 |
|
99 | | -2. Use the package in your Python code: |
| 47 | +## Documentation |
100 | 48 |
|
101 | | - ```python |
102 | | - from ngraph.scenario import Scenario |
103 | | - from ngraph.explorer import NetworkExplorer |
104 | | - scenario_yaml = """ |
105 | | - <describe your scenario here> |
106 | | - """ |
107 | | - scenario = Scenario.from_yaml(scenario_yaml) |
108 | | - scenario.run() |
109 | | - network = scenario.network |
110 | | - explorer = NetworkExplorer.explore_network(network) |
111 | | - explorer.print_tree(skip_leaves=True, detailed=False) |
112 | | - ``` |
| 49 | +📚 **[Full Documentation](https://networmix.github.io/NetGraph/)** |
113 | 50 |
|
114 | | -## Use Case Examples |
| 51 | +- **[Installation Guide](https://networmix.github.io/NetGraph/getting-started/installation/)** - Docker and pip installation |
| 52 | +- **[Quick Tutorial](https://networmix.github.io/NetGraph/getting-started/tutorial/)** - Build your first scenario |
| 53 | +- **[Examples](https://networmix.github.io/NetGraph/examples/)** - Clos fabrics, WAN networks, and more |
| 54 | +- **[DSL Reference](https://networmix.github.io/NetGraph/reference/dsl/)** - Complete YAML syntax |
| 55 | +- **[API Reference](https://networmix.github.io/NetGraph/reference/api/)** - Python API documentation |
115 | 56 |
|
116 | | -### Calculate MaxFlow between two 3-tier Clos networks |
| 57 | +## Quick Example: Clos Fabric Analysis |
117 | 58 |
|
118 | 59 | ```python |
119 | 60 | from ngraph.scenario import Scenario |
120 | 61 | from ngraph.lib.flow_policy import FlowPlacement |
121 | | -scenario_yaml = """ |
122 | | -blueprints: |
123 | | - brick_2tier: |
124 | | - groups: |
125 | | - t1: |
126 | | - node_count: 8 |
127 | | - name_template: t1-{node_num} |
128 | | - t2: |
129 | | - node_count: 8 |
130 | | - name_template: t2-{node_num} |
131 | | -
|
132 | | - adjacency: |
133 | | - - source: /t1 |
134 | | - target: /t2 |
135 | | - pattern: mesh |
136 | | - link_params: |
137 | | - capacity: 2 |
138 | | - cost: 1 |
139 | | -
|
140 | | - 3tier_clos: |
141 | | - groups: |
142 | | - b1: |
143 | | - use_blueprint: brick_2tier |
144 | | - b2: |
145 | | - use_blueprint: brick_2tier |
146 | | - spine: |
147 | | - node_count: 64 |
148 | | - name_template: t3-{node_num} |
149 | | -
|
150 | | - adjacency: |
151 | | - - source: b1/t2 |
152 | | - target: spine |
153 | | - pattern: one_to_one |
154 | | - link_params: |
155 | | - capacity: 2 |
156 | | - cost: 1 |
157 | | - - source: b2/t2 |
158 | | - target: spine |
159 | | - pattern: one_to_one |
160 | | - link_params: |
161 | | - capacity: 2 |
162 | | - cost: 1 |
163 | | -
|
164 | | -network: |
165 | | - name: "3tier_clos_network" |
166 | | - version: 1.0 |
167 | | -
|
168 | | - groups: |
169 | | - my_clos1: |
170 | | - use_blueprint: 3tier_clos |
171 | | -
|
172 | | - my_clos2: |
173 | | - use_blueprint: 3tier_clos |
174 | 62 |
|
175 | | - adjacency: |
176 | | - - source: my_clos1/spine |
177 | | - target: my_clos2/spine |
178 | | - pattern: one_to_one |
179 | | - link_count: 4 |
180 | | - link_params: |
181 | | - capacity: 1 |
182 | | - cost: 1 |
183 | | -""" |
184 | | -scenario = Scenario.from_yaml(scenario_yaml) |
| 63 | +# Define a 3-tier Clos network with inter-fabric connectivity |
| 64 | +scenario = Scenario.from_yaml(clos_scenario_yaml) |
185 | 65 | network = scenario.network |
186 | | -network.max_flow( |
187 | | - source_path=r"my_clos1.*(b[0-9]*)/t1", |
188 | | - sink_path=r"my_clos2.*(b[0-9]*)/t1", |
| 66 | + |
| 67 | +# Calculate maximum flow with ECMP |
| 68 | +max_flow = network.max_flow( |
| 69 | + source_path=r"clos1.*(tier1)/servers", |
| 70 | + sink_path=r"clos2.*(tier1)/servers", |
189 | 71 | mode="combine", |
190 | | - shortest_path=True, |
191 | | - flow_placement=FlowPlacement.EQUAL_BALANCED, |
| 72 | + flow_placement=FlowPlacement.EQUAL_BALANCED |
192 | 73 | ) |
| 74 | +# Result: {('tier1', 'tier1'): 256.0} |
| 75 | +``` |
| 76 | + |
| 77 | +## Development Setup |
| 78 | + |
| 79 | +### Docker (Recommended) |
| 80 | + |
| 81 | +```bash |
| 82 | +git clone https://github.com/networmix/NetGraph |
| 83 | +cd NetGraph |
| 84 | +./run.sh build |
| 85 | +./run.sh run # Opens JupyterLab at http://127.0.0.1:8788/ |
193 | 86 | ``` |
194 | | -Result is `{('b1|b2', 'b1|b2'): 256.0}`. It means that the maximum flow between all t1 nodes in `my_clos1` and all t1 nodes in `my_clos2` is 256.0. |
195 | 87 |
|
196 | | -Note that flow_placement parameter is set to FlowPlacement.EQUAL_BALANCED, which emulates ECMP. This means that the flow is distributed equally between all possible paths. If we were to disable three out of four links between any pair of spine routers (bringing the overal spine - spine capacity to 253.0), the overall flow in such ECMP scenario would be limited by this bottleneck and the maximum flow would be 64.0 (not 253). While setting flow_placement to FlowPlacement.PROPORTIONAL would result in the flow being distributed proportionally to the link capacities (emulation of UCMP). Resulting in the maximum flow of 253.0. |
| 88 | +### Local Installation |
| 89 | + |
| 90 | +```bash |
| 91 | +git clone https://github.com/networmix/NetGraph |
| 92 | +cd NetGraph |
| 93 | +python -m venv venv |
| 94 | +source venv/bin/activate # On Windows: venv\Scripts\activate |
| 95 | +pip install -e . |
| 96 | +``` |
| 97 | + |
| 98 | +## License |
| 99 | + |
| 100 | +[MIT License](LICENSE) |
0 commit comments