vantage6 4.10.1rc1__py3-none-any.whl → 4.11.0rc2__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.
- tests_cli/test_client_script.py +23 -0
- vantage6/cli/__build__ +1 -1
- vantage6/cli/_version.py +1 -1
- vantage6/cli/cli.py +2 -0
- vantage6/cli/configuration_manager.py +1 -0
- vantage6/cli/context/server.py +26 -0
- vantage6/cli/dev/create.py +78 -17
- vantage6/cli/globals.py +12 -0
- vantage6/cli/prometheus/monitoring_manager.py +145 -0
- vantage6/cli/server/start.py +58 -2
- vantage6/cli/server/stop.py +7 -0
- vantage6/cli/template/node_config.j2 +4 -2
- vantage6/cli/test/algo_test_scripts/algo_test_arguments.py +33 -0
- vantage6/cli/test/algo_test_scripts/algo_test_script.py +89 -0
- vantage6/cli/test/client_script.py +143 -0
- {vantage6-4.10.1rc1.dist-info → vantage6-4.11.0rc2.dist-info}/METADATA +3 -3
- {vantage6-4.10.1rc1.dist-info → vantage6-4.11.0rc2.dist-info}/RECORD +20 -15
- {vantage6-4.10.1rc1.dist-info → vantage6-4.11.0rc2.dist-info}/WHEEL +0 -0
- {vantage6-4.10.1rc1.dist-info → vantage6-4.11.0rc2.dist-info}/entry_points.txt +0 -0
- {vantage6-4.10.1rc1.dist-info → vantage6-4.11.0rc2.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from click import UsageError
|
|
2
|
+
from vantage6.cli.test.client_script import cli_test_client_script
|
|
3
|
+
|
|
4
|
+
import click
|
|
5
|
+
import unittest
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class TestScriptTest(unittest.TestCase):
|
|
9
|
+
def test_script_incorrect_usage(self):
|
|
10
|
+
ctx = click.Context(cli_test_client_script)
|
|
11
|
+
|
|
12
|
+
with self.assertRaises(UsageError):
|
|
13
|
+
ctx.invoke(
|
|
14
|
+
cli_test_client_script,
|
|
15
|
+
script="path/to/script.py",
|
|
16
|
+
task_arguments="{'my_arg': 1}",
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
with self.assertRaises(UsageError):
|
|
20
|
+
ctx.invoke(
|
|
21
|
+
cli_test_client_script,
|
|
22
|
+
task_arguments="not_a_json",
|
|
23
|
+
)
|
vantage6/cli/__build__
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
2
|
vantage6/cli/_version.py
CHANGED
|
@@ -7,7 +7,7 @@ with open(os.path.join(here, "__build__")) as fp:
|
|
|
7
7
|
__build__ = json.load(fp)
|
|
8
8
|
|
|
9
9
|
# Module version
|
|
10
|
-
version_info = (4,
|
|
10
|
+
version_info = (4, 11, 0, "candidate", __build__, 0)
|
|
11
11
|
|
|
12
12
|
# Module version stage suffix map
|
|
13
13
|
_specifier_ = {"alpha": "a", "beta": "b", "candidate": "rc", "final": ""}
|
vantage6/cli/cli.py
CHANGED
|
@@ -28,6 +28,7 @@ from vantage6.cli.dev.start import start_demo_network
|
|
|
28
28
|
from vantage6.cli.dev.stop import stop_demo_network
|
|
29
29
|
from vantage6.cli.algorithm.create import cli_algorithm_create
|
|
30
30
|
from vantage6.cli.algorithm.update import cli_algorithm_update
|
|
31
|
+
from vantage6.cli.test.client_script import cli_test_client_script
|
|
31
32
|
from vantage6.cli.test.feature_tester import cli_test_features
|
|
32
33
|
from vantage6.cli.test.integration_test import cli_test_integration
|
|
33
34
|
from vantage6.cli.algostore.attach import cli_algo_store_attach
|
|
@@ -124,6 +125,7 @@ def cli_test() -> None:
|
|
|
124
125
|
# Define the commands for the test group
|
|
125
126
|
cli_test.add_command(cli_test_features, name="feature-test")
|
|
126
127
|
cli_test.add_command(cli_test_integration, name="integration-test")
|
|
128
|
+
cli_test.add_command(cli_test_client_script, name="client-script")
|
|
127
129
|
|
|
128
130
|
|
|
129
131
|
# Define the algorithm-store group
|
vantage6/cli/context/server.py
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
|
+
from pathlib import Path
|
|
2
3
|
|
|
3
4
|
from vantage6.common.globals import APPNAME, InstanceType
|
|
4
5
|
from vantage6.cli.configuration_manager import ServerConfigurationManager
|
|
5
6
|
from vantage6.cli.globals import (
|
|
6
7
|
DEFAULT_SERVER_SYSTEM_FOLDERS as S_FOL,
|
|
8
|
+
PROMETHEUS_DIR,
|
|
7
9
|
ServerType,
|
|
8
10
|
ServerGlobals,
|
|
9
11
|
)
|
|
@@ -57,6 +59,30 @@ class ServerContext(BaseServerContext):
|
|
|
57
59
|
"""
|
|
58
60
|
return f"{APPNAME}-{self.name}-{self.scope}-{ServerType.V6SERVER}"
|
|
59
61
|
|
|
62
|
+
@property
|
|
63
|
+
def prometheus_container_name(self) -> str:
|
|
64
|
+
"""
|
|
65
|
+
Get the name of the Prometheus Docker container for this server.
|
|
66
|
+
|
|
67
|
+
Returns
|
|
68
|
+
-------
|
|
69
|
+
str
|
|
70
|
+
Prometheus container name, unique to this server instance.
|
|
71
|
+
"""
|
|
72
|
+
return f"{APPNAME}-prometheus"
|
|
73
|
+
|
|
74
|
+
@property
|
|
75
|
+
def prometheus_dir(self) -> Path:
|
|
76
|
+
"""
|
|
77
|
+
Get the Prometheus directory path.
|
|
78
|
+
|
|
79
|
+
Returns
|
|
80
|
+
-------
|
|
81
|
+
Path
|
|
82
|
+
Path to the Prometheus directory
|
|
83
|
+
"""
|
|
84
|
+
return self.data_dir / PROMETHEUS_DIR
|
|
85
|
+
|
|
60
86
|
@classmethod
|
|
61
87
|
def from_external_config_file(
|
|
62
88
|
cls, path: str, system_folders: bool = S_FOL
|
vantage6/cli/dev/create.py
CHANGED
|
@@ -12,7 +12,7 @@ from vantage6.common import ensure_config_dir_writable, info, error, generate_ap
|
|
|
12
12
|
|
|
13
13
|
import vantage6.cli.dev.data as data_dir
|
|
14
14
|
from vantage6.cli.context.algorithm_store import AlgorithmStoreContext
|
|
15
|
-
from vantage6.cli.globals import PACKAGE_FOLDER
|
|
15
|
+
from vantage6.cli.globals import PACKAGE_FOLDER, DefaultDatasets
|
|
16
16
|
from vantage6.cli.context.server import ServerContext
|
|
17
17
|
from vantage6.cli.context.node import NodeContext
|
|
18
18
|
from vantage6.cli.server.common import get_server_context
|
|
@@ -20,7 +20,9 @@ from vantage6.cli.server.import_ import cli_server_import
|
|
|
20
20
|
from vantage6.cli.utils import prompt_config_name
|
|
21
21
|
|
|
22
22
|
|
|
23
|
-
def create_node_data_files(
|
|
23
|
+
def create_node_data_files(
|
|
24
|
+
num_nodes: int, server_name: str, dataset: tuple[str, Path]
|
|
25
|
+
) -> list[tuple[str, Path]]:
|
|
24
26
|
"""Create data files for nodes.
|
|
25
27
|
|
|
26
28
|
Parameters
|
|
@@ -29,15 +31,16 @@ def create_node_data_files(num_nodes: int, server_name: str) -> list[Path]:
|
|
|
29
31
|
Number of nodes to create data files for.
|
|
30
32
|
server_name : str
|
|
31
33
|
Name of the server.
|
|
32
|
-
|
|
34
|
+
dataset : tuple[str, Path]
|
|
35
|
+
Tuple containing the name and the path to the dataset.
|
|
33
36
|
Returns
|
|
34
37
|
-------
|
|
35
|
-
list[Path]
|
|
36
|
-
List of paths to the created data files.
|
|
38
|
+
list[tuple[str, Path]]
|
|
39
|
+
List of the label and paths to the created data files.
|
|
37
40
|
"""
|
|
38
41
|
info(f"Creating data files for {num_nodes} nodes.")
|
|
39
42
|
data_files = []
|
|
40
|
-
full_df = pd.read_csv(
|
|
43
|
+
full_df = pd.read_csv(dataset[1])
|
|
41
44
|
length_df = len(full_df)
|
|
42
45
|
for i in range(num_nodes):
|
|
43
46
|
node_name = f"{server_name}_node_{i + 1}"
|
|
@@ -49,16 +52,20 @@ def create_node_data_files(num_nodes: int, server_name: str) -> list[Path]:
|
|
|
49
52
|
start = i * length_df // num_nodes
|
|
50
53
|
end = (i + 1) * length_df // num_nodes
|
|
51
54
|
data = full_df[start:end]
|
|
52
|
-
data_file = data_folder / f"df_{node_name}.csv"
|
|
55
|
+
data_file = data_folder / f"df_{dataset[0]}_{node_name}.csv"
|
|
53
56
|
|
|
54
57
|
# write data to file
|
|
55
58
|
data.to_csv(data_file, index=False)
|
|
56
|
-
data_files.append(data_file)
|
|
59
|
+
data_files.append((dataset[0], data_file))
|
|
57
60
|
return data_files
|
|
58
61
|
|
|
59
62
|
|
|
60
63
|
def create_node_config_file(
|
|
61
|
-
server_url: str,
|
|
64
|
+
server_url: str,
|
|
65
|
+
port: int,
|
|
66
|
+
config: dict,
|
|
67
|
+
server_name: str,
|
|
68
|
+
datasets: list[tuple[str, Path]] = (),
|
|
62
69
|
) -> None:
|
|
63
70
|
"""Create a node configuration file (YAML).
|
|
64
71
|
|
|
@@ -77,8 +84,8 @@ def create_node_config_file(
|
|
|
77
84
|
additional user_defined_config.
|
|
78
85
|
server_name : str
|
|
79
86
|
Configuration name of the dummy server.
|
|
80
|
-
|
|
81
|
-
|
|
87
|
+
datasets : list[tuple[str, Path]]
|
|
88
|
+
List of tuples containing the labels and the paths to the datasets
|
|
82
89
|
"""
|
|
83
90
|
environment = Environment(
|
|
84
91
|
loader=FileSystemLoader(PACKAGE_FOLDER / APPNAME / "cli" / "template"),
|
|
@@ -102,10 +109,12 @@ def create_node_config_file(
|
|
|
102
109
|
error(f"Node configuration file already exists: {full_path}")
|
|
103
110
|
exit(1)
|
|
104
111
|
|
|
112
|
+
databases = [{dataset[0]: dataset[1]} for dataset in datasets]
|
|
113
|
+
|
|
105
114
|
node_config = template.render(
|
|
106
115
|
{
|
|
107
116
|
"api_key": config["api_key"],
|
|
108
|
-
"databases":
|
|
117
|
+
"databases": databases,
|
|
109
118
|
"logging": {"file": f"{node_name}.log"},
|
|
110
119
|
"port": port,
|
|
111
120
|
"server_url": server_url,
|
|
@@ -124,8 +133,7 @@ def create_node_config_file(
|
|
|
124
133
|
f.write(node_config)
|
|
125
134
|
|
|
126
135
|
info(
|
|
127
|
-
f"Spawned node for organization {Fore.GREEN}{config['org_id']}"
|
|
128
|
-
f"{Style.RESET_ALL}"
|
|
136
|
+
f"Spawned node for organization {Fore.GREEN}{config['org_id']}{Style.RESET_ALL}"
|
|
129
137
|
)
|
|
130
138
|
|
|
131
139
|
|
|
@@ -156,6 +164,7 @@ def generate_node_configs(
|
|
|
156
164
|
port: int,
|
|
157
165
|
server_name: str,
|
|
158
166
|
extra_node_config: Path | None,
|
|
167
|
+
extra_datasets: list[tuple[str, Path]],
|
|
159
168
|
) -> list[dict]:
|
|
160
169
|
"""Generates ``num_nodes`` node configuration files.
|
|
161
170
|
|
|
@@ -171,6 +180,8 @@ def generate_node_configs(
|
|
|
171
180
|
Configuration name of the dummy server.
|
|
172
181
|
extra_node_config : Path | None
|
|
173
182
|
Path to file with additional node configuration.
|
|
183
|
+
extra_datasets : list[tuple[str, Path]]
|
|
184
|
+
List of tuples containing the labels and the paths to extra datasets
|
|
174
185
|
|
|
175
186
|
Returns
|
|
176
187
|
-------
|
|
@@ -178,8 +189,36 @@ def generate_node_configs(
|
|
|
178
189
|
List of dictionaries containing node configurations.
|
|
179
190
|
"""
|
|
180
191
|
configs = []
|
|
192
|
+
node_data_files = []
|
|
181
193
|
extra_config = _read_extra_config_file(extra_node_config)
|
|
182
|
-
|
|
194
|
+
|
|
195
|
+
data_directory = impresources.files(data_dir)
|
|
196
|
+
|
|
197
|
+
# Add default datasets to the list of dataset provided
|
|
198
|
+
for default_dataset in DefaultDatasets:
|
|
199
|
+
extra_datasets.append(
|
|
200
|
+
(default_dataset.name.lower(), data_directory / default_dataset.value)
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
# Check for duplicate dataset labels
|
|
204
|
+
seen_labels = set()
|
|
205
|
+
duplicates = [
|
|
206
|
+
label
|
|
207
|
+
for label in [dataset[0] for dataset in extra_datasets]
|
|
208
|
+
if (label in seen_labels or seen_labels.add(label))
|
|
209
|
+
]
|
|
210
|
+
|
|
211
|
+
if len(duplicates) > 0:
|
|
212
|
+
error(
|
|
213
|
+
f"Duplicate dataset labels found: {duplicates}. "
|
|
214
|
+
f"Please make sure all dataset labels are unique."
|
|
215
|
+
)
|
|
216
|
+
exit(1)
|
|
217
|
+
|
|
218
|
+
# create the data files for the nodes and get the path and label for each dataset
|
|
219
|
+
for dataset in extra_datasets:
|
|
220
|
+
node_data_files.append(create_node_data_files(num_nodes, server_name, dataset))
|
|
221
|
+
|
|
183
222
|
for i in range(num_nodes):
|
|
184
223
|
config = {
|
|
185
224
|
"org_id": i + 1,
|
|
@@ -188,7 +227,11 @@ def generate_node_configs(
|
|
|
188
227
|
"user_defined_config": extra_config,
|
|
189
228
|
}
|
|
190
229
|
create_node_config_file(
|
|
191
|
-
server_url,
|
|
230
|
+
server_url,
|
|
231
|
+
port,
|
|
232
|
+
config,
|
|
233
|
+
server_name,
|
|
234
|
+
[files[i] for files in node_data_files],
|
|
192
235
|
)
|
|
193
236
|
configs.append(config)
|
|
194
237
|
|
|
@@ -422,6 +465,7 @@ def demo_network(
|
|
|
422
465
|
ui_image: str,
|
|
423
466
|
ui_port: int,
|
|
424
467
|
algorithm_store_port: int,
|
|
468
|
+
extra_datasets: list[tuple[str, Path]],
|
|
425
469
|
) -> tuple[list[dict], Path, Path]:
|
|
426
470
|
"""Generates the demo network.
|
|
427
471
|
|
|
@@ -448,6 +492,8 @@ def demo_network(
|
|
|
448
492
|
Port to run the UI on.
|
|
449
493
|
algorithm_store_port : int
|
|
450
494
|
Port to run the algorithm store on.
|
|
495
|
+
extra_datasets : list[tuple[str, Path]]
|
|
496
|
+
List of tuples containing the labels and the paths to extra datasets
|
|
451
497
|
|
|
452
498
|
Returns
|
|
453
499
|
-------
|
|
@@ -455,7 +501,12 @@ def demo_network(
|
|
|
455
501
|
Tuple containing node, server import and server configurations.
|
|
456
502
|
"""
|
|
457
503
|
node_configs = generate_node_configs(
|
|
458
|
-
num_nodes,
|
|
504
|
+
num_nodes,
|
|
505
|
+
server_url,
|
|
506
|
+
server_port,
|
|
507
|
+
server_name,
|
|
508
|
+
extra_node_config,
|
|
509
|
+
extra_datasets,
|
|
459
510
|
)
|
|
460
511
|
server_import_config = create_vserver_import_config(node_configs, server_name)
|
|
461
512
|
server_config = create_vserver_config(
|
|
@@ -549,6 +600,14 @@ def demo_network(
|
|
|
549
600
|
help="YAML File with additional algorithm store configuration. This will be"
|
|
550
601
|
" appended to the algorithm store configuration file",
|
|
551
602
|
)
|
|
603
|
+
@click.option(
|
|
604
|
+
"--add-dataset",
|
|
605
|
+
type=(str, click.Path()),
|
|
606
|
+
default=(),
|
|
607
|
+
multiple=True,
|
|
608
|
+
help="Add a dataset to the nodes. The first argument is the label of the database, "
|
|
609
|
+
"the second is the path to the dataset file.",
|
|
610
|
+
)
|
|
552
611
|
@click.pass_context
|
|
553
612
|
def create_demo_network(
|
|
554
613
|
click_ctx: click.Context,
|
|
@@ -563,6 +622,7 @@ def create_demo_network(
|
|
|
563
622
|
extra_server_config: Path = None,
|
|
564
623
|
extra_node_config: Path = None,
|
|
565
624
|
extra_store_config: Path = None,
|
|
625
|
+
add_dataset: list[tuple[str, Path]] = (),
|
|
566
626
|
) -> dict:
|
|
567
627
|
"""Creates a demo network.
|
|
568
628
|
|
|
@@ -584,6 +644,7 @@ def create_demo_network(
|
|
|
584
644
|
ui_image,
|
|
585
645
|
ui_port,
|
|
586
646
|
algorithm_store_port,
|
|
647
|
+
list(add_dataset),
|
|
587
648
|
)
|
|
588
649
|
info(
|
|
589
650
|
f"Created {Fore.GREEN}{len(demo[0])}{Style.RESET_ALL} node "
|
vantage6/cli/globals.py
CHANGED
|
@@ -42,6 +42,18 @@ DIAGNOSTICS_IMAGE = "harbor2.vantage6.ai/algorithms/diagnostic"
|
|
|
42
42
|
# Address of community algorithm store
|
|
43
43
|
COMMUNITY_STORE = "https://store.cotopaxi.vantage6.ai/api"
|
|
44
44
|
|
|
45
|
+
DEFAULT_PROMETHEUS_IMAGE = "prom/prometheus"
|
|
46
|
+
PROMETHEUS_CONFIG = "prometheus.yml"
|
|
47
|
+
PROMETHEUS_DIR = "prometheus"
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
# datasets included in the nodes of the dev network
|
|
51
|
+
class DefaultDatasets(str, Enum):
|
|
52
|
+
"""Enum containing default datasets"""
|
|
53
|
+
|
|
54
|
+
OLYMPIC_ATHLETES = "olympic_athletes_2016.csv"
|
|
55
|
+
KAPLAN_MEIER_TEST = "km_dataset.csv"
|
|
56
|
+
|
|
45
57
|
|
|
46
58
|
class ServerType(str, Enum):
|
|
47
59
|
"""Enum containing server types"""
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import yaml
|
|
2
|
+
import docker
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
from vantage6.common import info, error
|
|
6
|
+
from vantage6.common.docker.network_manager import NetworkManager
|
|
7
|
+
from vantage6.common.globals import DEFAULT_PROMETHEUS_EXPORTER_PORT
|
|
8
|
+
from vantage6.cli.context.server import ServerContext
|
|
9
|
+
from vantage6.cli.globals import (
|
|
10
|
+
DEFAULT_PROMETHEUS_IMAGE,
|
|
11
|
+
PROMETHEUS_CONFIG,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class PrometheusServer:
|
|
16
|
+
"""
|
|
17
|
+
Manages the Prometheus Docker container
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
def __init__(
|
|
21
|
+
self, ctx: ServerContext, network_mgr: NetworkManager, image: str = None
|
|
22
|
+
):
|
|
23
|
+
"""
|
|
24
|
+
Initialize the PrometheusServer instance.
|
|
25
|
+
|
|
26
|
+
Parameters
|
|
27
|
+
----------
|
|
28
|
+
ctx : ServerContext
|
|
29
|
+
The server context containing configuration and paths.
|
|
30
|
+
network_mgr : NetworkManager
|
|
31
|
+
The network manager responsible for managing Docker networks.
|
|
32
|
+
image : str, optional
|
|
33
|
+
The Docker image to use for the Prometheus container. If not provided,
|
|
34
|
+
the default Prometheus image will be used.
|
|
35
|
+
"""
|
|
36
|
+
self.ctx = ctx
|
|
37
|
+
self.network_mgr = network_mgr
|
|
38
|
+
self.docker = docker.from_env()
|
|
39
|
+
self.image = image if image else DEFAULT_PROMETHEUS_IMAGE
|
|
40
|
+
self.config_file = Path(self.ctx.data_dir / PROMETHEUS_CONFIG)
|
|
41
|
+
self.data_dir = self.ctx.prometheus_dir
|
|
42
|
+
|
|
43
|
+
def start(self):
|
|
44
|
+
"""
|
|
45
|
+
Start a Docker container running Prometheus
|
|
46
|
+
"""
|
|
47
|
+
self._prepare_config()
|
|
48
|
+
|
|
49
|
+
volumes = {
|
|
50
|
+
str(self.config_file): {
|
|
51
|
+
"bind": "/etc/prometheus/prometheus.yml",
|
|
52
|
+
"mode": "ro",
|
|
53
|
+
},
|
|
54
|
+
str(self.data_dir): {"bind": "/prometheus", "mode": "rw"},
|
|
55
|
+
}
|
|
56
|
+
ports = {"9090/tcp": 9090}
|
|
57
|
+
|
|
58
|
+
if self._is_container_running():
|
|
59
|
+
info("Prometheus is already running!")
|
|
60
|
+
return
|
|
61
|
+
|
|
62
|
+
self.docker.containers.run(
|
|
63
|
+
name=self.ctx.prometheus_container_name,
|
|
64
|
+
image=self.image,
|
|
65
|
+
volumes=volumes,
|
|
66
|
+
ports=ports,
|
|
67
|
+
detach=True,
|
|
68
|
+
restart_policy={"Name": "unless-stopped"},
|
|
69
|
+
network=self.network_mgr.network_name,
|
|
70
|
+
)
|
|
71
|
+
info("Prometheus container started successfully!")
|
|
72
|
+
|
|
73
|
+
def _prepare_config(self):
|
|
74
|
+
"""
|
|
75
|
+
Prepare the Prometheus configuration and data directories
|
|
76
|
+
"""
|
|
77
|
+
if not self.config_file.exists():
|
|
78
|
+
error(f"Prometheus configuration file {self.config_file} not found!")
|
|
79
|
+
raise FileNotFoundError(f"{self.config_file} not found!")
|
|
80
|
+
|
|
81
|
+
if not self.data_dir.exists():
|
|
82
|
+
self.data_dir.mkdir(parents=True, exist_ok=True)
|
|
83
|
+
|
|
84
|
+
self._update_prometheus_config()
|
|
85
|
+
|
|
86
|
+
def _update_prometheus_config(self):
|
|
87
|
+
"""
|
|
88
|
+
Update the Prometheus configuration file with the server address.
|
|
89
|
+
"""
|
|
90
|
+
|
|
91
|
+
try:
|
|
92
|
+
prometheus_exporter_port = self.ctx.config.get("prometheus", {}).get(
|
|
93
|
+
"exporter_port", DEFAULT_PROMETHEUS_EXPORTER_PORT
|
|
94
|
+
)
|
|
95
|
+
server_hostname = self.ctx.prometheus_container_name
|
|
96
|
+
server_address = f"{server_hostname}:{prometheus_exporter_port}"
|
|
97
|
+
|
|
98
|
+
info(
|
|
99
|
+
f"Using Docker container hostname '{server_hostname}' for Prometheus target. "
|
|
100
|
+
"Ensure Prometheus is in the same Docker network to resolve this address."
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
with open(self.config_file, "r") as f:
|
|
104
|
+
config = yaml.safe_load(f)
|
|
105
|
+
|
|
106
|
+
job_name = "vantage6_server_metrics"
|
|
107
|
+
job_exists = any(
|
|
108
|
+
job.get("job_name") == job_name
|
|
109
|
+
for job in config.get("scrape_configs", [])
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
if not job_exists:
|
|
113
|
+
new_job = {
|
|
114
|
+
"job_name": job_name,
|
|
115
|
+
"static_configs": [{"targets": [server_address]}],
|
|
116
|
+
}
|
|
117
|
+
config.setdefault("scrape_configs", []).append(new_job)
|
|
118
|
+
else:
|
|
119
|
+
for job in config["scrape_configs"]:
|
|
120
|
+
if job.get("job_name") == job_name:
|
|
121
|
+
job["static_configs"] = [{"targets": [server_address]}]
|
|
122
|
+
|
|
123
|
+
with open(self.config_file, "w") as f:
|
|
124
|
+
yaml.dump(config, f)
|
|
125
|
+
|
|
126
|
+
info(f"Prometheus configuration updated with target: {server_address}")
|
|
127
|
+
|
|
128
|
+
except Exception as e:
|
|
129
|
+
error(f"Failed to update Prometheus configuration: {e}")
|
|
130
|
+
raise
|
|
131
|
+
|
|
132
|
+
def _is_container_running(self) -> bool:
|
|
133
|
+
"""
|
|
134
|
+
Check if a Prometheus container is already running.
|
|
135
|
+
|
|
136
|
+
Returns
|
|
137
|
+
-------
|
|
138
|
+
bool
|
|
139
|
+
True if the Prometheus container is running, False otherwise.
|
|
140
|
+
"""
|
|
141
|
+
try:
|
|
142
|
+
container = self.docker.containers.get(self.ctx.prometheus_container_name)
|
|
143
|
+
return container.status == "running"
|
|
144
|
+
except docker.errors.NotFound:
|
|
145
|
+
return False
|
vantage6/cli/server/start.py
CHANGED
|
@@ -11,11 +11,12 @@ from vantage6.common.globals import (
|
|
|
11
11
|
InstanceType,
|
|
12
12
|
)
|
|
13
13
|
|
|
14
|
-
from vantage6.common.globals import Ports
|
|
14
|
+
from vantage6.common.globals import Ports, DEFAULT_PROMETHEUS_EXPORTER_PORT
|
|
15
15
|
from vantage6.cli.context.server import ServerContext
|
|
16
16
|
from vantage6.cli.rabbitmq.queue_manager import RabbitMQManager
|
|
17
17
|
from vantage6.cli.server.common import stop_ui
|
|
18
18
|
from vantage6.cli.common.decorator import click_insert_context
|
|
19
|
+
from vantage6.cli.prometheus.monitoring_manager import PrometheusServer
|
|
19
20
|
from vantage6.cli.common.start import (
|
|
20
21
|
attach_logs,
|
|
21
22
|
check_for_start,
|
|
@@ -49,6 +50,14 @@ from vantage6.cli.common.start import (
|
|
|
49
50
|
"container - use in development only",
|
|
50
51
|
)
|
|
51
52
|
@click.option("--rabbitmq-image", default=None, help="RabbitMQ docker image to use")
|
|
53
|
+
@click.option(
|
|
54
|
+
"--with-prometheus",
|
|
55
|
+
"start_prometheus",
|
|
56
|
+
flag_value=True,
|
|
57
|
+
default=False,
|
|
58
|
+
help="Start Prometheus monitoring as a local container",
|
|
59
|
+
)
|
|
60
|
+
@click.option("--prometheus-image", default=None, help="Prometheus docker image to use")
|
|
52
61
|
@click.option(
|
|
53
62
|
"--keep/--auto-remove",
|
|
54
63
|
default=False,
|
|
@@ -75,6 +84,8 @@ def cli_server_start(
|
|
|
75
84
|
ui_port: int,
|
|
76
85
|
start_rabbitmq: bool,
|
|
77
86
|
rabbitmq_image: str,
|
|
87
|
+
start_prometheus: bool,
|
|
88
|
+
prometheus_image: str,
|
|
78
89
|
keep: bool,
|
|
79
90
|
mount_src: str,
|
|
80
91
|
attach: bool,
|
|
@@ -135,6 +146,24 @@ def cli_server_start(
|
|
|
135
146
|
"cannot be scaled horizontally!"
|
|
136
147
|
)
|
|
137
148
|
|
|
149
|
+
if (
|
|
150
|
+
start_prometheus
|
|
151
|
+
or ctx.config.get("prometheus")
|
|
152
|
+
and ctx.config["prometheus"].get("start_with_server", False)
|
|
153
|
+
):
|
|
154
|
+
info("Starting Prometheus container")
|
|
155
|
+
_start_prometheus(ctx, prometheus_image, server_network_mgr)
|
|
156
|
+
elif ctx.config.get("prometheus"):
|
|
157
|
+
info(
|
|
158
|
+
"Prometheus is provided in the config file as external service."
|
|
159
|
+
"Assuming this service is up and running."
|
|
160
|
+
)
|
|
161
|
+
else:
|
|
162
|
+
warning(
|
|
163
|
+
"Monitoring is not set up! This means that the vantage6 server "
|
|
164
|
+
"cannot be monitored with Prometheus!"
|
|
165
|
+
)
|
|
166
|
+
|
|
138
167
|
# start the UI if requested
|
|
139
168
|
if start_ui or ctx.config.get("ui") and ctx.config["ui"].get("enabled"):
|
|
140
169
|
_start_ui(docker_client, ctx, ui_port)
|
|
@@ -152,6 +181,9 @@ def cli_server_start(
|
|
|
152
181
|
|
|
153
182
|
info("Run Docker container")
|
|
154
183
|
port_ = str(port or ctx.config["port"] or Ports.DEV_SERVER.value)
|
|
184
|
+
prometheus_exporter_port = ctx.config.get("prometheus", {}).get(
|
|
185
|
+
"exporter_port", DEFAULT_PROMETHEUS_EXPORTER_PORT
|
|
186
|
+
)
|
|
155
187
|
container = docker_client.containers.run(
|
|
156
188
|
image,
|
|
157
189
|
command=cmd,
|
|
@@ -162,7 +194,10 @@ def cli_server_start(
|
|
|
162
194
|
"name": ctx.config_file_name,
|
|
163
195
|
},
|
|
164
196
|
environment=environment_vars,
|
|
165
|
-
ports={
|
|
197
|
+
ports={
|
|
198
|
+
f"{internal_port}/tcp": (ip, port_), # API port
|
|
199
|
+
f"{prometheus_exporter_port}/tcp": prometheus_exporter_port,
|
|
200
|
+
},
|
|
166
201
|
name=ctx.docker_container_name,
|
|
167
202
|
auto_remove=not keep,
|
|
168
203
|
tty=True,
|
|
@@ -202,6 +237,27 @@ def _start_rabbitmq(
|
|
|
202
237
|
rabbit_mgr.start()
|
|
203
238
|
|
|
204
239
|
|
|
240
|
+
def _start_prometheus(
|
|
241
|
+
ctx: ServerContext, prometheus_image: str, network_mgr: NetworkManager
|
|
242
|
+
) -> None:
|
|
243
|
+
"""
|
|
244
|
+
Start the Prometheus container if it is not already running.
|
|
245
|
+
|
|
246
|
+
Parameters
|
|
247
|
+
----------
|
|
248
|
+
ctx : ServerContext
|
|
249
|
+
Server context object
|
|
250
|
+
prometheus_image : str
|
|
251
|
+
Prometheus image to use
|
|
252
|
+
network_mgr : NetworkManager
|
|
253
|
+
Network manager object
|
|
254
|
+
"""
|
|
255
|
+
prometheus_server = PrometheusServer(
|
|
256
|
+
ctx=ctx, network_mgr=network_mgr, image=prometheus_image
|
|
257
|
+
)
|
|
258
|
+
prometheus_server.start()
|
|
259
|
+
|
|
260
|
+
|
|
205
261
|
def _start_ui(client: DockerClient, ctx: ServerContext, ui_port: int) -> None:
|
|
206
262
|
"""
|
|
207
263
|
Start the UI container.
|
vantage6/cli/server/stop.py
CHANGED
|
@@ -117,3 +117,10 @@ def _stop_server_containers(
|
|
|
117
117
|
f"Stopped the {Fore.GREEN}{rabbit_container_name}"
|
|
118
118
|
f"{Style.RESET_ALL} container."
|
|
119
119
|
)
|
|
120
|
+
|
|
121
|
+
if ctx.config.get("prometheus", {}).get("enabled"):
|
|
122
|
+
remove_container_if_exists(client, name=ctx.prometheus_container_name)
|
|
123
|
+
info(
|
|
124
|
+
f"Stopped the {Fore.GREEN}{ctx.prometheus_container_name}"
|
|
125
|
+
f"{Style.RESET_ALL} container."
|
|
126
|
+
)
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
api_key: {{ api_key }}
|
|
2
2
|
api_path: /api
|
|
3
3
|
databases:
|
|
4
|
-
{% for
|
|
4
|
+
{% for db in databases %}
|
|
5
|
+
{% for label, path in db.items() %}
|
|
5
6
|
- label: {{ label }}
|
|
6
7
|
uri: {{ path }}
|
|
7
8
|
type: csv
|
|
8
9
|
{% endfor %}
|
|
10
|
+
{% endfor %}
|
|
9
11
|
encryption:
|
|
10
12
|
enabled: false
|
|
11
13
|
private_key: null
|
|
@@ -31,4 +33,4 @@ logging:
|
|
|
31
33
|
port: {{ port }}
|
|
32
34
|
server_url: {{ server_url }}
|
|
33
35
|
task_dir: {{ task_dir}}
|
|
34
|
-
{{ user_provided_config }}
|
|
36
|
+
{{- user_provided_config -}}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
average = {
|
|
2
|
+
"collaboration": 1,
|
|
3
|
+
"organizations": [1],
|
|
4
|
+
"name": "test_average_task",
|
|
5
|
+
"image": "harbor2.vantage6.ai/demo/average",
|
|
6
|
+
"description": "",
|
|
7
|
+
"input_": {
|
|
8
|
+
"method": "central_average",
|
|
9
|
+
"args": [],
|
|
10
|
+
"kwargs": {"column_name": "Age"},
|
|
11
|
+
},
|
|
12
|
+
"databases": [{"label": "olympic_athletes"}],
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
kaplan_meier = {
|
|
16
|
+
"collaboration": 1,
|
|
17
|
+
"organizations": [1],
|
|
18
|
+
"name": "test_average_task",
|
|
19
|
+
"image": "harbor2.vantage6.ai/algorithms/kaplan-meier",
|
|
20
|
+
"description": "",
|
|
21
|
+
"input_": {
|
|
22
|
+
"method": "kaplan_meier_central",
|
|
23
|
+
"args": [],
|
|
24
|
+
"kwargs": {
|
|
25
|
+
"time_column_name": "days",
|
|
26
|
+
"censor_column_name": "censor",
|
|
27
|
+
"organizations_to_include": [1, 2, 3],
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
"databases": [{"label": "kaplan_meier_test"}],
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
args = {"average": average, "kaplan_meier": kaplan_meier}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import algo_test_arguments as arguments
|
|
3
|
+
import json
|
|
4
|
+
import sys
|
|
5
|
+
|
|
6
|
+
import vantage6.common.task_status as task_status
|
|
7
|
+
|
|
8
|
+
from vantage6.client import Client
|
|
9
|
+
from vantage6.common import error
|
|
10
|
+
from vantage6.common.globals import Ports
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def create_and_run_task(client: Client, task_args: dict, algo_name: str = "algorithm"):
|
|
14
|
+
"""
|
|
15
|
+
Create and run a task using the provided client and task arguments.
|
|
16
|
+
|
|
17
|
+
Parameters
|
|
18
|
+
----------
|
|
19
|
+
client: Client
|
|
20
|
+
The client instance to use for creating and running the task.
|
|
21
|
+
task_args: dict
|
|
22
|
+
The arguments to pass to the task creation method.
|
|
23
|
+
algo_name: str, optional
|
|
24
|
+
The name of the algorithm for logging purposes. Default is "algorithm".
|
|
25
|
+
|
|
26
|
+
Raises
|
|
27
|
+
------
|
|
28
|
+
AssertionError: If the task fails.
|
|
29
|
+
"""
|
|
30
|
+
task = client.task.create(**task_args)
|
|
31
|
+
task_id = task["id"]
|
|
32
|
+
client.wait_for_results(task_id)
|
|
33
|
+
|
|
34
|
+
try:
|
|
35
|
+
# check if the task has failed
|
|
36
|
+
assert not task_status.has_task_failed(client.task.get(task_id)["status"])
|
|
37
|
+
|
|
38
|
+
logging.info(f"Task for {algo_name} completed successfully.")
|
|
39
|
+
|
|
40
|
+
except AssertionError:
|
|
41
|
+
error(
|
|
42
|
+
f"Task for {algo_name} failed. Check the log file of the task "
|
|
43
|
+
f"{task_id} for more information."
|
|
44
|
+
)
|
|
45
|
+
exit(1)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def run_test(custom_args: dict | None = None):
|
|
49
|
+
"""
|
|
50
|
+
Run a test by creating and running tasks using the provided arguments.
|
|
51
|
+
|
|
52
|
+
Parameters
|
|
53
|
+
----------
|
|
54
|
+
custom_args: dict, optional
|
|
55
|
+
The arguments to pass to the task creation method. If not provided,
|
|
56
|
+
the arguments from the `arguments` module will be used.
|
|
57
|
+
"""
|
|
58
|
+
# Create a client and authenticate
|
|
59
|
+
client = Client("http://localhost", Ports.DEV_SERVER.value, "/api")
|
|
60
|
+
try:
|
|
61
|
+
client.authenticate("dev_admin", "password")
|
|
62
|
+
except ConnectionError:
|
|
63
|
+
error(
|
|
64
|
+
"Could not connect to the server. Please check if a dev network is running."
|
|
65
|
+
)
|
|
66
|
+
exit(1)
|
|
67
|
+
|
|
68
|
+
# if custom arguments are provided, use them for running the task
|
|
69
|
+
if custom_args:
|
|
70
|
+
create_and_run_task(client, custom_args)
|
|
71
|
+
|
|
72
|
+
else:
|
|
73
|
+
# Run the task for each algorithm in the arguments file
|
|
74
|
+
for algo in arguments.args:
|
|
75
|
+
logging.info(f"Running task for {algo}")
|
|
76
|
+
|
|
77
|
+
task_args = arguments.args[algo]
|
|
78
|
+
create_and_run_task(client, task_args, algo)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
if __name__ == "__main__":
|
|
82
|
+
# check if arguments are provided
|
|
83
|
+
if len(sys.argv) > 1:
|
|
84
|
+
input_string = sys.argv[1].replace("'", '"')
|
|
85
|
+
json_input = json.loads(input_string)
|
|
86
|
+
else:
|
|
87
|
+
json_input = None
|
|
88
|
+
|
|
89
|
+
run_test(json_input)
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import click
|
|
2
|
+
import json
|
|
3
|
+
import subprocess
|
|
4
|
+
import sys
|
|
5
|
+
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
from rich.console import Console
|
|
9
|
+
|
|
10
|
+
from vantage6.cli.dev.create import create_demo_network
|
|
11
|
+
from vantage6.cli.dev.remove import remove_demo_network
|
|
12
|
+
from vantage6.cli.dev.start import start_demo_network
|
|
13
|
+
from vantage6.cli.dev.stop import stop_demo_network
|
|
14
|
+
from vantage6.common.globals import Ports
|
|
15
|
+
|
|
16
|
+
TEST_FILE_PATH = Path(__file__).parent / "algo_test_scripts" / "algo_test_script.py"
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@click.command()
|
|
20
|
+
@click.option(
|
|
21
|
+
"--script",
|
|
22
|
+
type=click.Path(),
|
|
23
|
+
default=TEST_FILE_PATH,
|
|
24
|
+
help="Path of the script to test the algorithm. If a script is not provided, the default script is used.",
|
|
25
|
+
)
|
|
26
|
+
@click.option(
|
|
27
|
+
"--task-arguments",
|
|
28
|
+
type=str,
|
|
29
|
+
default=None,
|
|
30
|
+
help="Arguments to be provided to Task.create function. If --script is provided, this should not be set.",
|
|
31
|
+
)
|
|
32
|
+
@click.option(
|
|
33
|
+
"--create-dev-network",
|
|
34
|
+
is_flag=True,
|
|
35
|
+
help="Create a new dev network to run the test",
|
|
36
|
+
)
|
|
37
|
+
@click.option(
|
|
38
|
+
"--start-dev-network",
|
|
39
|
+
is_flag=True,
|
|
40
|
+
help="Start a dev network to run the test",
|
|
41
|
+
)
|
|
42
|
+
@click.option(
|
|
43
|
+
"-n", "--name", default=None, type=str, help="Name for your development setup"
|
|
44
|
+
)
|
|
45
|
+
@click.option(
|
|
46
|
+
"--server-url",
|
|
47
|
+
type=str,
|
|
48
|
+
default="http://host.docker.internal",
|
|
49
|
+
help="Server URL to point to. If you are using Docker Desktop, "
|
|
50
|
+
"the default http://host.docker.internal should not be changed.",
|
|
51
|
+
)
|
|
52
|
+
@click.option(
|
|
53
|
+
"-i", "--image", type=str, default=None, help="Server Docker image to use"
|
|
54
|
+
)
|
|
55
|
+
@click.option(
|
|
56
|
+
"--keep",
|
|
57
|
+
type=bool,
|
|
58
|
+
default=False,
|
|
59
|
+
help="Keep the dev network after finishing the test",
|
|
60
|
+
)
|
|
61
|
+
@click.option(
|
|
62
|
+
"--add-dataset",
|
|
63
|
+
type=(str, click.Path()),
|
|
64
|
+
default=[],
|
|
65
|
+
multiple=True,
|
|
66
|
+
help="Add a dataset to the nodes. The first argument is the label of the database, "
|
|
67
|
+
"the second is the path to the dataset file.",
|
|
68
|
+
)
|
|
69
|
+
@click.pass_context
|
|
70
|
+
def cli_test_client_script(
|
|
71
|
+
click_ctx: click.Context,
|
|
72
|
+
script: Path,
|
|
73
|
+
task_arguments: str,
|
|
74
|
+
name: str,
|
|
75
|
+
server_url: str,
|
|
76
|
+
create_dev_network: bool,
|
|
77
|
+
start_dev_network: bool,
|
|
78
|
+
image: str,
|
|
79
|
+
keep: bool,
|
|
80
|
+
add_dataset: list[tuple[str, Path]] = (),
|
|
81
|
+
) -> int:
|
|
82
|
+
"""
|
|
83
|
+
Run a script for testing an algorithm on a dev network.
|
|
84
|
+
The path to the script must be provided as an argument.
|
|
85
|
+
"""
|
|
86
|
+
if not (script or task_arguments):
|
|
87
|
+
raise click.UsageError("--script or --task-arguments must be set.")
|
|
88
|
+
elif script != TEST_FILE_PATH and task_arguments:
|
|
89
|
+
raise click.UsageError("--script and --task-arguments cannot be set together.")
|
|
90
|
+
|
|
91
|
+
# Check if the task_arguments is a valid JSON string
|
|
92
|
+
if task_arguments:
|
|
93
|
+
try:
|
|
94
|
+
json.loads(task_arguments.replace("'", '"'))
|
|
95
|
+
except json.JSONDecodeError:
|
|
96
|
+
raise click.UsageError("task-arguments must be a valid JSON string.")
|
|
97
|
+
|
|
98
|
+
# create the network
|
|
99
|
+
if create_dev_network:
|
|
100
|
+
click_ctx.invoke(
|
|
101
|
+
create_demo_network,
|
|
102
|
+
name=name,
|
|
103
|
+
num_nodes=3,
|
|
104
|
+
server_url=server_url,
|
|
105
|
+
server_port=Ports.DEV_SERVER.value,
|
|
106
|
+
image=image,
|
|
107
|
+
extra_server_config=None,
|
|
108
|
+
extra_node_config=None,
|
|
109
|
+
add_dataset=add_dataset,
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
# start the server and nodes
|
|
113
|
+
if create_dev_network or start_dev_network:
|
|
114
|
+
click_ctx.invoke(
|
|
115
|
+
start_demo_network,
|
|
116
|
+
name=name,
|
|
117
|
+
server_image=image,
|
|
118
|
+
node_image=image,
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
# run the test script and get the result
|
|
122
|
+
if not task_arguments:
|
|
123
|
+
subprocess_args = ["python", script]
|
|
124
|
+
else:
|
|
125
|
+
subprocess_args = ["python", script, task_arguments]
|
|
126
|
+
|
|
127
|
+
result = subprocess.run(subprocess_args, stdout=sys.stdout, stderr=sys.stderr)
|
|
128
|
+
|
|
129
|
+
# check the exit code. If the test passed, it should be 0
|
|
130
|
+
if result.returncode == 0:
|
|
131
|
+
msg = ":heavy_check_mark: [green]Test passed[/green]"
|
|
132
|
+
else:
|
|
133
|
+
msg = ":x: [red]Test failed[/red]"
|
|
134
|
+
|
|
135
|
+
console = Console()
|
|
136
|
+
console.print(msg)
|
|
137
|
+
|
|
138
|
+
# clean up the test resources
|
|
139
|
+
if not keep:
|
|
140
|
+
click_ctx.invoke(stop_demo_network, name=name)
|
|
141
|
+
click_ctx.invoke(remove_demo_network, name=name)
|
|
142
|
+
|
|
143
|
+
return result.returncode
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: vantage6
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.11.0rc2
|
|
4
4
|
Summary: vantage6 command line interface
|
|
5
5
|
Home-page: https://github.com/vantage6/vantage6
|
|
6
6
|
Requires-Python: >=3.10
|
|
@@ -16,8 +16,8 @@ Requires-Dist: questionary==1.10.0
|
|
|
16
16
|
Requires-Dist: rich==13.5.2
|
|
17
17
|
Requires-Dist: schema==0.7.5
|
|
18
18
|
Requires-Dist: SQLAlchemy==1.4.46
|
|
19
|
-
Requires-Dist: vantage6-common==4.
|
|
20
|
-
Requires-Dist: vantage6-client==4.
|
|
19
|
+
Requires-Dist: vantage6-common==4.11.0rc2
|
|
20
|
+
Requires-Dist: vantage6-client==4.11.0rc2
|
|
21
21
|
Provides-Extra: dev
|
|
22
22
|
Requires-Dist: coverage==6.4.4; extra == "dev"
|
|
23
23
|
Requires-Dist: black; extra == "dev"
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
tests_cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
tests_cli/test_client_script.py,sha256=pJiCk0Yu5xyAcj_FzdUCa4av0dKKrXvpr_Ybz9fW0ew,647
|
|
2
3
|
tests_cli/test_example.py,sha256=0fw_v-lgZEacshWSDwLNyLMA1_xc48bKUGM3ll-n1L0,146
|
|
3
4
|
tests_cli/test_node_cli.py,sha256=XAKRS1-SXdeBRz3ob25q467soCIB178pKVz8MJVZbCQ,17534
|
|
4
5
|
tests_cli/test_server_cli.py,sha256=DLcOWM0ZCRTs-XMNsNKCOEELUMh22Ayow1FvAFLI0aA,5879
|
|
5
6
|
tests_cli/test_wizard.py,sha256=NIj59eiCBuVNJXwhofrWLmLIKAsD45gSOzqOFWLmWhY,4916
|
|
6
|
-
vantage6/cli/__build__,sha256=
|
|
7
|
+
vantage6/cli/__build__,sha256=1HNeOiZeFu7gP1lxi5tdAwGcB9i2xR-Q2jpmbuwTqzU,1
|
|
7
8
|
vantage6/cli/__init__.py,sha256=ZXbeQ_-g2-M4XYteWZkoO5lMFYhqjm5doQgGy1fq8i0,125
|
|
8
|
-
vantage6/cli/_version.py,sha256=
|
|
9
|
-
vantage6/cli/cli.py,sha256=
|
|
10
|
-
vantage6/cli/configuration_manager.py,sha256=
|
|
9
|
+
vantage6/cli/_version.py,sha256=7g1VYEN766Mf9wGlm8bPgQO8QzE0d-l9gt02DbZwjWE,701
|
|
10
|
+
vantage6/cli/cli.py,sha256=L_t0sHUwVkEumkYg6MsXm_sdAEWEjiz5DkUa51ihGtU,6318
|
|
11
|
+
vantage6/cli/configuration_manager.py,sha256=YqObxbV4jl3K_0GiJcE0V7r2pFE2nETLEgP3yieYZaU,3695
|
|
11
12
|
vantage6/cli/configuration_wizard.py,sha256=ifqvrVqHkxoM0ZVUVIwlYXFByzAbuVlahNjmwFGLVRU,20874
|
|
12
|
-
vantage6/cli/globals.py,sha256=
|
|
13
|
+
vantage6/cli/globals.py,sha256=TBvO_ywYXRIyX1GlKUND_s6s9dPAEpdlh7p8i6aKSYA,1953
|
|
13
14
|
vantage6/cli/utils.py,sha256=Jfr6IeHMQDk_wU5X7rJ1dRY118dhVVX8PwzwMYMv9Vw,2481
|
|
14
15
|
vantage6/cli/algorithm/create.py,sha256=kRT1BlBcb0fDaB2Q988WxtA6EyAZmOW5QoU2uhbwBIo,2075
|
|
15
16
|
vantage6/cli/algorithm/update.py,sha256=WwAfTnq0kTOgePUsBzGoo1AJQqGMn82E9Bjk1wf61CQ,1338
|
|
@@ -27,8 +28,8 @@ vantage6/cli/context/__init__.py,sha256=e8rfY2tCyu6_SLQ-rbVzEHkDtmbnGCZRHFN_HH-2
|
|
|
27
28
|
vantage6/cli/context/algorithm_store.py,sha256=RimxNcoqfWeu2WQede6wsOu1rx-azzXIPVkCDqVJLWs,3944
|
|
28
29
|
vantage6/cli/context/base_server.py,sha256=paKSzNrKWD-J6eakHAtGELk2cD05A8NqoCAuQfF7c2s,2972
|
|
29
30
|
vantage6/cli/context/node.py,sha256=4R7X__u_pyZVvRSNO3ojTnVQFTWhuIemoHcGP6hsD5I,7444
|
|
30
|
-
vantage6/cli/context/server.py,sha256=
|
|
31
|
-
vantage6/cli/dev/create.py,sha256=
|
|
31
|
+
vantage6/cli/context/server.py,sha256=4BiccAakyXviGiV1SisZ0w0-0hrKAmCGVneZCRsSne8,4563
|
|
32
|
+
vantage6/cli/dev/create.py,sha256=ZN4BfExJVypl28ZKQEua0PIXpQCfcP8AC3RUhp1Cj-I,21280
|
|
32
33
|
vantage6/cli/dev/remove.py,sha256=R_OU_LXLDCnoD-2xnegg4lh0B3t8EgpqzDqueLx16io,3730
|
|
33
34
|
vantage6/cli/dev/start.py,sha256=fUMoPAEpmXoDAJidAmjIziaHZX1yqEErcrTKEXqPik8,4471
|
|
34
35
|
vantage6/cli/dev/stop.py,sha256=gPy87r8T3nqe7RFJjlYE9Bns8N3RiPPcdzNIFCoqGRY,1430
|
|
@@ -47,6 +48,7 @@ vantage6/cli/node/start.py,sha256=mV4vDBBtFcxva4MJdg5ymsstefDM4bV4pmhSsVX1o4k,12
|
|
|
47
48
|
vantage6/cli/node/stop.py,sha256=-jw0DChIoUScVVwY4SBi_AvmdXT0XlMsGVuO9_vrpJI,4085
|
|
48
49
|
vantage6/cli/node/version.py,sha256=X921xyIvIPYObPac2Si5msZ2tay5ySidnPWmGj1ilZw,1959
|
|
49
50
|
vantage6/cli/node/common/__init__.py,sha256=ziGS3skkX6Kf4uvFqe22kdFbSck7mubNK5a-KgDAxX8,3467
|
|
51
|
+
vantage6/cli/prometheus/monitoring_manager.py,sha256=fbzzUkXKogoHgfR-pKn7DASMBfXZnio8ft77VMBSjDE,4889
|
|
50
52
|
vantage6/cli/rabbitmq/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
51
53
|
vantage6/cli/rabbitmq/definitions.py,sha256=CcS9jG7ZGB6LjzHQqZ2FliDurPItUvNSjHrOYptORZg,637
|
|
52
54
|
vantage6/cli/rabbitmq/queue_manager.py,sha256=KGDGHy4NBN8O9xhjzfI7mh65i9lOQIqQwrOFqvGFdHI,7545
|
|
@@ -58,19 +60,22 @@ vantage6/cli/server/list.py,sha256=_kVBe7TrtUfT2ZLWPkVvKj4xx5AvS17e99Bwp0ajc_E,4
|
|
|
58
60
|
vantage6/cli/server/new.py,sha256=JnUMMD0UUSCOdO0K7v19l5HOV7vnMd9D38WUoEJ2F00,2094
|
|
59
61
|
vantage6/cli/server/remove.py,sha256=6tfKfVa5dYnZAKQYo_VlGZTuiugi7sh2F3U2cZ7mCmQ,1627
|
|
60
62
|
vantage6/cli/server/shell.py,sha256=7cSdBOwvloWyCz3RXHaFZUnxgNRV4gZUDmIFecV8Hks,1589
|
|
61
|
-
vantage6/cli/server/start.py,sha256=
|
|
62
|
-
vantage6/cli/server/stop.py,sha256=
|
|
63
|
+
vantage6/cli/server/start.py,sha256=u3wWHlS7FjAkOHndCrebC6uCPuvRUQFci7dSlGDYMTs,9614
|
|
64
|
+
vantage6/cli/server/stop.py,sha256=CP8WtMLkxRhKRr6PnATkCzjJoSVzy9XR9B1ETWtarmU,4422
|
|
63
65
|
vantage6/cli/server/version.py,sha256=aXAztHEky_F2jPbfPdHPfsAY7rdTurl0_3S6bL94_QQ,1318
|
|
64
66
|
vantage6/cli/server/common/__init__.py,sha256=htv0mFYa4GhIHdzA2xqUUgKhHcMh09UQERlIjIgrwOM,2062
|
|
65
67
|
vantage6/cli/template/algo_store_config.j2,sha256=XR-ly-47p6egH8lVh4lZZDh3YSV4kFnkZprdsfSkS2Y,552
|
|
66
|
-
vantage6/cli/template/node_config.j2,sha256=
|
|
68
|
+
vantage6/cli/template/node_config.j2,sha256=1uK21oLan2r48-v_HyIW2TeO5bR9ER_Wy0PICHQ-xXo,781
|
|
67
69
|
vantage6/cli/template/server_config.j2,sha256=3gEPY8YlqUMAQEgfR7a1HTU8WaCRhVzTS-IwPhsU1Gg,802
|
|
68
70
|
vantage6/cli/template/server_import_config.j2,sha256=9WT2XeG9-ADoYLb4ahXhof3i9Fcvg0oqwNPyFwLJpvc,1827
|
|
71
|
+
vantage6/cli/test/client_script.py,sha256=yKZECAMox8sgnHZQyxWTBxILnqQIAbf6v884wgaMkuE,4195
|
|
69
72
|
vantage6/cli/test/feature_tester.py,sha256=M8hvebupPwYjcBZoUB8GB3qb8G1-d3ipNzRMc_3-Z8E,2761
|
|
70
73
|
vantage6/cli/test/integration_test.py,sha256=yQVG72XKDNH_eOPTsf3pb65FCBwJzMxn5VNfUGemJBM,3808
|
|
74
|
+
vantage6/cli/test/algo_test_scripts/algo_test_arguments.py,sha256=PfJUwXXbOUvs8W2i3XqIoNNkqvnXmRTv19kKcpg9ouk,888
|
|
75
|
+
vantage6/cli/test/algo_test_scripts/algo_test_script.py,sha256=F1meN4vI4Nz7_RXD_-xmclfw3M5MzBKGINgzbZmDaN8,2652
|
|
71
76
|
vantage6/cli/test/common/diagnostic_runner.py,sha256=x_4ikihgoSTKI914pqlgVziBSg5LpV6MheO6O_GBCeA,6657
|
|
72
|
-
vantage6-4.
|
|
73
|
-
vantage6-4.
|
|
74
|
-
vantage6-4.
|
|
75
|
-
vantage6-4.
|
|
76
|
-
vantage6-4.
|
|
77
|
+
vantage6-4.11.0rc2.dist-info/METADATA,sha256=0ATXMr019zRsaUuKNRhin-W_4AUlfbNB3SOT1st4vAg,10890
|
|
78
|
+
vantage6-4.11.0rc2.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
|
|
79
|
+
vantage6-4.11.0rc2.dist-info/entry_points.txt,sha256=YFBvwjxoeAGxYyPC-YevEgOBBYRGaXkS6jiOGGCLNy0,157
|
|
80
|
+
vantage6-4.11.0rc2.dist-info/top_level.txt,sha256=CYDIBS8jEfFq5YCs_Fuit54K9-3wdosZppTrsymIoUk,19
|
|
81
|
+
vantage6-4.11.0rc2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|