vantage6 5.0.0a35__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 (47) 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/auth/attach.py +60 -0
  7. vantage6/cli/auth/files.py +16 -0
  8. vantage6/cli/auth/list.py +13 -0
  9. vantage6/cli/auth/new.py +80 -0
  10. vantage6/cli/auth/remove.py +31 -0
  11. vantage6/cli/auth/start.py +80 -0
  12. vantage6/cli/auth/stop.py +64 -0
  13. vantage6/cli/cli.py +37 -5
  14. vantage6/cli/common/start.py +1 -1
  15. vantage6/cli/common/utils.py +2 -0
  16. vantage6/cli/configuration_manager.py +31 -0
  17. vantage6/cli/configuration_wizard.py +6 -1
  18. vantage6/cli/context/__init__.py +3 -0
  19. vantage6/cli/context/auth.py +107 -0
  20. vantage6/cli/context/base_server.py +0 -4
  21. vantage6/cli/dev/clean.py +28 -0
  22. vantage6/cli/dev/common.py +34 -0
  23. vantage6/cli/dev/rebuild.py +39 -0
  24. vantage6/cli/dev/start.py +36 -0
  25. vantage6/cli/dev/stop.py +23 -0
  26. vantage6/cli/globals.py +4 -1
  27. vantage6/cli/node/list.py +5 -4
  28. vantage6/cli/node/version.py +5 -4
  29. vantage6/cli/prometheus/monitoring_manager.py +5 -3
  30. vantage6/cli/rabbitmq/queue_manager.py +13 -11
  31. vantage6/cli/server/attach.py +1 -0
  32. vantage6/cli/server/common/__init__.py +1 -27
  33. vantage6/cli/server/import_.py +1 -1
  34. vantage6/cli/server/new.py +17 -4
  35. vantage6/cli/template/auth_config.j2 +230 -0
  36. vantage6/cli/template/node_config.j2 +8 -8
  37. vantage6/cli/template/node_config_nonk8s.j2 +33 -0
  38. vantage6/cli/test/common/diagnostic_runner.py +5 -3
  39. vantage6/cli/use/namespace.py +2 -1
  40. {vantage6-5.0.0a35.dist-info → vantage6-5.0.0a36.dist-info}/METADATA +3 -3
  41. {vantage6-5.0.0a35.dist-info → vantage6-5.0.0a36.dist-info}/RECORD +43 -32
  42. vantage6/cli/dev/create.py +0 -693
  43. vantage6/cli/dev/data/km_dataset.csv +0 -2401
  44. vantage6/cli/dev/remove.py +0 -112
  45. vantage6/cli/server/shell.py +0 -54
  46. {vantage6-5.0.0a35.dist-info → vantage6-5.0.0a36.dist-info}/WHEEL +0 -0
  47. {vantage6-5.0.0a35.dist-info → vantage6-5.0.0a36.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,107 @@
1
+ from __future__ import annotations
2
+
3
+ from vantage6.common.context import AppContext
4
+ from vantage6.common.globals import InstanceType
5
+
6
+ from vantage6.cli import __version__
7
+ from vantage6.cli.configuration_manager import AuthConfigurationManager
8
+ from vantage6.cli.globals import DEFAULT_SERVER_SYSTEM_FOLDERS as S_FOL
9
+
10
+
11
+ class AuthContext(AppContext):
12
+ """
13
+ Context class for the keycloak authentication server.
14
+
15
+ Parameters
16
+ ----------
17
+ instance_name : str
18
+ Name of the configuration instance, corresponds to the filename
19
+ of the configuration file.
20
+ system_folders : bool, optional
21
+ System wide or user configuration, by default S_FOL
22
+ """
23
+
24
+ # The auth configuration manager is aware of the structure of the auth
25
+ # configuration file and makes sure only valid configuration can be loaded.
26
+ INST_CONFIG_MANAGER = AuthConfigurationManager
27
+
28
+ def __init__(
29
+ self,
30
+ instance_name: str,
31
+ system_folders: bool = S_FOL,
32
+ ):
33
+ super().__init__(
34
+ InstanceType.AUTH,
35
+ instance_name,
36
+ system_folders=system_folders,
37
+ )
38
+ self.log.info("vantage6 version '%s'", __version__)
39
+
40
+ @classmethod
41
+ def from_external_config_file(
42
+ cls, path: str, system_folders: bool = S_FOL
43
+ ) -> AuthContext:
44
+ """
45
+ Create a server context from an external configuration file. External
46
+ means that the configuration file is not located in the default folders
47
+ but its location is specified by the user.
48
+
49
+ Parameters
50
+ ----------
51
+ path : str
52
+ Path of the configuration file
53
+ system_folders : bool, optional
54
+ System wide or user configuration, by default S_FOL
55
+
56
+ Returns
57
+ -------
58
+ ServerContext
59
+ Server context object
60
+ """
61
+ return super().from_external_config_file(
62
+ path,
63
+ InstanceType.AUTH,
64
+ system_folders,
65
+ )
66
+
67
+ @classmethod
68
+ def config_exists(cls, instance_name: str, system_folders: bool = S_FOL) -> bool:
69
+ """
70
+ Check if a configuration file exists.
71
+
72
+ Parameters
73
+ ----------
74
+ instance_name : str
75
+ Name of the configuration instance, corresponds to the filename
76
+ of the configuration file.
77
+ system_folders : bool, optional
78
+ System wide or user configuration, by default S_FOL
79
+
80
+ Returns
81
+ -------
82
+ bool
83
+ Whether the configuration file exists or not
84
+ """
85
+ return super().config_exists(
86
+ InstanceType.AUTH, instance_name, system_folders=system_folders
87
+ )
88
+
89
+ @classmethod
90
+ def available_configurations(
91
+ cls, system_folders: bool = S_FOL
92
+ ) -> tuple[list, list]:
93
+ """
94
+ Find all available auth configurations in the default folders.
95
+
96
+ Parameters
97
+ ----------
98
+ system_folders : bool, optional
99
+ System wide or user configuration, by default S_FOL
100
+
101
+ Returns
102
+ -------
103
+ tuple[list, list]
104
+ The first list contains validated configuration files, the second
105
+ list contains invalid configuration files.
106
+ """
107
+ return super().available_configurations(InstanceType.AUTH, system_folders)
@@ -1,9 +1,5 @@
1
1
  from __future__ import annotations
2
2
 
3
- import os.path
4
-
5
- from sqlalchemy.engine.url import make_url
6
-
7
3
  from vantage6.common.context import AppContext
8
4
 
9
5
  from vantage6.cli.globals import (
@@ -0,0 +1,28 @@
1
+ import subprocess
2
+ import sys
3
+
4
+ import click
5
+
6
+ from vantage6.common import error, info
7
+
8
+ from vantage6.cli.dev.common import check_devspace_installed
9
+
10
+
11
+ @click.command()
12
+ def cli_clean_dev_env():
13
+ """
14
+ Stops and cleans up the development environment.
15
+
16
+ Removes the kubernetes resources and local data (e.g. tasks data, database data).
17
+ This is useful when you want to start from scratch.
18
+ """
19
+ check_devspace_installed()
20
+
21
+ try:
22
+ info("🧹 Cleaning development environment with devspace...")
23
+ cmd = ["devspace", "run", "purge"]
24
+ subprocess.run(cmd, check=True, capture_output=False)
25
+ info("✅ Development environment cleaned successfully!")
26
+ except subprocess.CalledProcessError as e:
27
+ error(f"❌ Error cleaning development environment: {e}")
28
+ sys.exit(e.returncode)
@@ -0,0 +1,34 @@
1
+ import shutil
2
+ import subprocess
3
+ import sys
4
+
5
+ from vantage6.common import error
6
+
7
+
8
+ def check_devspace_installed() -> None:
9
+ """Check if devspace is installed. Exits if not."""
10
+ # Check if devspace command exists
11
+ if shutil.which("devspace") is None:
12
+ _message_devspace_not_installed()
13
+
14
+ try:
15
+ # Try to run devspace --version to verify it's working
16
+ result = subprocess.run(
17
+ ["devspace", "--version"], capture_output=True, text=True, timeout=10
18
+ )
19
+ if result.returncode != 0:
20
+ _message_devspace_not_installed()
21
+ except (
22
+ subprocess.TimeoutExpired,
23
+ subprocess.CalledProcessError,
24
+ FileNotFoundError,
25
+ ):
26
+ _message_devspace_not_installed()
27
+
28
+
29
+ def _message_devspace_not_installed() -> None:
30
+ error(
31
+ "❌ DevSpace command not found. Please ensure devspace is installed and in "
32
+ "your PATH."
33
+ )
34
+ sys.exit(1)
@@ -0,0 +1,39 @@
1
+ import subprocess
2
+ import sys
3
+
4
+ import click
5
+
6
+ from vantage6.common import error, info
7
+
8
+ from vantage6.cli.dev.common import check_devspace_installed
9
+
10
+
11
+ @click.command()
12
+ @click.option("--only-server", is_flag=True, help="Rebuild the server image.")
13
+ @click.option("--only-node", is_flag=True, help="Rebuild the node image.")
14
+ @click.option("--only-store", is_flag=True, help="Rebuild the store image.")
15
+ @click.option("--only-ui", is_flag=True, help="Rebuild the ui image.")
16
+ def cli_rebuild_dev_env(
17
+ only_server: bool, only_node: bool, only_store: bool, only_ui: bool
18
+ ):
19
+ """Rebuild Docker images for your development environment."""
20
+ check_devspace_installed()
21
+
22
+ try:
23
+ info("🔄 Rebuilding development environment with devspace...")
24
+ cmd = ["devspace", "run", "rebuild"]
25
+
26
+ if only_server:
27
+ cmd.append("--server")
28
+ if only_node:
29
+ cmd.append("--node")
30
+ if only_store:
31
+ cmd.append("--store")
32
+ if only_ui:
33
+ cmd.append("--ui")
34
+
35
+ subprocess.run(cmd, check=True, capture_output=False)
36
+ info("✅ Development environment rebuilt successfully!")
37
+ except subprocess.CalledProcessError as e:
38
+ error(f"❌ Error rebuilding development environment: {e}")
39
+ sys.exit(e.returncode)
@@ -0,0 +1,36 @@
1
+ import subprocess
2
+ import sys
3
+
4
+ import click
5
+
6
+ from vantage6.common import error, info
7
+
8
+ from vantage6.cli.dev.common import check_devspace_installed
9
+
10
+
11
+ @click.command()
12
+ def cli_start_dev_env():
13
+ """Start the development environment using devspace."""
14
+ check_devspace_installed()
15
+
16
+ try:
17
+ info("🚀 Starting development environment with devspace...")
18
+
19
+ # Build the devspace command
20
+ cmd = ["devspace", "run", "start-dev"]
21
+
22
+ # Run the devspace command
23
+ result = subprocess.run(cmd, check=True, capture_output=False)
24
+
25
+ if result.returncode == 0:
26
+ info("✅ Development environment started successfully!")
27
+ else:
28
+ error("❌ Failed to start development environment.")
29
+ sys.exit(result.returncode)
30
+
31
+ except subprocess.CalledProcessError as e:
32
+ error(f"❌ Error running devspace: {e}")
33
+ sys.exit(e.returncode)
34
+ except Exception as e:
35
+ error(f"❌ Unexpected error: {e}")
36
+ sys.exit(1)
@@ -0,0 +1,23 @@
1
+ import subprocess
2
+ import sys
3
+
4
+ import click
5
+
6
+ from vantage6.common import error, info
7
+
8
+ from vantage6.cli.dev.common import check_devspace_installed
9
+
10
+
11
+ @click.command()
12
+ def cli_stop_dev_env():
13
+ """Stop the development environment."""
14
+ check_devspace_installed()
15
+
16
+ try:
17
+ info("🛑 Stopping development environment with devspace...")
18
+ cmd = ["devspace", "run", "stop-dev"]
19
+ subprocess.run(cmd, check=True, capture_output=False)
20
+ info("✅ Development environment stopped successfully!")
21
+ except subprocess.CalledProcessError as e:
22
+ error(f"❌ Error stopping development environment: {e}")
23
+ sys.exit(e.returncode)
vantage6/cli/globals.py CHANGED
@@ -56,11 +56,12 @@ DEFAULT_PROMETHEUS_IMAGE = "prom/prometheus"
56
56
  PROMETHEUS_CONFIG = "prometheus.yml"
57
57
  PROMETHEUS_DIR = "prometheus"
58
58
 
59
- # template folder
59
+ # template configuration files
60
60
  TEMPLATE_FOLDER = PACKAGE_FOLDER / APPNAME / "cli" / "template"
61
61
  SERVER_TEMPLATE_FILE = "server_config.j2"
62
62
  NODE_TEMPLATE_FILE = "node_config.j2"
63
63
  ALGO_STORE_TEMPLATE_FILE = "algo_store_config.j2"
64
+ AUTH_TEMPLATE_FILE = "auth_config.j2"
64
65
 
65
66
 
66
67
  # datasets included in the nodes of the dev network
@@ -97,6 +98,7 @@ class CLICommandName(StrEnumBase):
97
98
  TEST = "test"
98
99
  DEV = "dev"
99
100
  USE = "use"
101
+ AUTH = "auth"
100
102
 
101
103
 
102
104
  class InfraComponentName(StrEnumBase):
@@ -105,3 +107,4 @@ class InfraComponentName(StrEnumBase):
105
107
  SERVER = "server"
106
108
  ALGORITHM_STORE = "store"
107
109
  NODE = "node"
110
+ AUTH = "auth"
vantage6/cli/node/list.py CHANGED
@@ -3,8 +3,9 @@ import docker
3
3
  from colorama import Fore, Style
4
4
 
5
5
  from vantage6.common import warning
6
- from vantage6.common.globals import APPNAME
7
6
  from vantage6.common.docker.addons import check_docker_running
7
+ from vantage6.common.globals import APPNAME
8
+
8
9
  from vantage6.cli.context.node import NodeContext
9
10
  from vantage6.cli.node.common import find_running_node_names
10
11
 
@@ -39,7 +40,7 @@ def cli_node_list() -> None:
39
40
  if f"{APPNAME}-{config.name}-system" in running_node_names
40
41
  else stopped
41
42
  )
42
- click.echo(f"{config.name:25}" f"{status:25}System ")
43
+ click.echo(f"{config.name:25}{status:25}System ")
43
44
 
44
45
  # user folders
45
46
  configs, f2 = NodeContext.available_configurations(system_folders=False)
@@ -49,8 +50,8 @@ def cli_node_list() -> None:
49
50
  if f"{APPNAME}-{config.name}-user" in running_node_names
50
51
  else stopped
51
52
  )
52
- click.echo(f"{config.name:25}" f"{status:25}User ")
53
+ click.echo(f"{config.name:25}{status:25}User ")
53
54
 
54
55
  click.echo("-" * 53)
55
56
  if len(f1) + len(f2):
56
- warning(f"{Fore.RED}Failed imports: {len(f1)+len(f2)}{Style.RESET_ALL}")
57
+ warning(f"{Fore.RED}Failed imports: {len(f1) + len(f2)}{Style.RESET_ALL}")
@@ -1,12 +1,13 @@
1
1
  import click
2
- import questionary as q
3
2
  import docker
3
+ import questionary as q
4
4
 
5
5
  from vantage6.common import error
6
- from vantage6.common.globals import APPNAME
7
6
  from vantage6.common.docker.addons import check_docker_running
8
- from vantage6.cli.globals import DEFAULT_NODE_SYSTEM_FOLDERS as N_FOL
7
+ from vantage6.common.globals import APPNAME
8
+
9
9
  from vantage6.cli import __version__
10
+ from vantage6.cli.globals import DEFAULT_NODE_SYSTEM_FOLDERS as N_FOL
10
11
  from vantage6.cli.node.common import find_running_node_names
11
12
 
12
13
 
@@ -16,7 +17,7 @@ from vantage6.cli.node.common import find_running_node_names
16
17
  "--system",
17
18
  "system_folders",
18
19
  flag_value=True,
19
- help="Search for configuration in system folders rather than " "user folders",
20
+ help="Search for configuration in system folders rather than user folders",
20
21
  )
21
22
  @click.option(
22
23
  "--user",
@@ -1,10 +1,12 @@
1
- import yaml
2
- import docker
3
1
  from pathlib import Path
4
2
 
5
- from vantage6.common import info, error
3
+ import docker
4
+ import yaml
5
+
6
+ from vantage6.common import error, info
6
7
  from vantage6.common.docker.network_manager import NetworkManager
7
8
  from vantage6.common.globals import DEFAULT_PROMETHEUS_EXPORTER_PORT
9
+
8
10
  from vantage6.cli.context.server import ServerContext
9
11
  from vantage6.cli.globals import (
10
12
  DEFAULT_PROMETHEUS_IMAGE,
@@ -1,21 +1,21 @@
1
- import docker
1
+ import base64
2
+ import hashlib
2
3
  import json
3
4
  import os
4
5
  import shutil
5
- import base64
6
- import hashlib
7
6
  import time
8
-
9
7
  from pathlib import Path
10
8
 
11
- from vantage6.common.globals import APPNAME
12
- from vantage6.common import debug, info, error
9
+ import docker
10
+
11
+ from vantage6.common import debug, error, info, split_rabbitmq_uri
13
12
  from vantage6.common.docker.addons import get_container
14
13
  from vantage6.common.docker.network_manager import NetworkManager
15
- from vantage6.common import split_rabbitmq_uri
14
+ from vantage6.common.globals import APPNAME
15
+
16
16
  from vantage6.cli.context.server import ServerContext
17
- from vantage6.cli.rabbitmq.definitions import RABBITMQ_DEFINITIONS
18
17
  from vantage6.cli.globals import RABBIT_TIMEOUT
18
+ from vantage6.cli.rabbitmq.definitions import RABBITMQ_DEFINITIONS
19
19
 
20
20
  DEFAULT_RABBIT_IMAGE = "harbor2.vantage6.ai/infrastructure/rabbitmq"
21
21
  RABBIT_CONFIG = "rabbitmq.config"
@@ -75,7 +75,7 @@ class RabbitMQManager:
75
75
  # check if a RabbitMQ container is already running
76
76
  self.rabbit_container = get_container(docker_client=self.docker, name=self.host)
77
77
  if self.rabbit_container:
78
- info("RabbitMQ is already running! Linking the server to that " "queue")
78
+ info("RabbitMQ is already running! Linking the server to that queue")
79
79
  if not self.network_mgr.contains(self.rabbit_container):
80
80
  self.network_mgr.connect(self.rabbit_container)
81
81
  return
@@ -161,8 +161,10 @@ class RabbitMQManager:
161
161
  "bind": "/etc/rabbitmq/definitions.json",
162
162
  "mode": "ro",
163
163
  },
164
- self.ctx.data_dir
165
- / RABBIT_CONFIG: {"bind": "/etc/rabbitmq/rabbitmq.config", "mode": "ro"},
164
+ self.ctx.data_dir / RABBIT_CONFIG: {
165
+ "bind": "/etc/rabbitmq/rabbitmq.config",
166
+ "mode": "ro",
167
+ },
166
168
  rabbit_data_dir: {"bind": "/var/lib/rabbitmq", "mode": "rw"},
167
169
  }
168
170
 
@@ -1,6 +1,7 @@
1
1
  import click
2
2
 
3
3
  from vantage6.common import info
4
+
4
5
  from vantage6.cli.common.utils import attach_logs
5
6
 
6
7
 
@@ -1,13 +1,8 @@
1
- from docker.client import DockerClient
2
1
  from colorama import Fore, Style
3
2
 
4
- from vantage6.common import error, info
5
- from vantage6.common.globals import APPNAME
6
- from vantage6.common.docker.addons import remove_container, get_container
3
+ from vantage6.common import error
7
4
  from vantage6.common.context import AppContext
8
5
 
9
- from vantage6.cli.context.server import ServerContext
10
-
11
6
 
12
7
  def get_server_context(
13
8
  name: str, system_folders: bool, ctx_class: AppContext
@@ -45,24 +40,3 @@ def get_server_context(
45
40
  ctx = ctx_class(name, system_folders=system_folders)
46
41
 
47
42
  return ctx
48
-
49
-
50
- def stop_ui(client: DockerClient, ctx: ServerContext) -> None:
51
- """
52
- Check if the UI container is running, and if so, stop and remove it.
53
-
54
- Parameters
55
- ----------
56
- client : DockerClient
57
- Docker client
58
- ctx : ServerContext
59
- Server context object
60
- """
61
- ui_container_name = f"{APPNAME}-{ctx.name}-{ctx.scope}-ui"
62
- ui_container = get_container(client, name=ui_container_name)
63
- if ui_container:
64
- remove_container(ui_container, kill=True)
65
- info(
66
- f"Stopped the {Fore.GREEN}{ui_container_name}"
67
- f"{Style.RESET_ALL} User Interface container."
68
- )
@@ -102,7 +102,7 @@ def cli_server_import(
102
102
  # We're dealing with a relative path here -> make it absolute
103
103
  db_path = ctx.data_dir / url.database
104
104
 
105
- basename = os.path.basename(db_path)
105
+ # basename = os.path.basename(db_path)
106
106
  dirname = os.path.dirname(db_path)
107
107
  os.makedirs(dirname, exist_ok=True)
108
108
 
@@ -45,6 +45,17 @@ def cli_server_new(
45
45
  """
46
46
  Create a new server configuration.
47
47
  """
48
+ # info(
49
+ # "Vantage6 uses keycloak for authentication. Please configure a keycloak "
50
+ # "server here unless you have one running externally."
51
+ # )
52
+ # configure_keycloak = q.confirm(
53
+ # "Do you want to configure a keycloak server?",
54
+ # default=True,
55
+ # ).unsafe_ask()
56
+ # if configure_keycloak:
57
+ # print("awefawef")
58
+
48
59
  new(
49
60
  questionnaire_function=server_configuration_questionaire,
50
61
  name=name,
@@ -69,10 +80,6 @@ def server_configuration_questionaire(instance_name: str) -> dict[str, Any]:
69
80
  dict[str, Any]
70
81
  dictionary with Helm values for the server configuration
71
82
  """
72
- # Get active kube namespace
73
- cli_config = CliConfig()
74
- kube_namespace = cli_config.get_last_namespace()
75
-
76
83
  # Initialize config with basic structure
77
84
  config = {"server": {}, "database": {}, "ui": {}, "rabbitmq": {}}
78
85
 
@@ -102,7 +109,13 @@ def server_configuration_questionaire(instance_name: str) -> dict[str, Any]:
102
109
  default="harbor2.vantage6.ai/infrastructure/ui:latest",
103
110
  ).unsafe_ask()
104
111
 
112
+ # TODO v5+ we need to add a question to ask which algorithm stores are allowed, to
113
+ # set the CSP headers in the UI. This is not done now because it becomes easier when
114
+ # store and keycloak service can also be setup in the `v6 server new` command.
115
+
105
116
  # === Keycloak settings ===
117
+ cli_config = CliConfig()
118
+ kube_namespace = cli_config.get_last_namespace()
106
119
  keycloak_url = f"http://vantage6-auth-keycloak.{kube_namespace}.svc.cluster.local"
107
120
  config["server"]["keycloakUrl"] = keycloak_url
108
121