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
@@ -4,9 +4,9 @@ from pathlib import Path
4
4
  import click
5
5
 
6
6
  from vantage6.common import error
7
- from vantage6.common.globals import InstanceType
7
+ from vantage6.common.globals import SANDBOX_SUFFIX, InstanceType
8
8
 
9
- from vantage6.cli.configuration_wizard import select_configuration_questionaire
9
+ from vantage6.cli.configuration_create import select_configuration_questionnaire
10
10
  from vantage6.cli.context import get_context, select_context_class
11
11
 
12
12
 
@@ -14,6 +14,8 @@ def click_insert_context(
14
14
  type_: InstanceType,
15
15
  include_name: bool = False,
16
16
  include_system_folders: bool = False,
17
+ is_sandbox: bool = False,
18
+ sandbox_param: str | None = None,
17
19
  ) -> callable:
18
20
  """
19
21
  Supply the Click function with an additional context parameter. The context
@@ -27,6 +29,12 @@ def click_insert_context(
27
29
  Include the name of the configuration as an argument
28
30
  include_system_folders : bool
29
31
  Include whether or not to use the system folders as an argument
32
+ is_sandbox : bool
33
+ Include whether or not to use the sandbox configurations as an argument
34
+ sandbox_param : str | None
35
+ Name of a Click option/parameter in the command function whose boolean
36
+ value should determine sandbox mode at runtime. If provided, this value
37
+ overrides the static is_sandbox parameter.
30
38
 
31
39
  Returns
32
40
  -------
@@ -58,7 +66,7 @@ def click_insert_context(
58
66
  "--user",
59
67
  "system_folders",
60
68
  flag_value=False,
61
- default=False if type_ == InstanceType.NODE else True,
69
+ default=False if type_ == InstanceType.NODE or is_sandbox else True,
62
70
  help="Use user folders instead of system folders",
63
71
  )
64
72
  @wraps(func)
@@ -74,6 +82,15 @@ def click_insert_context(
74
82
  Decorated function
75
83
  """
76
84
  ctx_class = select_context_class(type_)
85
+
86
+ # Determine sandbox mode, preferring runtime option when provided
87
+ runtime_is_sandbox = is_sandbox
88
+ if sandbox_param is not None:
89
+ # Pop to avoid passing unknown kwarg to the wrapped function
90
+ runtime_is_sandbox = bool(kwargs.pop(sandbox_param, False))
91
+ if runtime_is_sandbox and name and name.endswith(SANDBOX_SUFFIX):
92
+ name = name[: -len(SANDBOX_SUFFIX)]
93
+
77
94
  # path to configuration file always overrides name
78
95
  if config:
79
96
  ctx = ctx_class.from_external_config_file(config, system_folders)
@@ -87,12 +104,14 @@ def click_insert_context(
87
104
  if not name:
88
105
  try:
89
106
  # select configuration if none supplied
90
- name = select_configuration_questionaire(type_, system_folders)
107
+ name = select_configuration_questionnaire(
108
+ type_, system_folders, runtime_is_sandbox
109
+ )
91
110
  except Exception:
92
111
  error("No configurations could be found!")
93
112
  exit(1)
94
113
 
95
- ctx = get_context(type_, name, system_folders)
114
+ ctx = get_context(type_, name, system_folders, runtime_is_sandbox)
96
115
  extra_args = []
97
116
  if include_name:
98
117
  if not name:
@@ -1,3 +1,5 @@
1
+ from pathlib import Path
2
+
1
3
  from colorama import Fore, Style
2
4
 
3
5
  from vantage6.common import ensure_config_dir_writable, error, info
@@ -5,26 +7,30 @@ from vantage6.common.globals import InstanceType
5
7
 
6
8
  from vantage6.cli.common.utils import get_main_cli_command_name
7
9
  from vantage6.cli.config import CliConfig
8
- from vantage6.cli.configuration_wizard import configuration_wizard
10
+ from vantage6.cli.configuration_create import make_configuration
9
11
  from vantage6.cli.context import select_context_class
10
12
  from vantage6.cli.utils import check_config_name_allowed, prompt_config_name
11
13
 
12
14
 
13
15
  def new(
14
- questionnaire_function: callable,
16
+ config_producing_func: callable,
17
+ config_producing_func_args: tuple,
15
18
  name: str,
16
19
  system_folders: bool,
17
20
  namespace: str,
18
21
  context: str,
19
22
  type_: InstanceType,
20
- ) -> None:
23
+ is_sandbox: bool = False,
24
+ ) -> Path | None:
21
25
  """
22
26
  Create a new configuration.
23
27
 
24
28
  Parameters
25
29
  ----------
26
- questionnaire_function : callable
30
+ config_producing_func : callable
27
31
  Function to generate the configuration
32
+ config_producing_func_args : tuple
33
+ Arguments to pass to the config producing function
28
34
  name : str
29
35
  Name of the configuration
30
36
  system_folders : bool
@@ -35,6 +41,13 @@ def new(
35
41
  Context to use
36
42
  type_ : InstanceType
37
43
  Type of the configuration (node, server, algorithm store, etc)
44
+ is_sandbox : bool
45
+ Whether to create a sandbox configuration or not
46
+
47
+ Returns
48
+ -------
49
+ Path | None
50
+ Path to the configuration file. None if the process is aborted for any reason.
38
51
  """
39
52
  cli_config = CliConfig()
40
53
  context, namespace = cli_config.compare_changes_config(
@@ -50,11 +63,12 @@ def new(
50
63
  # check that this config does not exist
51
64
  ctx_class = select_context_class(type_)
52
65
  try:
53
- if ctx_class.config_exists(name, system_folders):
66
+ if ctx_class.config_exists(name, system_folders, is_sandbox):
54
67
  error(f"Configuration {Fore.RED}{name}{Style.RESET_ALL} already exists!")
55
68
  exit(1)
56
69
  except Exception as e:
57
70
  error(e)
71
+
58
72
  exit(1)
59
73
 
60
74
  command_name = get_main_cli_command_name(type_)
@@ -70,8 +84,13 @@ def new(
70
84
 
71
85
  # create config in ctx location
72
86
  try:
73
- cfg_file = configuration_wizard(
74
- questionnaire_function, type_, name, system_folders
87
+ cfg_file = make_configuration(
88
+ config_producing_func=config_producing_func,
89
+ config_producing_func_args=config_producing_func_args,
90
+ type_=type_,
91
+ instance_name=name,
92
+ system_folders=system_folders,
93
+ is_sandbox=is_sandbox,
75
94
  )
76
95
  except KeyboardInterrupt:
77
96
  error("Configuration creation aborted.")
@@ -83,3 +102,4 @@ def new(
83
102
  f"You can start the {command_name} by running {Fore.GREEN}v6 {command_name} "
84
103
  f"start {flag}{Style.RESET_ALL}"
85
104
  )
105
+ return cfg_file
@@ -19,13 +19,11 @@ from vantage6.common.globals import (
19
19
  DEFAULT_NODE_IMAGE,
20
20
  DEFAULT_SERVER_IMAGE,
21
21
  DEFAULT_UI_IMAGE,
22
+ LOCALHOST,
22
23
  InstanceType,
23
24
  )
24
25
 
25
- from vantage6.cli.common.utils import (
26
- check_running,
27
- select_context_and_namespace,
28
- )
26
+ from vantage6.cli.common.utils import check_running
29
27
  from vantage6.cli.globals import ChartName
30
28
  from vantage6.cli.utils import check_config_name_allowed, validate_input_cmd_args
31
29
 
@@ -35,8 +33,6 @@ def prestart_checks(
35
33
  instance_type: InstanceType,
36
34
  name: str,
37
35
  system_folders: bool,
38
- context: str,
39
- namespace: str,
40
36
  ) -> None:
41
37
  """
42
38
  Run pre-start checks for an instance.
@@ -48,11 +44,6 @@ def prestart_checks(
48
44
  error(f"Instance '{name}' is already running.")
49
45
  exit(1)
50
46
 
51
- context, namespace = select_context_and_namespace(
52
- context=context,
53
- namespace=namespace,
54
- )
55
-
56
47
 
57
48
  def pull_infra_image(
58
49
  client: DockerClient, image: str, instance_type: InstanceType
@@ -142,6 +133,7 @@ def helm_install(
142
133
  values_file: str | PathLike | None = None,
143
134
  context: str | None = None,
144
135
  namespace: str | None = None,
136
+ local_chart_dir: str | None = None,
145
137
  ) -> None:
146
138
  """
147
139
  Manage the `helm install` command.
@@ -158,6 +150,8 @@ def helm_install(
158
150
  The Kubernetes context to use.
159
151
  namespace : str, optional
160
152
  The Kubernetes namespace to use.
153
+ local_chart_dir : str, optional
154
+ The local directory containing the Helm charts.
161
155
  """
162
156
  # Input validation
163
157
  validate_input_cmd_args(release_name, "release name")
@@ -171,17 +165,28 @@ def helm_install(
171
165
  validate_input_cmd_args(context, "context name", allow_none=True)
172
166
  validate_input_cmd_args(namespace, "namespace name", allow_none=True)
173
167
 
168
+ if local_chart_dir and local_chart_dir.rstrip("/").endswith(chart_name.value):
169
+ local_chart_dir = str(Path(local_chart_dir).parent)
170
+
174
171
  # Create the command
175
- command = [
176
- "helm",
177
- "install",
178
- release_name,
179
- chart_name,
180
- "--repo",
181
- DEFAULT_CHART_REPO,
182
- # TODO v5+ remove this flag when we have a stable release
183
- "--devel", # ensure using latest version including pre-releases
184
- ]
172
+ if local_chart_dir:
173
+ command = [
174
+ "helm",
175
+ "install",
176
+ release_name,
177
+ f"{local_chart_dir}/{chart_name.value}",
178
+ ]
179
+ else:
180
+ command = [
181
+ "helm",
182
+ "install",
183
+ release_name,
184
+ chart_name,
185
+ "--repo",
186
+ DEFAULT_CHART_REPO,
187
+ # TODO v5+ remove this flag when we have a stable release
188
+ "--devel",
189
+ ]
185
190
 
186
191
  if values_file:
187
192
  command.extend(["-f", str(values_file)])
@@ -200,7 +205,7 @@ def helm_install(
200
205
  )
201
206
  info(
202
207
  f"Successfully installed release '{release_name}' using chart "
203
- f"'{chart_name}'."
208
+ f"'{chart_name.value}'."
204
209
  )
205
210
  except subprocess.CalledProcessError:
206
211
  error(f"Failed to install release '{release_name}'.")
@@ -217,7 +222,7 @@ def start_port_forward(
217
222
  service_name: str,
218
223
  service_port: int,
219
224
  port: int,
220
- ip: str | None,
225
+ ip: str = LOCALHOST,
221
226
  context: str | None = None,
222
227
  namespace: str | None = None,
223
228
  ) -> None:
@@ -232,8 +237,8 @@ def start_port_forward(
232
237
  The port on the service to forward.
233
238
  port : int
234
239
  The port to listen on.
235
- ip : str | None
236
- The IP address to listen on. If None, defaults to localhost.
240
+ ip : str
241
+ The IP address to listen on. Defaults to localhost.
237
242
  context : str | None
238
243
  The Kubernetes context to use.
239
244
  namespace : str | None
@@ -264,20 +269,22 @@ def start_port_forward(
264
269
  timeout = 300 # seconds
265
270
  while time.time() - start_time < timeout:
266
271
  try:
267
- result = (
268
- subprocess.check_output(
269
- [
270
- "kubectl",
271
- "get",
272
- "endpoints",
273
- service_name,
274
- "-o",
275
- "jsonpath={.subsets[*].addresses[*].ip}",
276
- ]
277
- )
278
- .decode()
279
- .strip()
280
- )
272
+ command = [
273
+ "kubectl",
274
+ "get",
275
+ "endpoints",
276
+ service_name,
277
+ "-o",
278
+ "jsonpath={.subsets[*].addresses[*].ip}",
279
+ ]
280
+
281
+ if context:
282
+ command.extend(["--context", context])
283
+
284
+ if namespace:
285
+ command.extend(["--namespace", namespace])
286
+
287
+ result = subprocess.check_output(command).decode().strip()
281
288
 
282
289
  if result:
283
290
  info(f"Service '{service_name}' is ready.")
@@ -288,13 +295,14 @@ def start_port_forward(
288
295
  time.sleep(2)
289
296
  else:
290
297
  error(
291
- f"Timeout: Service '{service_name}' has no ready endpoints after {timeout} seconds."
298
+ f"Timeout: Service '{service_name}' has no ready endpoints after {timeout} "
299
+ "seconds."
292
300
  )
293
301
  return
294
302
 
295
303
  # Create the port forwarding command
296
304
  if not ip:
297
- ip = "localhost"
305
+ ip = LOCALHOST
298
306
 
299
307
  command = [
300
308
  "kubectl",
@@ -5,7 +5,7 @@ import subprocess
5
5
  from colorama import Fore, Style
6
6
 
7
7
  from vantage6.common import error, info, warning
8
- from vantage6.common.globals import InstanceType
8
+ from vantage6.common.globals import SANDBOX_SUFFIX, InstanceType
9
9
 
10
10
  from vantage6.cli.common.utils import (
11
11
  find_running_service_names,
@@ -26,6 +26,8 @@ def execute_stop(
26
26
  namespace: str,
27
27
  context: str,
28
28
  system_folders: bool,
29
+ is_sandbox: bool = False,
30
+ stop_function_args: dict | None = None,
29
31
  ):
30
32
  """
31
33
  Execute the stop function for a given instance type and infra component.
@@ -41,19 +43,25 @@ def execute_stop(
41
43
  stop_all : bool
42
44
  Whether to stop all services.
43
45
  to_stop : str | None
44
- The name of the service to stop.
46
+ The name of the service to stop. If None, the user will be asked to select a
47
+ service.
45
48
  namespace : str
46
49
  The namespace of the service.
47
50
  context : str
48
51
  The context of the service.
49
52
  system_folders : bool
50
53
  Whether to use system folders.
54
+ is_sandbox : bool
55
+ Whether the configuration is a sandbox configuration, by default False
56
+ stop_function_args : dict | None
57
+ Additional arguments to pass to the stop function
51
58
  """
59
+ if stop_function_args is None:
60
+ stop_function_args = {}
52
61
  context, namespace = select_context_and_namespace(
53
62
  context=context,
54
63
  namespace=namespace,
55
64
  )
56
-
57
65
  running_services = find_running_service_names(
58
66
  instance_type=instance_type,
59
67
  only_system_folders=system_folders,
@@ -73,11 +81,21 @@ def execute_stop(
73
81
  if not to_stop:
74
82
  helm_name = select_running_service(running_services, instance_type)
75
83
  else:
76
- ctx = get_context(instance_type, to_stop, system_folders)
84
+ if to_stop.endswith(SANDBOX_SUFFIX):
85
+ to_stop = to_stop[: -len(SANDBOX_SUFFIX)]
86
+ is_sandbox = True
87
+ elif is_sandbox:
88
+ warning(
89
+ "Sandbox configuration detected, but no sandbox suffix found. "
90
+ "This may lead to issues."
91
+ )
92
+ ctx = get_context(
93
+ instance_type, to_stop, system_folders, is_sandbox=is_sandbox
94
+ )
77
95
  helm_name = ctx.helm_release_name
78
96
 
79
97
  if helm_name in running_services:
80
- stop_function(helm_name, namespace, context)
98
+ stop_function(helm_name, namespace, context, **stop_function_args)
81
99
  info(
82
100
  f"Stopped the {Fore.GREEN}{helm_name}{Style.RESET_ALL} {infra_component.value}."
83
101
  )
@@ -66,6 +66,7 @@ def find_running_service_names(
66
66
  only_user_folders: bool = False,
67
67
  context: str | None = None,
68
68
  namespace: str | None = None,
69
+ sandbox: bool = False,
69
70
  ) -> list[str]:
70
71
  """
71
72
  List running Vantage6 servers.
@@ -82,6 +83,8 @@ def find_running_service_names(
82
83
  The Kubernetes context to use.
83
84
  namespace : str, optional
84
85
  The Kubernetes namespace to use.
86
+ sandbox : bool, optional
87
+ Whether to look for sandbox services or not. By default False.
85
88
 
86
89
  Returns
87
90
  -------
@@ -380,6 +383,8 @@ def get_main_cli_command_name(instance_type: InstanceType) -> str:
380
383
  return CLICommandName.ALGORITHM_STORE.value
381
384
  elif instance_type == InstanceType.NODE:
382
385
  return CLICommandName.NODE.value
386
+ elif instance_type == InstanceType.AUTH:
387
+ return CLICommandName.AUTH.value
383
388
  else:
384
389
  raise ValueError(f"Invalid instance type: {instance_type}")
385
390
 
@@ -412,3 +417,23 @@ def check_running(
412
417
  only_user_folders=not system_folders,
413
418
  )
414
419
  return helm_release_name in running_services
420
+
421
+
422
+ def get_config_name_from_helm_release_name(helm_release_name: str) -> str:
423
+ """
424
+ Get the config name from a helm release name.
425
+
426
+ Parameters
427
+ ----------
428
+ helm_release_name : str
429
+ The name of the Helm release
430
+
431
+ Returns
432
+ -------
433
+ str
434
+ The config name
435
+ """
436
+ # helm release name is structured as:
437
+ # f"{APPNAME}-{name}-{scope}-{instance_type}"
438
+ # we want to get the name from the service name
439
+ return "-".join(helm_release_name.split("-")[1:-2])
vantage6/cli/config.py CHANGED
@@ -13,6 +13,8 @@ from vantage6.cli.globals import (
13
13
  DEFAULT_CLI_CONFIG_FILE,
14
14
  )
15
15
 
16
+ _CONTEXT_INFO_PRINTED = False
17
+
16
18
 
17
19
  class CliConfig:
18
20
  """
@@ -255,6 +257,12 @@ class CliConfig:
255
257
  if last_namespace != active_namespace:
256
258
  self.set_last_namespace(namespace=active_namespace)
257
259
 
258
- info(f"Using context: {Fore.YELLOW}{active_context}{Style.RESET_ALL}")
259
- info(f"Using namespace: {Fore.YELLOW}{active_namespace}{Style.RESET_ALL}")
260
+ # only print the context and namespace once. This is to avoid printing it many
261
+ # times, e.g. in sandbox commands
262
+ global _CONTEXT_INFO_PRINTED
263
+ if not _CONTEXT_INFO_PRINTED:
264
+ info(f"Using context: {Fore.YELLOW}{active_context}{Style.RESET_ALL}")
265
+ info(f"Using namespace: {Fore.YELLOW}{active_namespace}{Style.RESET_ALL}")
266
+ _CONTEXT_INFO_PRINTED = True
267
+
260
268
  return active_context, active_namespace
@@ -12,6 +12,7 @@ from vantage6.common.globals import (
12
12
 
13
13
  from vantage6.cli.configuration_manager import (
14
14
  AlgorithmStoreConfigurationManager,
15
+ AuthConfigurationManager,
15
16
  NodeConfigurationManager,
16
17
  ServerConfigurationManager,
17
18
  )
@@ -125,25 +126,31 @@ def _add_production_server_config(config: dict) -> dict:
125
126
  return config
126
127
 
127
128
 
128
- def configuration_wizard(
129
- questionnaire_function: callable,
129
+ def make_configuration(
130
+ config_producing_func: callable,
131
+ config_producing_func_args: tuple,
130
132
  type_: InstanceType,
131
133
  instance_name: str,
132
134
  system_folders: bool,
135
+ is_sandbox: bool = False,
133
136
  ) -> Path:
134
137
  """
135
138
  Create a configuration file for a node or server instance.
136
139
 
137
140
  Parameters
138
141
  ----------
139
- questionnaire_function : callable
142
+ config_producing_func : callable
140
143
  Function to generate the configuration
144
+ config_producing_func_args : tuple
145
+ Arguments to pass to the config producing function
141
146
  type_ : InstanceType
142
147
  Type of the instance to create a configuration for
143
148
  instance_name : str
144
149
  Name of the instance
145
150
  system_folders : bool
146
151
  Whether to use the system folders or not
152
+ is_sandbox : bool
153
+ Whether to create a sandbox configuration or not
147
154
 
148
155
  Returns
149
156
  -------
@@ -153,11 +160,10 @@ def configuration_wizard(
153
160
  # for defaults and where to save the config
154
161
  dirs = AppContext.instance_folders(type_, instance_name, system_folders)
155
162
 
156
- # invoke questionaire to create configuration file
157
- if type_ == InstanceType.NODE:
158
- config = questionnaire_function(dirs, instance_name)
159
- else:
160
- config = questionnaire_function(instance_name)
163
+ # invoke function to create configuration file. Usually this is a questionaire
164
+ # but it can also be a function that immediately returns a dict with the
165
+ # configuration.
166
+ config = config_producing_func(*config_producing_func_args)
161
167
 
162
168
  # in the case of an environment we need to add it to the current
163
169
  # configuration. In the case of application we can simply overwrite this
@@ -167,21 +173,27 @@ def configuration_wizard(
167
173
  conf_manager = NodeConfigurationManager
168
174
  elif type_ == InstanceType.SERVER:
169
175
  conf_manager = ServerConfigurationManager
170
- else:
176
+ elif type_ == InstanceType.ALGORITHM_STORE:
171
177
  conf_manager = AlgorithmStoreConfigurationManager
178
+ elif type_ == InstanceType.AUTH:
179
+ conf_manager = AuthConfigurationManager
180
+ else:
181
+ raise ValueError(f"Invalid instance type: {type_}")
172
182
 
173
183
  if Path(config_file).exists():
174
- config_manager = conf_manager.from_file(config_file)
184
+ config_manager = conf_manager.from_file(config_file, is_sandbox=is_sandbox)
175
185
  else:
176
- config_manager = conf_manager(instance_name)
186
+ config_manager = conf_manager(instance_name, is_sandbox=is_sandbox)
177
187
 
178
188
  config_manager.put(config)
179
- config_manager.save(config_file)
189
+ config_file = config_manager.save(config_file)
180
190
 
181
191
  return config_file
182
192
 
183
193
 
184
- def select_configuration_questionaire(type_: InstanceType, system_folders: bool) -> str:
194
+ def select_configuration_questionnaire(
195
+ type_: InstanceType, system_folders: bool, is_sandbox: bool = False
196
+ ) -> str:
185
197
  """
186
198
  Ask which configuration the user wants to use. It shows only configurations
187
199
  that are in the default folder.
@@ -192,14 +204,15 @@ def select_configuration_questionaire(type_: InstanceType, system_folders: bool)
192
204
  Type of the instance to create a configuration for
193
205
  system_folders : bool
194
206
  Whether to use the system folders or not
195
-
207
+ is_sandbox : bool
208
+ Whether to show only the sandbox configurations or not
196
209
  Returns
197
210
  -------
198
211
  str
199
212
  Name of the configuration
200
213
  """
201
214
  context = select_context_class(type_)
202
- configs, _ = context.available_configurations(system_folders)
215
+ configs, _ = context.available_configurations(system_folders, is_sandbox)
203
216
 
204
217
  # each collection (file) can contain multiple configs. (e.g. test,
205
218
  # dev)