vantage6 5.0.0a21__py3-none-any.whl → 5.0.0a26__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 (39) hide show
  1. tests_cli/test_client_script.py +23 -0
  2. vantage6/cli/__build__ +1 -1
  3. vantage6/cli/algorithm/generate_algorithm_json.py +529 -0
  4. vantage6/cli/cli.py +25 -0
  5. vantage6/cli/common/start.py +220 -9
  6. vantage6/cli/common/stop.py +90 -0
  7. vantage6/cli/common/utils.py +8 -7
  8. vantage6/cli/config.py +260 -0
  9. vantage6/cli/configuration_manager.py +3 -11
  10. vantage6/cli/configuration_wizard.py +60 -101
  11. vantage6/cli/context/node.py +34 -45
  12. vantage6/cli/context/server.py +26 -0
  13. vantage6/cli/dev/create.py +78 -17
  14. vantage6/cli/dev/data/km_dataset.csv +2401 -0
  15. vantage6/cli/dev/remove.py +99 -98
  16. vantage6/cli/globals.py +20 -0
  17. vantage6/cli/node/new.py +4 -3
  18. vantage6/cli/node/remove.py +4 -2
  19. vantage6/cli/node/start.py +17 -20
  20. vantage6/cli/prometheus/monitoring_manager.py +146 -0
  21. vantage6/cli/prometheus/prometheus.yml +5 -0
  22. vantage6/cli/server/new.py +25 -6
  23. vantage6/cli/server/start.py +42 -212
  24. vantage6/cli/server/stop.py +35 -105
  25. vantage6/cli/template/algo_store_config.j2 +0 -1
  26. vantage6/cli/template/node_config.j2 +1 -1
  27. vantage6/cli/template/server_import_config.j2 +0 -2
  28. vantage6/cli/test/algo_test_scripts/algo_test_arguments.py +29 -0
  29. vantage6/cli/test/algo_test_scripts/algo_test_script.py +91 -0
  30. vantage6/cli/test/client_script.py +151 -0
  31. vantage6/cli/test/common/diagnostic_runner.py +2 -2
  32. vantage6/cli/use/context.py +46 -0
  33. vantage6/cli/use/namespace.py +55 -0
  34. vantage6/cli/utils.py +70 -4
  35. {vantage6-5.0.0a21.dist-info → vantage6-5.0.0a26.dist-info}/METADATA +5 -8
  36. {vantage6-5.0.0a21.dist-info → vantage6-5.0.0a26.dist-info}/RECORD +39 -27
  37. {vantage6-5.0.0a21.dist-info → vantage6-5.0.0a26.dist-info}/WHEEL +0 -0
  38. {vantage6-5.0.0a21.dist-info → vantage6-5.0.0a26.dist-info}/entry_points.txt +0 -0
  39. {vantage6-5.0.0a21.dist-info → vantage6-5.0.0a26.dist-info}/top_level.txt +0 -0
@@ -1,65 +1,27 @@
1
1
  import click
2
- import docker
3
- from docker.client import DockerClient
4
2
 
5
- from vantage6.common import info, warning, error
6
- from vantage6.common.docker.network_manager import NetworkManager
7
- from vantage6.common.globals import (
8
- APPNAME,
9
- DEFAULT_SERVER_IMAGE,
10
- DEFAULT_UI_IMAGE,
11
- InstanceType,
12
- )
3
+ from vantage6.common import info
13
4
 
14
- from vantage6.common.globals import Ports
15
- from vantage6.cli.context.server import ServerContext
16
- from vantage6.cli.rabbitmq.queue_manager import RabbitMQManager
17
- from vantage6.cli.server.common import stop_ui
18
5
  from vantage6.cli.common.decorator import click_insert_context
19
6
  from vantage6.cli.common.start import (
20
- attach_logs,
21
- check_for_start,
22
- get_image,
23
- mount_database,
24
- mount_source,
25
- pull_infra_image,
7
+ helm_install,
8
+ start_port_forward,
26
9
  )
10
+ from vantage6.cli.common.utils import attach_logs
11
+ from vantage6.cli.config import CliConfig
12
+ from vantage6.cli.context.server import ServerContext
27
13
 
28
14
 
29
15
  @click.command()
16
+ @click.option("--context", default=None, help="Kubernetes context to use")
17
+ @click.option("--namespace", default=None, help="Kubernetes namespace to use")
30
18
  @click.option("--ip", default=None, help="IP address to listen on")
31
- @click.option("-p", "--port", default=None, type=int, help="Port to listen on")
32
- @click.option("-i", "--image", default=None, help="Server Docker image to use")
33
19
  @click.option(
34
- "--with-ui",
35
- "start_ui",
36
- flag_value=True,
37
- default=False,
38
- help="Start the graphical User Interface as well",
20
+ "-p", "--port", default=None, type=int, help="Port to listen on for the server"
39
21
  )
40
22
  @click.option(
41
23
  "--ui-port", default=None, type=int, help="Port to listen on for the User Interface"
42
24
  )
43
- @click.option(
44
- "--with-rabbitmq",
45
- "start_rabbitmq",
46
- flag_value=True,
47
- default=False,
48
- help="Start RabbitMQ message broker as local "
49
- "container - use in development only",
50
- )
51
- @click.option("--rabbitmq-image", default=None, help="RabbitMQ docker image to use")
52
- @click.option(
53
- "--keep/--auto-remove",
54
- default=False,
55
- help="Keep image after server has stopped. Useful for debugging",
56
- )
57
- @click.option(
58
- "--mount-src",
59
- default="",
60
- help="Override vantage6 source code in container with the source"
61
- " code in this path",
62
- )
63
25
  @click.option(
64
26
  "--attach/--detach",
65
27
  default=False,
@@ -68,189 +30,57 @@ from vantage6.cli.common.start import (
68
30
  @click_insert_context(type_="server")
69
31
  def cli_server_start(
70
32
  ctx: ServerContext,
33
+ context: str,
34
+ namespace: str,
71
35
  ip: str,
72
36
  port: int,
73
- image: str,
74
- start_ui: bool,
75
37
  ui_port: int,
76
- start_rabbitmq: bool,
77
- rabbitmq_image: str,
78
- keep: bool,
79
- mount_src: str,
80
38
  attach: bool,
81
39
  ) -> None:
82
40
  """
83
41
  Start the server.
84
42
  """
85
43
  info("Starting server...")
86
- docker_client = check_for_start(ctx, InstanceType.SERVER.value)
44
+ cli_config = CliConfig()
87
45
 
88
- image = get_image(image, ctx, "server", DEFAULT_SERVER_IMAGE)
46
+ context, namespace = cli_config.compare_changes_config(
47
+ context=context,
48
+ namespace=namespace,
49
+ )
89
50
 
90
51
  # check that log directory exists - or create it
91
52
  ctx.log_dir.mkdir(parents=True, exist_ok=True)
92
53
 
93
- info("Pulling server image...")
94
- pull_infra_image(docker_client, image, InstanceType.SERVER)
95
-
96
- info("Creating mounts")
97
- config_file = "/mnt/config.yaml"
98
- mounts = [
99
- docker.types.Mount(config_file, str(ctx.config_file), type="bind"),
100
- docker.types.Mount("/mnt/log/", str(ctx.log_dir), type="bind"),
101
- ]
102
-
103
- src_mount = mount_source(mount_src)
104
- if src_mount:
105
- mounts.append(src_mount)
106
-
107
- mount, environment_vars = mount_database(ctx, InstanceType.SERVER)
108
- if mount:
109
- mounts.append(mount)
110
-
111
- # Create a docker network for the server and other services like RabbitMQ
112
- # to reside in
113
- server_network_mgr = NetworkManager(
114
- network_name=f"{APPNAME}-{ctx.name}-{ctx.scope}-network"
54
+ release_name = f"{ctx.name}-{ctx.instance_type}"
55
+ helm_install(
56
+ release_name=release_name,
57
+ chart_name="server",
58
+ values_file=ctx.config_file,
59
+ context=context,
60
+ namespace=namespace,
115
61
  )
116
- server_network_mgr.create_network(is_internal=False)
117
-
118
- if (
119
- start_rabbitmq
120
- or ctx.config.get("rabbitmq")
121
- and ctx.config["rabbitmq"].get("start_with_server", False)
122
- ):
123
- # Note that ctx.data_dir has been created at this point, which is
124
- # required for putting some RabbitMQ configuration files inside
125
- info("Starting RabbitMQ container")
126
- _start_rabbitmq(ctx, rabbitmq_image, server_network_mgr)
127
- elif ctx.config.get("rabbitmq"):
128
- info(
129
- "RabbitMQ is provided in the config file as external service. "
130
- "Assuming this service is up and running."
131
- )
132
- else:
133
- warning(
134
- "Message queue is not set up! This means that the vantage6 server "
135
- "cannot be scaled horizontally!"
136
- )
137
-
138
- # start the UI if requested
139
- if start_ui or ctx.config.get("ui") and ctx.config["ui"].get("enabled"):
140
- _start_ui(docker_client, ctx, ui_port)
141
62
 
142
- # The `ip` and `port` refer here to the ip and port within the container.
143
- # So we do not really care that is it listening on all interfaces.
144
- internal_port = 5000
145
- cmd = (
146
- f"uwsgi --http :{internal_port} --gevent 1000 --http-websockets "
147
- "--master --callable app --disable-logging "
148
- "--wsgi-file /vantage6/vantage6-server/vantage6/server/wsgi.py "
149
- f"--pyargv {config_file}"
63
+ # port forward for server
64
+ info("Port forwarding for server")
65
+ start_port_forward(
66
+ service_name=f"{release_name}-vantage6-server-service",
67
+ service_port=ctx.config["server"].get("port", 7601),
68
+ port=port or ctx.config["server"].get("port", 7601),
69
+ ip=ip,
70
+ context=context,
71
+ namespace=namespace,
150
72
  )
151
- info(cmd)
152
73
 
153
- info("Run Docker container")
154
- port_ = str(port or ctx.config["port"] or Ports.DEV_SERVER.value)
155
- container = docker_client.containers.run(
156
- image,
157
- command=cmd,
158
- mounts=mounts,
159
- detach=True,
160
- labels={
161
- f"{APPNAME}-type": InstanceType.SERVER.value,
162
- "name": ctx.config_file_name,
163
- },
164
- environment=environment_vars,
165
- ports={f"{internal_port}/tcp": (ip, port_)},
166
- name=ctx.docker_container_name,
167
- auto_remove=not keep,
168
- tty=True,
169
- network=server_network_mgr.network_name,
74
+ # port forward for UI
75
+ info("Port forwarding for UI")
76
+ start_port_forward(
77
+ service_name=f"{release_name}-vantage6-frontend-service",
78
+ service_port=ctx.config["ui"].get("port", 7600),
79
+ port=ui_port or ctx.config["ui"].get("port", 7600),
80
+ ip=ip,
81
+ context=context,
82
+ namespace=namespace,
170
83
  )
171
84
 
172
- info(f"Success! container id = {container.id}")
173
-
174
85
  if attach:
175
- attach_logs(container, InstanceType.SERVER)
176
-
177
-
178
- def _start_rabbitmq(
179
- ctx: ServerContext, rabbitmq_image: str, network_mgr: NetworkManager
180
- ) -> None:
181
- """
182
- Start the RabbitMQ container if it is not already running.
183
-
184
- Parameters
185
- ----------
186
- ctx : ServerContext
187
- Server context object
188
- rabbitmq_image : str
189
- RabbitMQ image to use
190
- network_mgr : NetworkManager
191
- Network manager object
192
- """
193
- rabbit_uri = ctx.config["rabbitmq"].get("uri")
194
- if not rabbit_uri:
195
- error(
196
- "No RabbitMQ URI found in the configuration file! Please add"
197
- "a 'uri' key to the 'rabbitmq' section of the configuration."
198
- )
199
- exit(1)
200
- # kick off RabbitMQ container
201
- rabbit_mgr = RabbitMQManager(ctx=ctx, network_mgr=network_mgr, image=rabbitmq_image)
202
- rabbit_mgr.start()
203
-
204
-
205
- def _start_ui(client: DockerClient, ctx: ServerContext, ui_port: int) -> None:
206
- """
207
- Start the UI container.
208
-
209
- Parameters
210
- ----------
211
- client : DockerClient
212
- Docker client
213
- ctx : ServerContext
214
- Server context object
215
- ui_port : int
216
- Port to expose the UI on
217
- """
218
- # if no port is specified, check if config contains a port
219
- ui_config = ctx.config.get("ui")
220
- if ui_config and not ui_port:
221
- ui_port = ui_config.get("port")
222
-
223
- # check if the port is valid
224
- # TODO make function to check if port is valid, and use in more places
225
- if not isinstance(ui_port, int) or not 0 < ui_port < 65536:
226
- warning(
227
- f"UI port '{ui_port}' is not valid! Using default port "
228
- f"{Ports.DEV_UI.value}"
229
- )
230
- ui_port = str(Ports.DEV_UI.value)
231
-
232
- # find image to use
233
- image = get_image(None, ctx, "ui", DEFAULT_UI_IMAGE)
234
-
235
- pull_infra_image(client, image, InstanceType.UI)
236
-
237
- # set environment variables
238
- env_vars = {
239
- "SERVER_URL": f"http://localhost:{ctx.config.get('port')}",
240
- "API_PATH": ctx.config.get("api_path"),
241
- }
242
-
243
- # stop the UI container if it is already running
244
- stop_ui(client, ctx)
245
-
246
- info(f"Starting User Interface at port {ui_port}")
247
- ui_container_name = f"{APPNAME}-{ctx.name}-{ctx.scope}-ui"
248
- client.containers.run(
249
- image,
250
- detach=True,
251
- labels={f"{APPNAME}-type": "ui", "name": ctx.config_file_name},
252
- ports={"80/tcp": (ctx.config.get("ip"), ui_port)},
253
- name=ui_container_name,
254
- environment=env_vars,
255
- tty=True,
256
- )
86
+ attach_logs("app=vantage6-server", "component=vantage6-server")
@@ -1,119 +1,49 @@
1
1
  import click
2
- import questionary as q
3
- import docker
4
- from colorama import Fore, Style
5
- from docker.client import DockerClient
6
2
 
7
- from vantage6.common import info, warning, error
8
- from vantage6.common.docker.addons import (
9
- check_docker_running,
10
- remove_container,
11
- get_server_config_name,
12
- get_container,
13
- get_num_nonempty_networks,
14
- get_network,
15
- delete_network,
16
- remove_container_if_exists,
17
- )
18
- from vantage6.common.globals import APPNAME, InstanceType
19
- from vantage6.common import split_rabbitmq_uri
3
+ from vantage6.common import info
4
+
5
+ from vantage6.cli.common.decorator import click_insert_context
6
+ from vantage6.cli.config import CliConfig
20
7
  from vantage6.cli.context.server import ServerContext
21
- from vantage6.cli.globals import DEFAULT_SERVER_SYSTEM_FOLDERS
22
- from vantage6.cli.server.common import get_server_context, stop_ui
8
+ from vantage6.cli.common.stop import helm_uninstall, stop_port_forward
23
9
 
24
10
 
25
11
  @click.command()
26
- @click.option("-n", "--name", default=None, help="Configuration name")
27
- @click.option("--system", "system_folders", flag_value=True)
28
- @click.option(
29
- "--user", "system_folders", flag_value=False, default=DEFAULT_SERVER_SYSTEM_FOLDERS
30
- )
31
- @click.option("--all", "all_servers", flag_value=True, help="Stop all servers")
32
- def cli_server_stop(name: str, system_folders: bool, all_servers: bool):
12
+ # add context and namespace options
13
+ @click.option("--context", default=None, help="Kubernetes context to use")
14
+ @click.option("--namespace", default=None, help="Kubernetes namespace to use")
15
+ @click_insert_context(type_="server")
16
+ def cli_server_stop(
17
+ ctx: ServerContext,
18
+ context: str,
19
+ namespace: str,
20
+ ):
33
21
  """
34
- Stop one or all running server(s).
22
+ Stop an running server.
35
23
  """
36
- check_docker_running()
37
- client = docker.from_env()
24
+ cli_config = CliConfig()
38
25
 
39
- running_servers = client.containers.list(
40
- filters={"label": f"{APPNAME}-type={InstanceType.SERVER.value}"}
26
+ context, namespace = cli_config.compare_changes_config(
27
+ context=context,
28
+ namespace=namespace,
41
29
  )
42
30
 
43
- if not running_servers:
44
- warning("No servers are currently running.")
45
- return
46
-
47
- running_server_names = [server.name for server in running_servers]
48
-
49
- if all_servers:
50
- for container_name in running_server_names:
51
- _stop_server_containers(client, container_name, system_folders)
52
- return
53
-
54
- # make sure we have a configuration name to work with
55
- if not name:
56
- try:
57
- container_name = q.select(
58
- "Select the server you wish to stop:", choices=running_server_names
59
- ).unsafe_ask()
60
- except KeyboardInterrupt:
61
- error("Aborted by user!")
62
- return
63
- else:
64
- post_fix = "system" if system_folders else "user"
65
- container_name = f"{APPNAME}-{name}-{post_fix}-{InstanceType.SERVER.value}"
66
-
67
- if container_name not in running_server_names:
68
- error(f"{Fore.RED}{name}{Style.RESET_ALL} is not running!")
69
- return
70
-
71
- _stop_server_containers(client, container_name, system_folders)
72
-
73
-
74
- def _stop_server_containers(
75
- client: DockerClient, container_name: str, system_folders: bool
76
- ) -> None:
77
- """
78
- Given a server's name, kill its docker container and related (RabbitMQ)
79
- containers.
80
-
81
- Parameters
82
- ----------
83
- client : DockerClient
84
- Docker client
85
- container_name : str
86
- Name of the server to stop
87
- system_folders : bool
88
- Wether to use system folders or not
89
- """
90
- # kill the server
91
- remove_container_if_exists(client, name=container_name)
92
- info(f"Stopped the {Fore.GREEN}{container_name}{Style.RESET_ALL} server.")
93
-
94
- # find the configuration name from the docker container name
95
- scope = "system" if system_folders else "user"
96
- config_name = get_server_config_name(container_name, scope)
97
-
98
- ctx = get_server_context(config_name, system_folders, ServerContext)
31
+ # uninstall the helm release
32
+ info("Stopping server...")
33
+ release_name = f"{ctx.name}-{ctx.instance_type}"
34
+ helm_uninstall(
35
+ release_name=release_name,
36
+ context=context,
37
+ namespace=namespace,
38
+ )
99
39
 
100
- # kill the UI container (if it exists)
101
- stop_ui(client, ctx)
40
+ # stop the port forwarding for server and UI
41
+ stop_port_forward(
42
+ service_name=f"{release_name}-vantage6-server-service",
43
+ )
102
44
 
103
- # delete the server network
104
- network_name = f"{APPNAME}-{ctx.name}-{ctx.scope}-network"
105
- network = get_network(client, name=network_name)
106
- delete_network(network, kill_containers=False)
45
+ stop_port_forward(
46
+ service_name=f"{release_name}-vantage6-frontend-service",
47
+ )
107
48
 
108
- # kill RabbitMQ if it exists and no other servers are using to it (i.e. it
109
- # is not in other docker networks with other containers)
110
- rabbit_uri = ctx.config.get("rabbitmq", {}).get("uri")
111
- if rabbit_uri:
112
- rabbit_container_name = split_rabbitmq_uri(rabbit_uri=rabbit_uri)["host"]
113
- rabbit_container = get_container(client, name=rabbit_container_name)
114
- if rabbit_container and get_num_nonempty_networks(rabbit_container) == 0:
115
- remove_container(rabbit_container, kill=True)
116
- info(
117
- f"Stopped the {Fore.GREEN}{rabbit_container_name}"
118
- f"{Style.RESET_ALL} container."
119
- )
49
+ info("Server stopped successfully.")
@@ -19,5 +19,4 @@ dev:
19
19
  disable_review: true
20
20
  policies:
21
21
  algorithm_view: public
22
- allow_localhost: true
23
22
  {{ user_provided_config }}
@@ -28,4 +28,4 @@ port: {{ port }}
28
28
  server_url: {{ server_url }}
29
29
  task_dir: {{ task_dir}}
30
30
  task_namespace: {{ task_namespace }}
31
- {{ user_provided_config }}
31
+ {{- user_provided_config -}}
@@ -9,8 +9,6 @@ organizations:
9
9
  {% if org['make_admin'] %}
10
10
  users:
11
11
  - username: dev_admin
12
- firstname: admin
13
- lastname: robot
14
12
  password: password
15
13
  {% endif %}
16
14
  public_key: LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQ0lqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FnOEFNSUlDQ2dLQ0FnRUF2eU4wWVZhWWVZcHVWRVlpaDJjeQphTjdxQndCUnB5bVVibnRQNmw2Vk9OOGE1eGwxMmJPTlQyQ1hwSEVGUFhZQTFFZThQRFZwYnNQcVVKbUlseWpRCkgyN0NhZTlIL2lJbUNVNnViUXlnTzFsbG1KRTJQWDlTNXVxendVV3BXMmRxRGZFSHJLZTErUUlDRGtGSldmSEIKWkJkczRXMTBsMWlxK252dkZ4OWY3dk8xRWlLcVcvTGhQUS83Mm52YlZLMG9nRFNaUy9Jc1NnUlk5ZnJVU1FZUApFbGVZWUgwYmI5VUdlNUlYSHRMQjBkdVBjZUV4dXkzRFF5bXh2WTg3bTlkelJsN1NqaFBqWEszdUplSDAwSndjCk80TzJ0WDVod0lLL1hEQ3h4eCt4b3cxSDdqUWdXQ0FybHpodmdzUkdYUC9wQzEvL1hXaVZSbTJWZ3ZqaXNNaisKS2VTNWNaWWpkUkMvWkRNRW1QU29rS2Y4UnBZUk1lZk0xMWtETTVmaWZIQTlPcmY2UXEyTS9SMy90Mk92VDRlRgorUzVJeTd1QWk1N0ROUkFhejVWRHNZbFFxTU5QcUpKYlRtcGlYRWFpUHVLQitZVEdDSC90TXlrRG1JK1dpejNRCjh6SVo1bk1IUnhySFNqSWdWSFdwYnZlTnVaL1Q1aE95aE1uZHU0c3NpRkJyUXN5ZGc1RlVxR3lkdE1JMFJEVHcKSDVBc1ovaFlLeHdiUm1xTXhNcjFMaDFBaDB5SUlsZDZKREY5MkF1UlNTeDl0djNaVWRndEp5VVlYN29VZS9GKwpoUHVwVU4rdWVTUndGQjBiVTYwRXZQWTdVU2RIR1diVVIrRDRzTVQ4Wjk0UVl2S2ZCanU3ZXVKWSs0Mmd2Wm9jCitEWU9ZS05qNXFER2V5azErOE9aTXZNQ0F3RUFBUT09Ci0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQo=
@@ -0,0 +1,29 @@
1
+ average = {
2
+ "collaboration": 1,
3
+ "organizations": [1],
4
+ "name": "test_average_task",
5
+ "image": "harbor2.vantage6.ai/demo/average",
6
+ "description": "",
7
+ "method": "central_average",
8
+ "arguments": {
9
+ "column_name": "Age",
10
+ },
11
+ "databases": [{"label": "olympic_athletes"}],
12
+ }
13
+
14
+ kaplan_meier = {
15
+ "collaboration": 1,
16
+ "organizations": [1],
17
+ "name": "test_average_task",
18
+ "image": "harbor2.vantage6.ai/algorithms/kaplan-meier",
19
+ "description": "",
20
+ "method": "kaplan_meier_central",
21
+ "arguments": {
22
+ "time_column_name": "days",
23
+ "censor_column_name": "censor",
24
+ "organizations_to_include": [1, 2, 3],
25
+ },
26
+ "databases": [{"label": "kaplan_meier_test"}],
27
+ }
28
+
29
+ args = {"average": average, "kaplan_meier": kaplan_meier}
@@ -0,0 +1,91 @@
1
+ import logging
2
+ import json
3
+ import sys
4
+
5
+ from vantage6.common.enum import TaskStatus
6
+
7
+ from vantage6.client import Client
8
+ from vantage6.common import error
9
+ from vantage6.common.globals import Ports
10
+ import vantage6.cli.test.algo_test_scripts.algo_test_arguments as arguments
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 client.task.get(task_id)["status"] != TaskStatus.FAILED.value
37
+
38
+ logging.info("Task for %s completed successfully.", algo_name)
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(
60
+ server_url=f"http://localhost:{Ports.DEV_SERVER.value}/api",
61
+ auth_url="http://localhost:8080",
62
+ )
63
+ try:
64
+ client.authenticate()
65
+ except ConnectionError:
66
+ error(
67
+ "Could not connect to the server. Please check if a dev network is running."
68
+ )
69
+ exit(1)
70
+
71
+ # if custom arguments are provided, use them for running the task
72
+ if custom_args:
73
+ create_and_run_task(client, custom_args)
74
+
75
+ else:
76
+ # Run the task for each algorithm in the arguments file
77
+ for algo, task_args in arguments.args.items():
78
+ logging.info("Running task for %s", algo)
79
+ logging.info("Task arguments: %s", task_args)
80
+ create_and_run_task(client, task_args, algo)
81
+
82
+
83
+ if __name__ == "__main__":
84
+ # check if arguments are provided
85
+ if len(sys.argv) > 1:
86
+ input_string = sys.argv[1].replace("'", '"')
87
+ json_input = json.loads(input_string)
88
+ else:
89
+ json_input = None
90
+
91
+ run_test(json_input)