vantage6 5.0.0a35__py3-none-any.whl → 5.0.0a37__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.

Potentially problematic release.


This version of vantage6 might be problematic. Click here for more details.

Files changed (84) hide show
  1. vantage6/cli/algorithm/generate_algorithm_json.py +9 -10
  2. vantage6/cli/algorithm/update.py +1 -1
  3. vantage6/cli/algostore/attach.py +1 -0
  4. vantage6/cli/algostore/files.py +3 -2
  5. vantage6/cli/algostore/list.py +0 -3
  6. vantage6/cli/algostore/new.py +3 -2
  7. vantage6/cli/algostore/start.py +14 -3
  8. vantage6/cli/algostore/stop.py +3 -0
  9. vantage6/cli/auth/attach.py +60 -0
  10. vantage6/cli/auth/files.py +16 -0
  11. vantage6/cli/auth/list.py +13 -0
  12. vantage6/cli/auth/new.py +81 -0
  13. vantage6/cli/auth/remove.py +31 -0
  14. vantage6/cli/auth/start.py +94 -0
  15. vantage6/cli/auth/stop.py +67 -0
  16. vantage6/cli/cli.py +56 -5
  17. vantage6/cli/common/decorator.py +24 -5
  18. vantage6/cli/common/new.py +27 -7
  19. vantage6/cli/common/start.py +49 -41
  20. vantage6/cli/common/stop.py +23 -5
  21. vantage6/cli/common/utils.py +25 -0
  22. vantage6/cli/config.py +10 -2
  23. vantage6/cli/{configuration_wizard.py → configuration_create.py} +28 -15
  24. vantage6/cli/configuration_manager.py +97 -17
  25. vantage6/cli/context/__init__.py +10 -5
  26. vantage6/cli/context/algorithm_store.py +11 -5
  27. vantage6/cli/context/auth.py +125 -0
  28. vantage6/cli/context/base_server.py +0 -4
  29. vantage6/cli/context/node.py +25 -8
  30. vantage6/cli/context/server.py +18 -6
  31. vantage6/cli/dev/clean.py +28 -0
  32. vantage6/cli/dev/common.py +34 -0
  33. vantage6/cli/dev/rebuild.py +39 -0
  34. vantage6/cli/dev/start.py +36 -0
  35. vantage6/cli/dev/stop.py +23 -0
  36. vantage6/cli/globals.py +5 -1
  37. vantage6/cli/node/common/__init__.py +26 -10
  38. vantage6/cli/node/list.py +5 -4
  39. vantage6/cli/node/new.py +13 -6
  40. vantage6/cli/node/set_api_key.py +1 -1
  41. vantage6/cli/node/start.py +19 -4
  42. vantage6/cli/node/stop.py +153 -7
  43. vantage6/cli/node/task_cleanup/__init__.py +153 -0
  44. vantage6/cli/node/version.py +5 -4
  45. vantage6/cli/prometheus/monitoring_manager.py +5 -3
  46. vantage6/cli/sandbox/config/base.py +101 -0
  47. vantage6/cli/sandbox/config/core.py +300 -0
  48. vantage6/cli/sandbox/config/node.py +314 -0
  49. vantage6/cli/sandbox/data/olympic_athletes_2016.csv +2425 -0
  50. vantage6/cli/sandbox/new.py +207 -0
  51. vantage6/cli/sandbox/populate/__init__.py +173 -0
  52. vantage6/cli/sandbox/populate/helpers/connect_store.py +203 -0
  53. vantage6/cli/sandbox/populate/helpers/delete_fixtures.py +67 -0
  54. vantage6/cli/sandbox/populate/helpers/load_fixtures.py +476 -0
  55. vantage6/cli/sandbox/populate/helpers/utils.py +35 -0
  56. vantage6/cli/sandbox/remove.py +173 -0
  57. vantage6/cli/sandbox/start.py +341 -0
  58. vantage6/cli/sandbox/stop.py +106 -0
  59. vantage6/cli/server/attach.py +1 -0
  60. vantage6/cli/server/common/__init__.py +6 -33
  61. vantage6/cli/server/import_.py +137 -119
  62. vantage6/cli/server/new.py +22 -7
  63. vantage6/cli/server/start.py +10 -1
  64. vantage6/cli/server/stop.py +2 -0
  65. vantage6/cli/template/auth_config.j2 +253 -0
  66. vantage6/cli/template/node_config.j2 +8 -8
  67. vantage6/cli/template/node_config_nonk8s.j2 +33 -0
  68. vantage6/cli/template/server_config.j2 +10 -7
  69. vantage6/cli/test/common/diagnostic_runner.py +5 -3
  70. vantage6/cli/use/namespace.py +2 -1
  71. vantage6/cli/utils.py +33 -1
  72. {vantage6-5.0.0a35.dist-info → vantage6-5.0.0a37.dist-info}/METADATA +4 -4
  73. vantage6-5.0.0a37.dist-info/RECORD +97 -0
  74. vantage6/cli/dev/create.py +0 -693
  75. vantage6/cli/dev/remove.py +0 -112
  76. vantage6/cli/rabbitmq/__init__.py +0 -0
  77. vantage6/cli/rabbitmq/definitions.py +0 -26
  78. vantage6/cli/rabbitmq/queue_manager.py +0 -218
  79. vantage6/cli/rabbitmq/rabbitmq.config +0 -8
  80. vantage6/cli/server/shell.py +0 -54
  81. vantage6-5.0.0a35.dist-info/RECORD +0 -75
  82. /vantage6/cli/{dev → sandbox}/data/km_dataset.csv +0 -0
  83. {vantage6-5.0.0a35.dist-info → vantage6-5.0.0a37.dist-info}/WHEEL +0 -0
  84. {vantage6-5.0.0a35.dist-info → vantage6-5.0.0a37.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,314 @@
1
+ from dataclasses import dataclass
2
+ from importlib import resources as impresources
3
+ from pathlib import Path
4
+
5
+ import pandas as pd
6
+ from colorama import Fore, Style
7
+
8
+ from vantage6.common import error, info
9
+ from vantage6.common.globals import InstanceType
10
+
11
+ import vantage6.cli.sandbox.data as node_datafiles_dir
12
+ from vantage6.cli.common.new import new
13
+ from vantage6.cli.context.node import NodeContext
14
+ from vantage6.cli.globals import (
15
+ DefaultDatasets,
16
+ )
17
+ from vantage6.cli.sandbox.config.base import BaseSandboxConfigManager
18
+ from vantage6.cli.sandbox.populate.helpers.utils import replace_wsl_path
19
+
20
+
21
+ @dataclass
22
+ class NodeDataset:
23
+ label: str
24
+ path: Path
25
+
26
+
27
+ class NodeSandboxConfigManager(BaseSandboxConfigManager):
28
+ """
29
+ Class to store the node sandbox configurations.
30
+
31
+ Parameters
32
+ ----------
33
+ server_name : str
34
+ Name of the server.
35
+ api_keys : list[str]
36
+ List of API keys.
37
+ node_names : list[str]
38
+ List of node names.
39
+ server_port : int
40
+ Port of the server.
41
+ node_image : str | None
42
+ Image of the node.
43
+ extra_node_config : Path | None
44
+ Path to the extra node configuration file.
45
+ extra_dataset : NodeDataset | None
46
+ List of tuples with the label and path to the dataset file.
47
+ context : str
48
+ Kubernetes context.
49
+ namespace : str
50
+ Kubernetes namespace.
51
+ k8s_node_name : str
52
+ Kubernetes node name.
53
+ custom_data_dir : Path | None
54
+ Path to the custom data directory. Useful on WSL because of mount issues for
55
+ default directories.
56
+ """
57
+
58
+ def __init__(
59
+ self,
60
+ server_name: str,
61
+ api_keys: list[str],
62
+ node_names: list[str],
63
+ server_port: int,
64
+ node_image: str | None,
65
+ extra_node_config: Path | None,
66
+ extra_dataset: NodeDataset | None,
67
+ context: str,
68
+ namespace: str,
69
+ k8s_node_name: str,
70
+ custom_data_dir: Path | None,
71
+ ) -> None:
72
+ super().__init__(server_name, custom_data_dir)
73
+ self.api_keys = api_keys
74
+ self.node_names = node_names
75
+ self.num_nodes = len(api_keys)
76
+ self.server_port = server_port
77
+ self.node_image = node_image
78
+ self.extra_node_config = extra_node_config
79
+ if extra_dataset:
80
+ self.node_datasets = [extra_dataset]
81
+ else:
82
+ self.node_datasets = []
83
+ self.context = context
84
+ self.namespace = namespace
85
+ self.k8s_node_name = k8s_node_name
86
+
87
+ self.node_configs = []
88
+ self.node_config_files = []
89
+ self.node_config_names = []
90
+ self.extra_config = None
91
+
92
+ def generate_node_configs(self) -> None:
93
+ """
94
+ Generates ``num_nodes`` node configuration files.
95
+ """
96
+ node_data_files = []
97
+ self.extra_config = self._read_extra_config_file(self.extra_node_config)
98
+
99
+ data_directory = impresources.files(node_datafiles_dir)
100
+
101
+ # Add default datasets to the list of dataset provided
102
+ for default_dataset in DefaultDatasets:
103
+ # note that the label is the name of the dataset with the underscores
104
+ # replace with hyphens, to make it valid for k8s
105
+ self.node_datasets.append(
106
+ NodeDataset(
107
+ label=default_dataset.name.lower().replace("_", "-"),
108
+ path=data_directory / default_dataset.value,
109
+ )
110
+ )
111
+
112
+ # Check for duplicate dataset labels
113
+ seen_labels = set()
114
+ duplicates = [
115
+ label
116
+ for label in [dataset.label for dataset in self.node_datasets]
117
+ if (label in seen_labels or seen_labels.add(label))
118
+ ]
119
+
120
+ if len(duplicates) > 0:
121
+ error(
122
+ f"Duplicate dataset labels found: {duplicates}. "
123
+ f"Please make sure all dataset labels are unique."
124
+ )
125
+ exit(1)
126
+
127
+ # create the data files for the nodes and get the path and label for each
128
+ # dataset
129
+ for dataset in self.node_datasets:
130
+ node_data_files.append(self._create_node_data_files(dataset))
131
+
132
+ for idx, api_key in enumerate(self.api_keys):
133
+ config = {
134
+ "org_id": idx + 1,
135
+ "api_key": api_key,
136
+ "node_name": self.node_names[idx],
137
+ }
138
+ config_file = self._create_node_config_file(
139
+ config,
140
+ [files[idx] for files in node_data_files],
141
+ )
142
+ self.node_configs.append(config)
143
+ self.node_config_files.append(config_file)
144
+ info(
145
+ f"Created {Fore.GREEN}{len(self.node_config_files)}{Style.RESET_ALL} node "
146
+ f"configuration(s), attaching them to {Fore.GREEN}{self.server_name}"
147
+ f"{Style.RESET_ALL}."
148
+ )
149
+
150
+ def _create_node_data_files(
151
+ self, node_dataset: NodeDataset
152
+ ) -> list[tuple[str, Path]]:
153
+ """
154
+ Create data files for nodes.
155
+
156
+ Parameters
157
+ ----------
158
+ node_dataset : NodeDataset
159
+ Tuple with the label and path to the dataset file.
160
+
161
+ Returns
162
+ -------
163
+ list[tuple[str, Path]]
164
+ List of tuples with the label and path to the dataset file.
165
+ """
166
+ info(
167
+ f"Creating data files using dataset '{node_dataset.label}' for "
168
+ f"{self.num_nodes} nodes"
169
+ )
170
+ data_files = []
171
+ full_df = pd.read_csv(node_dataset.path)
172
+ length_df = len(full_df)
173
+ for i in range(self.num_nodes):
174
+ node_name = f"{self.server_name}_node_{i + 1}"
175
+ path_to_dev_dir = self._create_and_get_data_dir(
176
+ InstanceType.NODE, is_data_folder=False
177
+ )
178
+
179
+ # Split the data over the nodes
180
+ start = i * length_df // self.num_nodes
181
+ end = (i + 1) * length_df // self.num_nodes
182
+ data = full_df[start:end]
183
+ data_file = (
184
+ replace_wsl_path(path_to_dev_dir, to_mnt_wsl=True)
185
+ / f"df_{node_dataset.label}_{node_name}.csv"
186
+ )
187
+
188
+ # write data to file
189
+ data.to_csv(data_file, index=False)
190
+ data_files.append(
191
+ (node_dataset.label, replace_wsl_path(data_file, to_mnt_wsl=False))
192
+ )
193
+ return data_files
194
+
195
+ def _create_node_config_file(
196
+ self, config: dict, datasets: list[tuple[str, Path]]
197
+ ) -> Path:
198
+ """
199
+ Create a node configuration file (YAML).
200
+
201
+ Parameters
202
+ ----------
203
+ config : dict
204
+ Configuration dictionary.
205
+ datasets : list[tuple[str, Path]]
206
+ List of tuples with the label and path to the dataset file.
207
+
208
+ Returns
209
+ -------
210
+ Path
211
+ Path to the node configuration file.
212
+ """
213
+ node_name = config["node_name"]
214
+ config_name = f"{self.server_name}-{node_name}"
215
+
216
+ path_to_data_dir = self._create_and_get_data_dir(
217
+ InstanceType.NODE, is_data_folder=True
218
+ )
219
+
220
+ # delete old node config if it exists
221
+ NodeContext.remove_config_file_if_exists(
222
+ InstanceType.NODE, config_name, False, is_sandbox=True
223
+ )
224
+
225
+ # create new node config
226
+ node_config = new(
227
+ config_producing_func=self.__node_config_return_func,
228
+ config_producing_func_args=(
229
+ config,
230
+ self.extra_config,
231
+ datasets,
232
+ path_to_data_dir,
233
+ ),
234
+ name=config_name,
235
+ system_folders=False,
236
+ namespace=self.namespace,
237
+ context=self.context,
238
+ type_=InstanceType.NODE,
239
+ is_sandbox=True,
240
+ )
241
+
242
+ self.node_config_names.append(config_name)
243
+
244
+ return node_config
245
+
246
+ def __node_config_return_func(
247
+ self,
248
+ node_specific_config: dict,
249
+ extra_config: dict,
250
+ datasets: list[tuple[str, Path]],
251
+ path_to_data_dir: Path,
252
+ ) -> dict:
253
+ """
254
+ Return a dict with node configuration values to be used in creating the
255
+ config file.
256
+ """
257
+ config = {
258
+ "node": {
259
+ "proxyPort": 7676 + int(node_specific_config["org_id"]),
260
+ "apiKey": node_specific_config["api_key"],
261
+ "name": node_specific_config["node_name"],
262
+ "image": (
263
+ self.node_image
264
+ # TODO v5+ update
265
+ or "harbor2.vantage6.ai/infrastructure/node:5.0.0a36"
266
+ ),
267
+ "logging": {
268
+ "level": "DEBUG",
269
+ "file": f"{node_specific_config['node_name']}.log",
270
+ },
271
+ "keycloakUrl": (
272
+ f"http://vantage6-{self.server_name}-auth-user-auth-keycloak."
273
+ f"{self.namespace}.svc.cluster.local"
274
+ ),
275
+ "dev": {
276
+ "task_dir_extension": str(path_to_data_dir),
277
+ },
278
+ "persistence": {
279
+ "tasks": {
280
+ "hostPath": str(path_to_data_dir),
281
+ "size": "1Gi",
282
+ },
283
+ "database": {
284
+ "size": "1Gi",
285
+ },
286
+ },
287
+ "k8sNodeName": self.k8s_node_name,
288
+ "databases": {
289
+ "fileBased": [
290
+ {
291
+ "name": dataset[0],
292
+ "uri": dataset[1],
293
+ "type": "csv",
294
+ "volumePath": Path(dataset[1]).parent,
295
+ "originalName": dataset[0],
296
+ }
297
+ for dataset in [datasets[0]]
298
+ ]
299
+ },
300
+ "server": {
301
+ "url": (
302
+ f"http://vantage6-{self.server_name}-user-server-"
303
+ f"vantage6-server-service.{self.namespace}.svc.cluster.local"
304
+ ),
305
+ "port": self.server_port,
306
+ },
307
+ },
308
+ }
309
+
310
+ # merge the extra config with the node config
311
+ if extra_config is not None:
312
+ config.update(extra_config)
313
+
314
+ return config