vantage6 5.0.0a34__py3-none-any.whl → 5.0.0a36__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 (69) hide show
  1. vantage6/cli/algorithm/generate_algorithm_json.py +9 -9
  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 +83 -2
  7. vantage6/cli/algostore/remove.py +18 -34
  8. vantage6/cli/algostore/start.py +10 -7
  9. vantage6/cli/algostore/stop.py +12 -50
  10. vantage6/cli/auth/attach.py +60 -0
  11. vantage6/cli/auth/files.py +16 -0
  12. vantage6/cli/auth/list.py +13 -0
  13. vantage6/cli/auth/new.py +80 -0
  14. vantage6/cli/auth/remove.py +31 -0
  15. vantage6/cli/auth/start.py +80 -0
  16. vantage6/cli/auth/stop.py +64 -0
  17. vantage6/cli/cli.py +67 -37
  18. vantage6/cli/common/new.py +28 -3
  19. vantage6/cli/common/remove.py +54 -0
  20. vantage6/cli/common/start.py +31 -2
  21. vantage6/cli/common/stop.py +79 -1
  22. vantage6/cli/common/utils.py +47 -4
  23. vantage6/cli/configuration_manager.py +57 -13
  24. vantage6/cli/configuration_wizard.py +18 -397
  25. vantage6/cli/context/__init__.py +3 -0
  26. vantage6/cli/context/auth.py +107 -0
  27. vantage6/cli/context/base_server.py +0 -4
  28. vantage6/cli/context/node.py +10 -17
  29. vantage6/cli/dev/clean.py +28 -0
  30. vantage6/cli/dev/common.py +34 -0
  31. vantage6/cli/dev/rebuild.py +39 -0
  32. vantage6/cli/dev/start.py +36 -0
  33. vantage6/cli/dev/stop.py +23 -0
  34. vantage6/cli/globals.py +24 -1
  35. vantage6/cli/node/attach.py +1 -0
  36. vantage6/cli/node/files.py +12 -25
  37. vantage6/cli/node/list.py +5 -4
  38. vantage6/cli/node/new.py +348 -28
  39. vantage6/cli/node/remove.py +14 -90
  40. vantage6/cli/node/restart.py +30 -51
  41. vantage6/cli/node/start.py +81 -304
  42. vantage6/cli/node/stop.py +36 -96
  43. vantage6/cli/node/version.py +5 -4
  44. vantage6/cli/prometheus/monitoring_manager.py +5 -3
  45. vantage6/cli/rabbitmq/queue_manager.py +13 -11
  46. vantage6/cli/server/attach.py +1 -0
  47. vantage6/cli/server/common/__init__.py +1 -27
  48. vantage6/cli/server/import_.py +1 -1
  49. vantage6/cli/server/new.py +83 -2
  50. vantage6/cli/server/remove.py +12 -33
  51. vantage6/cli/server/start.py +8 -6
  52. vantage6/cli/server/stop.py +10 -39
  53. vantage6/cli/template/algo_store_config.j2 +1 -1
  54. vantage6/cli/template/auth_config.j2 +230 -0
  55. vantage6/cli/template/node_config.j2 +336 -33
  56. vantage6/cli/template/node_config_nonk8s.j2 +33 -0
  57. vantage6/cli/test/common/diagnostic_runner.py +5 -3
  58. vantage6/cli/use/namespace.py +2 -1
  59. vantage6/cli/utils.py +0 -2
  60. {vantage6-5.0.0a34.dist-info → vantage6-5.0.0a36.dist-info}/METADATA +3 -3
  61. vantage6-5.0.0a36.dist-info/RECORD +86 -0
  62. vantage6/cli/dev/create.py +0 -693
  63. vantage6/cli/dev/data/km_dataset.csv +0 -2401
  64. vantage6/cli/dev/remove.py +0 -112
  65. vantage6/cli/node/clean.py +0 -46
  66. vantage6/cli/server/shell.py +0 -54
  67. vantage6-5.0.0a34.dist-info/RECORD +0 -75
  68. {vantage6-5.0.0a34.dist-info → vantage6-5.0.0a36.dist-info}/WHEEL +0 -0
  69. {vantage6-5.0.0a34.dist-info → vantage6-5.0.0a36.dist-info}/entry_points.txt +0 -0
@@ -1,693 +0,0 @@
1
- from importlib import resources as impresources
2
- from pathlib import Path
3
-
4
- import click
5
- import pandas as pd
6
- import yaml
7
- from colorama import Fore, Style
8
- from jinja2 import Environment, FileSystemLoader
9
-
10
- from vantage6.common import ensure_config_dir_writable, error, generate_apikey, info
11
- from vantage6.common.globals import APPNAME, InstanceType, Ports
12
-
13
- import vantage6.cli.dev.data as data_dir
14
- from vantage6.cli.context.algorithm_store import AlgorithmStoreContext
15
- from vantage6.cli.context.node import NodeContext
16
- from vantage6.cli.context.server import ServerContext
17
- from vantage6.cli.globals import PACKAGE_FOLDER, DefaultDatasets
18
- from vantage6.cli.server.common import get_server_context
19
- from vantage6.cli.server.import_ import cli_server_import
20
- from vantage6.cli.utils import prompt_config_name
21
-
22
-
23
- def create_node_data_files(
24
- num_nodes: int, server_name: str, dataset: tuple[str, Path]
25
- ) -> list[tuple[str, Path]]:
26
- """Create data files for nodes.
27
-
28
- Parameters
29
- ----------
30
- num_nodes : int
31
- Number of nodes to create data files for.
32
- server_name : str
33
- Name of the server.
34
- dataset : tuple[str, Path]
35
- Tuple containing the name and the path to the dataset.
36
- Returns
37
- -------
38
- list[tuple[str, Path]]
39
- List of the label and paths to the created data files.
40
- """
41
- info(f"Creating data files for {num_nodes} nodes.")
42
- data_files = []
43
- full_df = pd.read_csv(dataset[1])
44
- length_df = len(full_df)
45
- for i in range(num_nodes):
46
- node_name = f"{server_name}_node_{i + 1}"
47
- dev_folder = NodeContext.instance_folders("node", node_name, False)["dev"]
48
- data_folder = Path(dev_folder / server_name)
49
- data_folder.mkdir(parents=True, exist_ok=True)
50
-
51
- # Split the data over the nodes
52
- start = i * length_df // num_nodes
53
- end = (i + 1) * length_df // num_nodes
54
- data = full_df[start:end]
55
- data_file = data_folder / f"df_{dataset[0]}_{node_name}.csv"
56
-
57
- # write data to file
58
- data.to_csv(data_file, index=False)
59
- data_files.append((dataset[0], data_file))
60
- return data_files
61
-
62
-
63
- def create_node_config_file(
64
- server_url: str,
65
- port: int,
66
- config: dict,
67
- server_name: str,
68
- datasets: list[tuple[str, Path]] = (),
69
- ) -> None:
70
- """Create a node configuration file (YAML).
71
-
72
- Creates a node configuration for a simulated organization. Organization ID
73
- is used for generating both the organization name and node_name as each
74
- organization only houses one node.
75
-
76
- Parameters
77
- ----------
78
- server_url : str
79
- Url of the dummy server.
80
- port : int
81
- Port of the dummy server.
82
- config : dict
83
- Configuration dictionary containing org_id, api_key, node name and
84
- additional user_defined_config.
85
- server_name : str
86
- Configuration name of the dummy server.
87
- datasets : list[tuple[str, Path]]
88
- List of tuples containing the labels and the paths to the datasets
89
- """
90
- environment = Environment(
91
- loader=FileSystemLoader(PACKAGE_FOLDER / APPNAME / "cli" / "template"),
92
- trim_blocks=True,
93
- lstrip_blocks=True,
94
- autoescape=True,
95
- )
96
- template = environment.get_template("node_config.j2")
97
-
98
- # TODO: make this name specific to the server it connects
99
- node_name = config["node_name"]
100
- folders = NodeContext.instance_folders("node", node_name, False)
101
- path_to_dev_dir = Path(folders["dev"] / server_name)
102
- path_to_dev_dir.mkdir(parents=True, exist_ok=True)
103
-
104
- path_to_data_dir = Path(folders["data"])
105
- path_to_data_dir.mkdir(parents=True, exist_ok=True)
106
- full_path = Path(folders["config"] / f"{node_name}.yaml")
107
-
108
- if full_path.exists():
109
- error(f"Node configuration file already exists: {full_path}")
110
- exit(1)
111
-
112
- databases = [{dataset[0]: dataset[1]} for dataset in datasets]
113
-
114
- node_config = template.render(
115
- {
116
- "api_key": config["api_key"],
117
- "databases": databases,
118
- "logging": {"file": f"{node_name}.log"},
119
- "port": port,
120
- "server_url": server_url,
121
- "task_dir": str(path_to_data_dir),
122
- "user_provided_config": config["user_defined_config"],
123
- }
124
- )
125
-
126
- # Check that we can write the node config
127
- if not ensure_config_dir_writable():
128
- error("Cannot write configuration file. Exiting...")
129
- exit(1)
130
-
131
- Path(full_path).parent.mkdir(parents=True, exist_ok=True)
132
- with open(full_path, "x", encoding="utf-8") as f:
133
- f.write(node_config)
134
-
135
- info(
136
- f"Spawned node for organization {Fore.GREEN}{config['org_id']}{Style.RESET_ALL}"
137
- )
138
-
139
-
140
- def _read_extra_config_file(extra_config_file: Path | None) -> str:
141
- """Reads extra configuration file.
142
-
143
- Parameters
144
- ----------
145
- extra_config_file : Path | None
146
- Path to file with additional configuration.
147
-
148
- Returns
149
- -------
150
- str
151
- Extra configuration file content
152
- """
153
- if extra_config_file:
154
- # read the YAML file as string, so it can be appended to the
155
- # configuration easily
156
- with open(extra_config_file, "r", encoding="utf-8") as f:
157
- return f.read()
158
- return ""
159
-
160
-
161
- def generate_node_configs(
162
- num_nodes: int,
163
- server_url: str,
164
- port: int,
165
- server_name: str,
166
- extra_node_config: Path | None,
167
- extra_datasets: list[tuple[str, Path]],
168
- ) -> list[dict]:
169
- """Generates ``num_nodes`` node configuration files.
170
-
171
- Parameters
172
- ----------
173
- num_nodes : int
174
- Integer to determine how many configurations to create.
175
- server_url : str
176
- Url of the dummy server.
177
- port : int
178
- Port of the dummy server.
179
- server_name : str
180
- Configuration name of the dummy server.
181
- extra_node_config : Path | None
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
185
-
186
- Returns
187
- -------
188
- list[dict]
189
- List of dictionaries containing node configurations.
190
- """
191
- configs = []
192
- node_data_files = []
193
- extra_config = _read_extra_config_file(extra_node_config)
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
-
222
- for i in range(num_nodes):
223
- config = {
224
- "org_id": i + 1,
225
- "api_key": generate_apikey(),
226
- "node_name": f"{server_name}_node_{i + 1}",
227
- "user_defined_config": extra_config,
228
- }
229
- create_node_config_file(
230
- server_url,
231
- port,
232
- config,
233
- server_name,
234
- [files[i] for files in node_data_files],
235
- )
236
- configs.append(config)
237
-
238
- return configs
239
-
240
-
241
- def create_vserver_import_config(node_configs: list[dict], server_name: str) -> Path:
242
- """Create server configuration import file (YAML).
243
-
244
- Utilized by the ``v6 server import`` command.
245
-
246
- Parameters
247
- ----------
248
- node_configs : list[dict]
249
- List of dictionaries containing the node configurations, returned from
250
- ``generate_node_configs()``.
251
- server_name : str
252
- Server name.
253
-
254
- Returns
255
- -------
256
- Path
257
- Path object where the server import configuration is stored.
258
- """
259
- environment = Environment(
260
- loader=FileSystemLoader(PACKAGE_FOLDER / APPNAME / "cli" / "template"),
261
- trim_blocks=True,
262
- lstrip_blocks=True,
263
- autoescape=True,
264
- )
265
- template = environment.get_template("server_import_config.j2")
266
-
267
- organizations = []
268
- collaboration = {"name": "demo", "participants": []}
269
- for config in node_configs:
270
- org_id = config["org_id"]
271
- org_data = {"name": f"org_{org_id}"}
272
-
273
- organizations.append(org_data)
274
- collaboration["participants"].append(
275
- {"name": f"org_{org_id}", "api_key": config["api_key"]}
276
- )
277
- organizations[0]["make_admin"] = True
278
- info(
279
- f"Organization {Fore.GREEN}{node_configs[0]['org_id']}"
280
- f"{Style.RESET_ALL} is the admin"
281
- )
282
-
283
- server_import_config = template.render(
284
- organizations=organizations, collaboration=collaboration
285
- )
286
- folders = ServerContext.instance_folders(InstanceType.SERVER, server_name, False)
287
-
288
- demo_dir = Path(folders["dev"])
289
- demo_dir.mkdir(parents=True, exist_ok=True)
290
- full_path = demo_dir / f"{server_name}.yaml"
291
- if full_path.exists():
292
- error(f"Server configuration file already exists: {full_path}")
293
- exit(1)
294
-
295
- try:
296
- with open(full_path, "x") as f:
297
- f.write(server_import_config)
298
- info(
299
- "Server import configuration ready, writing to "
300
- f"{Fore.GREEN}{full_path}{Style.RESET_ALL}"
301
- )
302
- except Exception as e:
303
- error(f"Could not write server import configuration file: {e}")
304
- exit(1)
305
-
306
- return full_path
307
-
308
-
309
- def create_vserver_config(
310
- server_name: str,
311
- port: int,
312
- server_url: str,
313
- extra_config_file: Path,
314
- ui_image: str | None,
315
- ui_port: int,
316
- store_port: int,
317
- ) -> Path:
318
- """Creates server configuration file (YAML).
319
-
320
- Parameters
321
- ----------
322
- server_name : str
323
- Server name.
324
- port : int
325
- Server port.
326
- server_url : str
327
- Url of the server this
328
- extra_config_file : Path
329
- Path to file with additional server configuration.
330
- ui_image : str | None
331
- UI docker image to specify in configuration files. Will be used on startup of
332
- the network.
333
- ui_port : int
334
- Port to run the UI on.
335
- store_port : int
336
- Port to run the algorithm store on.
337
-
338
- Returns
339
- -------
340
- Path
341
- Path object where server configuration is stored.
342
- """
343
- environment = Environment(
344
- loader=FileSystemLoader(PACKAGE_FOLDER / APPNAME / "cli" / "template"),
345
- trim_blocks=True,
346
- lstrip_blocks=True,
347
- autoescape=True,
348
- )
349
-
350
- extra_config = _read_extra_config_file(extra_config_file)
351
- if ui_image is not None:
352
- if extra_config:
353
- extra_config += "\n"
354
- extra_config += f"images:\n ui: {ui_image}"
355
-
356
- template = environment.get_template("server_config.j2")
357
- server_config = template.render(
358
- port=port,
359
- host_uri=server_url,
360
- user_provided_config=extra_config,
361
- ui_port=ui_port,
362
- store_port=store_port,
363
- )
364
- folders = ServerContext.instance_folders(
365
- instance_type=InstanceType.SERVER,
366
- instance_name=server_name,
367
- system_folders=False,
368
- )
369
-
370
- config_dir = Path(folders["config"] / server_name)
371
- config_dir.mkdir(parents=True, exist_ok=True)
372
- full_path = folders["config"] / f"{server_name}.yaml"
373
- if full_path.exists():
374
- error(f"Server configuration file already exists: {full_path}")
375
- exit(1)
376
-
377
- try:
378
- with open(full_path, "x") as f:
379
- f.write(server_config)
380
- info(
381
- "Server configuration read, writing to "
382
- f"{Fore.GREEN}{full_path}{Style.RESET_ALL}"
383
- )
384
- except Exception as e:
385
- error(f"Could not write server configuration file: {e}")
386
- exit(1)
387
-
388
- return full_path
389
-
390
-
391
- def create_algo_store_config(
392
- server_name: str,
393
- server_url: str,
394
- server_port: int,
395
- store_port: int,
396
- extra_config_file: Path,
397
- ) -> Path:
398
- """Create algorithm store configuration file (YAML).
399
-
400
- Parameters
401
- ----------
402
- server_name : str
403
- Server name.
404
- server_url : str
405
- Url of the server this store connects to.
406
- server_port : int
407
- Port of the server this store connects to.
408
- port : int
409
- Port of the algorithm store.
410
- extra_config_file : Path
411
- Path to file with additional algorithm store configuration.
412
- """
413
- environment = Environment(
414
- loader=FileSystemLoader(PACKAGE_FOLDER / APPNAME / "cli" / "template"),
415
- trim_blocks=True,
416
- lstrip_blocks=True,
417
- autoescape=True,
418
- )
419
-
420
- extra_config = _read_extra_config_file(extra_config_file)
421
-
422
- template = environment.get_template("algo_store_config.j2")
423
- store_config = template.render(
424
- port=store_port,
425
- server_port=server_port,
426
- host_uri=server_url,
427
- user_provided_config=extra_config,
428
- )
429
- folders = AlgorithmStoreContext.instance_folders(
430
- instance_type=InstanceType.ALGORITHM_STORE,
431
- instance_name=f"{server_name}_store",
432
- system_folders=False,
433
- )
434
-
435
- config_dir = Path(folders["config"] / f"{server_name}_store")
436
- config_dir.mkdir(parents=True, exist_ok=True)
437
- full_path = folders["config"] / f"{server_name}_store.yaml"
438
- if full_path.exists():
439
- error(f"Algorithm store configuration file already exists: {full_path}")
440
- exit(1)
441
-
442
- try:
443
- with open(full_path, "x") as f:
444
- f.write(store_config)
445
- info(
446
- "Algorithm store configuration ready, writing to "
447
- f"{Fore.GREEN}{full_path}{Style.RESET_ALL}"
448
- )
449
- except Exception as e:
450
- error(f"Could not write algorithm store configuration file: {e}")
451
- exit(1)
452
-
453
- return full_path
454
-
455
-
456
- def demo_network(
457
- num_nodes: int,
458
- server_url: str,
459
- server_port: int,
460
- server_name: str,
461
- extra_server_config: Path,
462
- extra_node_config: Path,
463
- extra_store_config: Path,
464
- ui_image: str,
465
- ui_port: int,
466
- algorithm_store_port: int,
467
- extra_datasets: list[tuple[str, Path]],
468
- ) -> tuple[list[dict], Path, Path]:
469
- """Generates the demo network.
470
-
471
- Parameters
472
- ----------
473
- num_nodes : int
474
- Integer to determine how many configurations to create.
475
- server_url : str
476
- Url of the dummy server.
477
- server_port : int
478
- Port of the dummy server.
479
- server_name : str
480
- Server name.
481
- extra_server_config : Path
482
- Path to file with additional server configuration.
483
- extra_node_config : Path
484
- Path to file with additional node configuration.
485
- extra_store_config : Path
486
- Path to file with additional algorithm store configuration.
487
- ui_image : str | None
488
- UI docker image to specify in configuration files. Will be used on startup of
489
- the network.
490
- ui_port : int
491
- Port to run the UI on.
492
- algorithm_store_port : int
493
- Port to run the algorithm store on.
494
- extra_datasets : list[tuple[str, Path]]
495
- List of tuples containing the labels and the paths to extra datasets
496
-
497
- Returns
498
- -------
499
- tuple[list[dict], Path, Path]
500
- Tuple containing node, server import and server configurations.
501
- """
502
- node_configs = generate_node_configs(
503
- num_nodes,
504
- server_url,
505
- server_port,
506
- server_name,
507
- extra_node_config,
508
- extra_datasets,
509
- )
510
- server_import_config = create_vserver_import_config(node_configs, server_name)
511
- server_config = create_vserver_config(
512
- server_name,
513
- server_port,
514
- server_url,
515
- extra_server_config,
516
- ui_image,
517
- ui_port,
518
- algorithm_store_port,
519
- )
520
- store_config = create_algo_store_config(
521
- server_name, server_url, server_port, algorithm_store_port, extra_store_config
522
- )
523
- return (node_configs, server_import_config, server_config, store_config)
524
-
525
-
526
- @click.command()
527
- @click.option(
528
- "-n", "--name", default=None, type=str, help="Name for your development setup"
529
- )
530
- @click.option(
531
- "--num-nodes",
532
- type=int,
533
- default=3,
534
- help="Generate this number of nodes in the development network",
535
- )
536
- @click.option(
537
- "--server-url",
538
- type=str,
539
- default="http://host.docker.internal",
540
- help="Server URL to point to. If you are using Docker Desktop, the default "
541
- "http://host.docker.internal should not be changed. If you are using Linux without"
542
- " Docker Desktop, you should set this to http://172.17.0.1",
543
- )
544
- @click.option(
545
- "-p",
546
- "--server-port",
547
- type=int,
548
- default=Ports.DEV_SERVER.value,
549
- help=f"Port to run the server on. Default is {Ports.DEV_SERVER}.",
550
- )
551
- @click.option(
552
- "--ui-port",
553
- type=int,
554
- default=Ports.DEV_UI.value,
555
- help=f"Port to run the UI on. Default is {Ports.DEV_UI}.",
556
- )
557
- @click.option(
558
- "--algorithm-store-port",
559
- type=int,
560
- default=Ports.DEV_ALGO_STORE.value,
561
- help=(f"Port to run the algorithm store on. Default is {Ports.DEV_ALGO_STORE}."),
562
- )
563
- @click.option(
564
- "-i",
565
- "--image",
566
- type=str,
567
- default=None,
568
- help="Server docker image to use when setting up resources for "
569
- "the development server",
570
- )
571
- @click.option(
572
- "--ui-image",
573
- type=str,
574
- default=None,
575
- help="UI docker image to specify in configuration files. Will be used on startup of"
576
- " the network",
577
- )
578
- @click.option(
579
- "--extra-server-config",
580
- type=click.Path(exists=True),
581
- default=None,
582
- help="YAML File with additional server "
583
- "configuration. This will be appended to the server "
584
- "configuration file",
585
- )
586
- @click.option(
587
- "--extra-node-config",
588
- type=click.Path("rb"),
589
- default=None,
590
- help="YAML File with additional node configuration. This will be"
591
- " appended to each of the node configuration files",
592
- )
593
- @click.option(
594
- "--extra-store-config",
595
- type=click.Path("rb"),
596
- default=None,
597
- help="YAML File with additional algorithm store configuration. This will be"
598
- " appended to the algorithm store configuration file",
599
- )
600
- @click.option(
601
- "--add-dataset",
602
- type=(str, click.Path()),
603
- default=(),
604
- multiple=True,
605
- help="Add a dataset to the nodes. The first argument is the label of the database, "
606
- "the second is the path to the dataset file.",
607
- )
608
- @click.pass_context
609
- def create_demo_network(
610
- click_ctx: click.Context,
611
- name: str,
612
- num_nodes: int,
613
- server_url: str,
614
- server_port: int,
615
- ui_port: int,
616
- algorithm_store_port: int,
617
- image: str = None,
618
- ui_image: str = None,
619
- extra_server_config: Path = None,
620
- extra_node_config: Path = None,
621
- extra_store_config: Path = None,
622
- add_dataset: list[tuple[str, Path]] = (),
623
- ) -> dict:
624
- """Creates a demo network.
625
-
626
- Creates server instance as well as its import configuration file. Server
627
- name is set to 'dev_default_server'. Generates `n` node configurations, but
628
- by default this is set to 3. Then runs a Batch import of
629
- organizations/collaborations/users and tasks.
630
- """
631
- server_name = prompt_config_name(name)
632
- if not ServerContext.config_exists(server_name, False):
633
- demo = demo_network(
634
- num_nodes,
635
- server_url,
636
- server_port,
637
- server_name,
638
- extra_server_config,
639
- extra_node_config,
640
- extra_store_config,
641
- ui_image,
642
- ui_port,
643
- algorithm_store_port,
644
- list(add_dataset),
645
- )
646
- info(
647
- f"Created {Fore.GREEN}{len(demo[0])}{Style.RESET_ALL} node "
648
- f"configuration(s), attaching them to {Fore.GREEN}{server_name}"
649
- f"{Style.RESET_ALL}."
650
- )
651
- else:
652
- error(f"Configuration {Fore.RED}{server_name}{Style.RESET_ALL} already exists!")
653
- exit(1)
654
- (node_config, server_import_config, server_config, store_config) = demo
655
- ctx = get_server_context(server_name, False, ServerContext)
656
- click_ctx.invoke(
657
- cli_server_import,
658
- ctx=ctx,
659
- file=server_import_config,
660
- drop_all=False,
661
- image=image,
662
- mount_src="",
663
- keep=False,
664
- wait=True,
665
- )
666
- info(
667
- "Development network was set up successfully! You can now start the "
668
- f"server and nodes with {Fore.GREEN}v6 dev start-demo-network"
669
- f"{Style.RESET_ALL}"
670
- )
671
- # find user credentials to print. Read from server import file
672
- with open(server_import_config, "r") as f:
673
- server_import_config = yaml.safe_load(f)
674
-
675
- try:
676
- user = server_import_config["organizations"][0]["users"][0]
677
- username = user["username"]
678
- password = user["password"]
679
- info(
680
- "You can login with the following credentials:\n"
681
- f"Username: {username}\n"
682
- f"Password: {password}\n"
683
- )
684
- except KeyError:
685
- # No user found, skip printing credentials
686
- pass
687
-
688
- return {
689
- "node_configs": node_config,
690
- "server_import_config": server_import_config,
691
- "server_config": server_config,
692
- "store_config": store_config,
693
- }