vantage6-node 4.15.1__tar.gz → 5.0.0__tar.gz

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.
Files changed (49) hide show
  1. vantage6_node-5.0.0/.gitignore +37 -0
  2. vantage6_node-5.0.0/Makefile +19 -0
  3. vantage6_node-5.0.0/PKG-INFO +50 -0
  4. vantage6_node-5.0.0/README.md +24 -0
  5. vantage6_node-5.0.0/dev_start.sh +43 -0
  6. vantage6_node-5.0.0/pyproject.toml +48 -0
  7. vantage6_node-5.0.0/tests_node/test_pod_status_mapping.py +131 -0
  8. vantage6_node-5.0.0/utest.py +13 -0
  9. vantage6_node-5.0.0/vantage6/dev_start.py +35 -0
  10. vantage6_node-5.0.0/vantage6/node/__init__.py +901 -0
  11. {vantage6_node-4.15.1 → vantage6_node-5.0.0}/vantage6/node/cli/node.py +25 -40
  12. vantage6_node-5.0.0/vantage6/node/enum.py +10 -0
  13. vantage6_node-5.0.0/vantage6/node/globals.py +60 -0
  14. vantage6_node-5.0.0/vantage6/node/k8s/container_manager.py +1804 -0
  15. vantage6_node-5.0.0/vantage6/node/k8s/data_classes.py +46 -0
  16. vantage6_node-5.0.0/vantage6/node/k8s/exceptions.py +50 -0
  17. vantage6_node-5.0.0/vantage6/node/k8s/jobpod_state_to_run_status_mapper.py +222 -0
  18. vantage6_node-5.0.0/vantage6/node/k8s/run_io.py +254 -0
  19. vantage6_node-5.0.0/vantage6/node/k8s/session_manager.py +160 -0
  20. {vantage6_node-4.15.1 → vantage6_node-5.0.0}/vantage6/node/proxy_server.py +66 -78
  21. {vantage6_node-4.15.1 → vantage6_node-5.0.0}/vantage6/node/socket.py +57 -22
  22. {vantage6_node-4.15.1 → vantage6_node-5.0.0}/vantage6/node/util/__init__.py +7 -0
  23. {vantage6_node-4.15.1 → vantage6_node-5.0.0}/vantage6/node/util/colorer.py +1 -24
  24. vantage6_node-4.15.1/PKG-INFO +0 -241
  25. vantage6_node-4.15.1/setup.cfg +0 -4
  26. vantage6_node-4.15.1/setup.py +0 -65
  27. vantage6_node-4.15.1/tests/test_ssh_tunnel.py +0 -0
  28. vantage6_node-4.15.1/vantage6/node/__build__ +0 -1
  29. vantage6_node-4.15.1/vantage6/node/__init__.py +0 -1310
  30. vantage6_node-4.15.1/vantage6/node/_version.py +0 -24
  31. vantage6_node-4.15.1/vantage6/node/context.py +0 -67
  32. vantage6_node-4.15.1/vantage6/node/docker/docker_base.py +0 -51
  33. vantage6_node-4.15.1/vantage6/node/docker/docker_manager.py +0 -996
  34. vantage6_node-4.15.1/vantage6/node/docker/exceptions.py +0 -28
  35. vantage6_node-4.15.1/vantage6/node/docker/squid.py +0 -284
  36. vantage6_node-4.15.1/vantage6/node/docker/ssh_tunnel.py +0 -306
  37. vantage6_node-4.15.1/vantage6/node/docker/task_manager.py +0 -968
  38. vantage6_node-4.15.1/vantage6/node/docker/utils.py +0 -44
  39. vantage6_node-4.15.1/vantage6/node/docker/vpn_manager.py +0 -714
  40. vantage6_node-4.15.1/vantage6/node/globals.py +0 -55
  41. vantage6_node-4.15.1/vantage6_node.egg-info/PKG-INFO +0 -241
  42. vantage6_node-4.15.1/vantage6_node.egg-info/SOURCES.txt +0 -29
  43. vantage6_node-4.15.1/vantage6_node.egg-info/dependency_links.txt +0 -1
  44. vantage6_node-4.15.1/vantage6_node.egg-info/entry_points.txt +0 -2
  45. vantage6_node-4.15.1/vantage6_node.egg-info/requires.txt +0 -21
  46. vantage6_node-4.15.1/vantage6_node.egg-info/top_level.txt +0 -2
  47. {vantage6_node-4.15.1/tests → vantage6_node-5.0.0/tests/docker}/__init__.py +0 -0
  48. {vantage6_node-4.15.1/tests/docker → vantage6_node-5.0.0/tests_node}/__init__.py +0 -0
  49. {vantage6_node-4.15.1 → vantage6_node-5.0.0}/vantage6/node/cli/__init__.py +0 -0
@@ -0,0 +1,37 @@
1
+
2
+ # documentation
3
+ docs/_build
4
+ docs/api-docs/_autosummary
5
+
6
+ # Python
7
+ .ipynb_checkpoints
8
+ **/__pycache__
9
+ **/.coverage
10
+
11
+ # IDE's
12
+ .idea/
13
+ *.sublime-project
14
+ *.sublime-workspace
15
+ .vscode/
16
+
17
+ # build files
18
+ **/build/
19
+ **/dist/
20
+ *.egg-info
21
+ *.code-workspace
22
+
23
+ # UI build files
24
+ **/node_modules/
25
+
26
+ # Ignore DevSpace cache and log folder
27
+ .devspace/
28
+ dev/.data/
29
+ dev/.tasks/
30
+ dev/.db/
31
+ dev/.log/
32
+
33
+ # Helm
34
+ charts/**/*.tgz
35
+
36
+ # MacOS
37
+ .DS_Store
@@ -0,0 +1,19 @@
1
+ # `make` is expected to be called from the directory that contains
2
+ # this Makefile
3
+
4
+ TAG ?= latest
5
+
6
+ rebuild: clean build-dist
7
+
8
+ build-dist:
9
+ # Build the PyPI package
10
+ uv build
11
+
12
+ publish:
13
+ # Uploading to pypi.org
14
+ twine upload --repository pypi dist/*
15
+
16
+ clean:
17
+ # Cleaning ...
18
+ -rm -r build
19
+ -rm dist/*
@@ -0,0 +1,50 @@
1
+ Metadata-Version: 2.4
2
+ Name: vantage6-node
3
+ Version: 5.0.0
4
+ Summary: vantage6 node
5
+ Author: Vantage6 Team
6
+ Maintainer-email: Frank Martin <f.martin@iknl.nl>, Bart van Beusekom <b.vanbeusekom@iknl.nl>
7
+ License: MIT
8
+ Requires-Python: >=3.13
9
+ Requires-Dist: click==8.1.3
10
+ Requires-Dist: gevent==25.4.2
11
+ Requires-Dist: jinja2==3.1.6
12
+ Requires-Dist: kubernetes==28.1.0
13
+ Requires-Dist: nvidia-ml-py==12.535.133
14
+ Requires-Dist: parquet-tools==0.2.16
15
+ Requires-Dist: psutil==7.0.0
16
+ Requires-Dist: python-socketio==5.15.0
17
+ Requires-Dist: requests==2.33.1
18
+ Requires-Dist: vantage6-client==5.0.0
19
+ Requires-Dist: vantage6-common==5.0.0
20
+ Requires-Dist: vantage6==5.0.0
21
+ Provides-Extra: dev
22
+ Requires-Dist: black; extra == 'dev'
23
+ Requires-Dist: coverage==7.10.2; extra == 'dev'
24
+ Requires-Dist: pre-commit; extra == 'dev'
25
+ Description-Content-Type: text/markdown
26
+
27
+ <h1 align="center">
28
+ <br>
29
+ <a href="https://vantage6.ai"><img src="https://github.com/IKNL/guidelines/blob/master/resources/logos/vantage6.png?raw=true" alt="vantage6" width="350"></a>
30
+ </h1>
31
+
32
+ <h3 align=center> A Privacy Enhancing Technology (PET) Operations platform</h3>
33
+
34
+ ---
35
+
36
+ # Vantage6 Node
37
+
38
+ This package contains the Vantage6 node application.
39
+
40
+ ## Documentation
41
+
42
+ For complete documentation, installation instructions, and usage examples, please see
43
+ the **[main Vantage6 README](https://github.com/vantage6/vantage6/blob/main/README.md)**
44
+ .
45
+
46
+ ## About Vantage6
47
+
48
+ Vantage6 is a Privacy Enhancing Technology (PET) Operations platform that enables
49
+ federated learning and multi-party computation. For more information, visit
50
+ [vantage6.ai](https://vantage6.ai) or our [documentation](https://docs.vantage6.ai).
@@ -0,0 +1,24 @@
1
+ <h1 align="center">
2
+ <br>
3
+ <a href="https://vantage6.ai"><img src="https://github.com/IKNL/guidelines/blob/master/resources/logos/vantage6.png?raw=true" alt="vantage6" width="350"></a>
4
+ </h1>
5
+
6
+ <h3 align=center> A Privacy Enhancing Technology (PET) Operations platform</h3>
7
+
8
+ ---
9
+
10
+ # Vantage6 Node
11
+
12
+ This package contains the Vantage6 node application.
13
+
14
+ ## Documentation
15
+
16
+ For complete documentation, installation instructions, and usage examples, please see
17
+ the **[main Vantage6 README](https://github.com/vantage6/vantage6/blob/main/README.md)**
18
+ .
19
+
20
+ ## About Vantage6
21
+
22
+ Vantage6 is a Privacy Enhancing Technology (PET) Operations platform that enables
23
+ federated learning and multi-party computation. For more information, visit
24
+ [vantage6.ai](https://vantage6.ai) or our [documentation](https://docs.vantage6.ai).
@@ -0,0 +1,43 @@
1
+ #!/bin/bash
2
+
3
+ # start a node for each config file the provided directory
4
+
5
+ config_dir=$1
6
+ if [ -z "$config_dir" ]; then
7
+ echo "Provide a configuration directory as argument"
8
+ exit 1
9
+ fi
10
+
11
+ # Remove trailing slashes from config_dir
12
+ config_dir=${config_dir%/}
13
+
14
+ for dir in $config_dir/*; do
15
+ if [ -d "$dir" ]; then
16
+ echo "Looking for node configurations in: $dir"
17
+
18
+ config=$(find "$dir" -maxdepth 1 -name "*.yaml" -type f)
19
+ dotenv_file="$dir"/.env
20
+
21
+ # Check if the config file exists
22
+ if [ ! -f "$config" ]; then
23
+ echo "No yaml config file found in $dir/*.yaml"
24
+ continue
25
+ fi
26
+
27
+ # Check if the .env file exists
28
+ if [ ! -f "$dotenv_file" ]; then
29
+ echo "No .env file found in $dir/.env"
30
+ continue
31
+ fi
32
+
33
+ # Source the .env file to set environment variables in their own shell as we
34
+ # start a new shell for each node
35
+ bash -c "source \"$dotenv_file\" && python /vantage6/vantage6-node/vantage6/dev_start.py \"$config\" &"
36
+ fi
37
+ done
38
+
39
+ # For development purposes, we put infinite sleep here. This has the advantage that
40
+ # once the node crashes, the container will keep running and therefore, the error will
41
+ # remain visible in the logs. A restart of the container would obfuscate the error
42
+ # which should not happen in development.
43
+ sleep infinity
@@ -0,0 +1,48 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "vantage6-node"
7
+ version = "5.0.0"
8
+ description = "vantage6 node"
9
+ readme = "README.md"
10
+ license = {text = "MIT"}
11
+ authors = [
12
+ {name = "Vantage6 Team"}
13
+ ]
14
+ maintainers = [
15
+ {name = "Frank Martin", email = "f.martin@iknl.nl"},
16
+ {name = "Bart van Beusekom", email = "b.vanbeusekom@iknl.nl"}
17
+ ]
18
+ requires-python = ">=3.13"
19
+ dependencies = [
20
+ "click==8.1.3",
21
+ "gevent==25.4.2",
22
+ "jinja2==3.1.6",
23
+ "kubernetes==28.1.0",
24
+ "nvidia-ml-py==12.535.133",
25
+ "parquet-tools==0.2.16",
26
+ "psutil==7.0.0",
27
+ "python-socketio==5.15.0",
28
+ "requests==2.33.1",
29
+ "vantage6==5.0.0",
30
+ "vantage6-client==5.0.0",
31
+ "vantage6-common==5.0.0",
32
+ ]
33
+
34
+ [project.optional-dependencies]
35
+ dev = [
36
+ "coverage==7.10.2",
37
+ "black",
38
+ "pre-commit",
39
+ ]
40
+
41
+ [project.scripts]
42
+ vnode-local = "vantage6.node.cli.node:cli_node"
43
+
44
+ [tool.hatch.build.targets.wheel]
45
+ packages = ["vantage6"]
46
+
47
+ [tool.hatch.build.targets.wheel.sources]
48
+ "vantage6" = "vantage6"
@@ -0,0 +1,131 @@
1
+ import logging
2
+ import unittest
3
+
4
+ from kubernetes.client import (
5
+ V1ContainerState,
6
+ V1ContainerStateRunning,
7
+ V1ContainerStateTerminated,
8
+ V1ContainerStateWaiting,
9
+ V1ContainerStatus,
10
+ V1Pod,
11
+ V1PodCondition,
12
+ V1PodStatus,
13
+ )
14
+
15
+ from vantage6.common.enum import RunStatus
16
+
17
+ from vantage6.node.k8s.jobpod_state_to_run_status_mapper import (
18
+ compute_run_pod_status,
19
+ )
20
+
21
+
22
+ def get_null_logger(name="null_logger"):
23
+ logger = logging.getLogger(name)
24
+ logger.addHandler(logging.NullHandler())
25
+ logger.propagate = False
26
+ return logger
27
+
28
+
29
+ class TestPodStatus(unittest.TestCase):
30
+ def setUp(self):
31
+ self.silent_logger = get_null_logger()
32
+
33
+ self.running_container_state = V1ContainerState(
34
+ running=V1ContainerStateRunning(started_at="")
35
+ )
36
+
37
+ self.waiting_container_state = V1ContainerState(
38
+ waiting=V1ContainerStateWaiting(reason="", message="")
39
+ )
40
+
41
+ self.terminated_container_state = V1ContainerState(
42
+ terminated=V1ContainerStateTerminated(exit_code=0, reason="")
43
+ )
44
+
45
+ self.mock_container_status = V1ContainerStatus(
46
+ name="",
47
+ ready=True,
48
+ restart_count=1,
49
+ image="",
50
+ image_id="",
51
+ container_id="",
52
+ state=None, # use running/waiting/terminated_container_state here
53
+ last_state=None,
54
+ )
55
+
56
+ self.mock_condition = V1PodCondition(type="", status="", reason="", message="")
57
+
58
+ self.mock_pod_status = V1PodStatus(
59
+ phase="",
60
+ reason="",
61
+ conditions=[self.mock_condition],
62
+ container_statuses=[self.mock_container_status],
63
+ )
64
+
65
+ self.mock_pod = V1Pod(metadata={"name": ""}, status=self.mock_pod_status)
66
+ pass
67
+
68
+ def test_running_job_pod(self):
69
+ self.mock_pod.status.phase = "Running"
70
+ self.assertEqual(
71
+ compute_run_pod_status(
72
+ log=self.silent_logger, task_namespace="", label="", pod=self.mock_pod
73
+ ),
74
+ RunStatus.ACTIVE,
75
+ )
76
+
77
+ def test_container_status_not_yet_defined(self):
78
+ self.mock_pod.status.phase = "Pending"
79
+ self.mock_pod.status.container_statuses = None
80
+ self.assertEqual(
81
+ compute_run_pod_status(
82
+ log=self.silent_logger, task_namespace="", label="", pod=self.mock_pod
83
+ ),
84
+ RunStatus.INITIALIZING,
85
+ )
86
+
87
+ def test_container_related_err(self):
88
+ self.mock_pod.status.phase = "Pending"
89
+ self.mock_pod.status.container_statuses[0].state = self.waiting_container_state
90
+ self.mock_pod.status.container_statuses[
91
+ 0
92
+ ].state.waiting.reason = "ImagePullBackOff"
93
+ self.assertEqual(
94
+ compute_run_pod_status(
95
+ log=self.silent_logger, task_namespace="", label="", pod=self.mock_pod
96
+ ),
97
+ RunStatus.NO_DOCKER_IMAGE,
98
+ )
99
+
100
+ def test_waiting_reason_not_ready_err(self):
101
+ self.mock_pod.status.phase = "Pending"
102
+ self.mock_pod.status.container_statuses[0].state = self.waiting_container_state
103
+ self.mock_pod.status.container_statuses[0].state.waiting = None
104
+ self.assertEqual(
105
+ compute_run_pod_status(
106
+ log=self.silent_logger, task_namespace="", label="", pod=self.mock_pod
107
+ ),
108
+ RunStatus.INITIALIZING,
109
+ )
110
+
111
+ def test_container_runtime_error(self):
112
+ self.mock_pod.status.phase = "Pending"
113
+ self.mock_pod.status.container_statuses[0].state = self.waiting_container_state
114
+ self.mock_pod.status.container_statuses[
115
+ 0
116
+ ].state.waiting.reason = "CrashLoopBackOff"
117
+ self.assertEqual(
118
+ compute_run_pod_status(
119
+ log=self.silent_logger, task_namespace="", label="", pod=self.mock_pod
120
+ ),
121
+ RunStatus.CRASHED,
122
+ )
123
+
124
+ def test_completed_job(self):
125
+ self.mock_pod.status.phase = "Succeded"
126
+ self.assertEqual(
127
+ compute_run_pod_status(
128
+ log=self.silent_logger, task_namespace="", label="", pod=self.mock_pod
129
+ ),
130
+ RunStatus.COMPLETED,
131
+ )
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env python3
2
+ from pathlib import Path
3
+
4
+ from vantage6.common.utest import find_tests, run_tests
5
+
6
+
7
+ def run():
8
+ suites = find_tests(str(Path(__file__).parent))
9
+ run_tests(suites)
10
+
11
+
12
+ if __name__ == "__main__":
13
+ run()
@@ -0,0 +1,35 @@
1
+ import logging
2
+ import sys
3
+ from pathlib import Path
4
+
5
+ from vantage6.cli.context.node import NodeContext
6
+
7
+ from vantage6.node import run
8
+
9
+ logging.basicConfig(level=logging.DEBUG)
10
+ log = logging.getLogger("vantage6.dev_start")
11
+
12
+
13
+ def run_function(config):
14
+ if not config:
15
+ log.critical("No config provided.")
16
+ return
17
+
18
+ name = Path(config).stem
19
+ ctx = NodeContext(name, True, config, logger_prefix=f"{name} | ", in_container=True)
20
+
21
+ run(ctx)
22
+
23
+
24
+ if __name__ == "__main__":
25
+ config_file = Path(sys.argv[1]) if len(sys.argv) > 1 else None
26
+ if not config_file:
27
+ log.critical("No config file provided.")
28
+ sys.exit(1)
29
+
30
+ if not config_file.exists():
31
+ log.critical("Config file does not exist: %s", config_file)
32
+ sys.exit(1)
33
+
34
+ log.info("Starting node with config: %s", config_file)
35
+ run_function(config_file)