p4net 0.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
p4net/__init__.py ADDED
@@ -0,0 +1,6 @@
1
+ """p4net: a P4Runtime-native SDN simulation framework."""
2
+
3
+ from p4net.network import Network
4
+
5
+ __all__ = ["Network", "__version__"]
6
+ __version__ = "0.2.0"
p4net/__main__.py ADDED
@@ -0,0 +1,6 @@
1
+ """Allow `python -m p4net <args>` to run the same entry point as the console script."""
2
+
3
+ from p4net.cli.main import main
4
+
5
+ if __name__ == "__main__":
6
+ raise SystemExit(main())
p4net/cli/__init__.py ADDED
@@ -0,0 +1,13 @@
1
+ """Interactive p4net CLI: dispatcher, shell, completer, console script."""
2
+
3
+ from p4net.cli.dispatcher import CommandDispatcher
4
+ from p4net.cli.exceptions import CLIError, CLIExit, CLIUsageError
5
+ from p4net.cli.shell import P4NetShell
6
+
7
+ __all__ = [
8
+ "CLIError",
9
+ "CLIExit",
10
+ "CLIUsageError",
11
+ "CommandDispatcher",
12
+ "P4NetShell",
13
+ ]
@@ -0,0 +1,46 @@
1
+ """prompt_toolkit completer for the p4net shell."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import TYPE_CHECKING
6
+
7
+ from prompt_toolkit.completion import NestedCompleter
8
+
9
+ if TYPE_CHECKING:
10
+ from p4net.cli.dispatcher import CommandDispatcher
11
+
12
+
13
+ def build_network_completer(dispatcher: CommandDispatcher) -> NestedCompleter:
14
+ """Build a NestedCompleter that knows about commands, hosts, and switches."""
15
+ nested: dict[str, dict[str, None] | None] = {}
16
+ for cmd in dispatcher.command_names:
17
+ nested[cmd] = None
18
+ # `topology` has one sub-verb so far: `graph`.
19
+ if "topology" in nested:
20
+ nested["topology"] = {"graph": None}
21
+ # Host commands: <host> [ping|ping6|cmd|ifconfig|xterm]
22
+ host_subs = _host_subcommands_for(dispatcher)
23
+ for name in dispatcher.host_names:
24
+ nested[name] = dict.fromkeys(host_subs, None)
25
+ # Switch commands.
26
+ for name in dispatcher.switch_names:
27
+ nested[name] = dict.fromkeys(_switch_subcommands_for(dispatcher), None)
28
+ return NestedCompleter.from_nested_dict(nested)
29
+
30
+
31
+ def _switch_subcommands_for(dispatcher: CommandDispatcher) -> list[str]:
32
+ """Read the dispatcher's switch handler keys at completer-build time.
33
+
34
+ Phase-2 ships an empty handler map; phase-3 fills it in. This helper
35
+ keeps the completer in sync without requiring two import paths.
36
+ """
37
+ # `_switch_handlers` is private but stable; the alternative is duplicating
38
+ # the verb list, which would drift.
39
+ handlers = getattr(dispatcher, "_switch_handlers", {})
40
+ return sorted(handlers.keys())
41
+
42
+
43
+ def _host_subcommands_for(dispatcher: CommandDispatcher) -> list[str]:
44
+ """Same idea for host verbs."""
45
+ handlers = getattr(dispatcher, "_host_handlers", {})
46
+ return sorted(handlers.keys())