vantage6 4.2.1__py3-none-any.whl → 4.3.0b3__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 (64) hide show
  1. tests_cli/test_example.py +0 -1
  2. tests_cli/test_node_cli.py +74 -79
  3. tests_cli/test_server_cli.py +22 -22
  4. tests_cli/test_wizard.py +41 -29
  5. vantage6/cli/__build__ +1 -1
  6. vantage6/cli/_version.py +11 -8
  7. vantage6/cli/algorithm/create.py +14 -14
  8. vantage6/cli/algorithm/update.py +9 -6
  9. vantage6/cli/algostore/attach.py +32 -0
  10. vantage6/cli/algostore/new.py +55 -0
  11. vantage6/cli/algostore/start.py +102 -0
  12. vantage6/cli/algostore/stop.py +60 -0
  13. vantage6/cli/cli.py +32 -12
  14. vantage6/cli/common/decorator.py +92 -0
  15. vantage6/cli/common/start.py +232 -0
  16. vantage6/cli/configuration_manager.py +22 -32
  17. vantage6/cli/configuration_wizard.py +255 -193
  18. vantage6/cli/context/__init__.py +86 -0
  19. vantage6/cli/context/algorithm_store.py +130 -0
  20. vantage6/cli/context/base_server.py +89 -0
  21. vantage6/cli/context/node.py +254 -0
  22. vantage6/cli/context/server.py +127 -0
  23. vantage6/cli/dev/create.py +180 -113
  24. vantage6/cli/dev/remove.py +20 -19
  25. vantage6/cli/dev/start.py +10 -10
  26. vantage6/cli/dev/stop.py +7 -5
  27. vantage6/cli/globals.py +24 -0
  28. vantage6/cli/node/attach.py +21 -10
  29. vantage6/cli/node/clean.py +4 -2
  30. vantage6/cli/node/common/__init__.py +15 -11
  31. vantage6/cli/node/create_private_key.py +58 -27
  32. vantage6/cli/node/files.py +14 -6
  33. vantage6/cli/node/list.py +18 -24
  34. vantage6/cli/node/new.py +21 -12
  35. vantage6/cli/node/remove.py +31 -22
  36. vantage6/cli/node/set_api_key.py +18 -12
  37. vantage6/cli/node/start.py +38 -12
  38. vantage6/cli/node/stop.py +32 -18
  39. vantage6/cli/node/version.py +23 -13
  40. vantage6/cli/rabbitmq/__init__.py +9 -9
  41. vantage6/cli/rabbitmq/definitions.py +24 -28
  42. vantage6/cli/rabbitmq/queue_manager.py +37 -40
  43. vantage6/cli/server/attach.py +16 -11
  44. vantage6/cli/server/common/__init__.py +37 -25
  45. vantage6/cli/server/files.py +1 -1
  46. vantage6/cli/server/import_.py +45 -37
  47. vantage6/cli/server/list.py +22 -23
  48. vantage6/cli/server/new.py +20 -14
  49. vantage6/cli/server/remove.py +5 -4
  50. vantage6/cli/server/shell.py +17 -6
  51. vantage6/cli/server/start.py +118 -174
  52. vantage6/cli/server/stop.py +31 -23
  53. vantage6/cli/server/version.py +16 -13
  54. vantage6/cli/test/common/diagnostic_runner.py +30 -34
  55. vantage6/cli/test/feature_tester.py +51 -25
  56. vantage6/cli/test/integration_test.py +69 -29
  57. vantage6/cli/utils.py +6 -5
  58. {vantage6-4.2.1.dist-info → vantage6-4.3.0b3.dist-info}/METADATA +5 -3
  59. vantage6-4.3.0b3.dist-info/RECORD +68 -0
  60. vantage6/cli/context.py +0 -416
  61. vantage6-4.2.1.dist-info/RECORD +0 -58
  62. {vantage6-4.2.1.dist-info → vantage6-4.3.0b3.dist-info}/WHEEL +0 -0
  63. {vantage6-4.2.1.dist-info → vantage6-4.3.0b3.dist-info}/entry_points.txt +0 -0
  64. {vantage6-4.2.1.dist-info → vantage6-4.3.0b3.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,130 @@
1
+ from __future__ import annotations
2
+
3
+ from vantage6.common.globals import APPNAME, InstanceType
4
+ from vantage6.cli.configuration_manager import ServerConfigurationManager
5
+ from vantage6.cli.globals import (
6
+ DEFAULT_SERVER_SYSTEM_FOLDERS as S_FOL,
7
+ ServerType,
8
+ AlgoStoreGlobals,
9
+ )
10
+ from vantage6.cli._version import __version__
11
+ from vantage6.cli.context.base_server import BaseServerContext
12
+
13
+
14
+ class AlgorithmStoreContext(BaseServerContext):
15
+ """
16
+ A context class for the algorithm store server.
17
+
18
+ Parameters
19
+ ----------
20
+ instance_name : str
21
+ Name of the configuration instance, corresponds to the filename
22
+ of the configuration file.
23
+ system_folders : bool, optional
24
+ System wide or user configuration, by default S_FOL
25
+ """
26
+
27
+ INST_CONFIG_MANAGER = ServerConfigurationManager
28
+
29
+ def __init__(self, instance_name: str, system_folders: bool = S_FOL):
30
+ super().__init__(
31
+ InstanceType.ALGORITHM_STORE, instance_name, system_folders=system_folders
32
+ )
33
+ self.log.info("vantage6 version '%s'", __version__)
34
+
35
+ def get_database_uri(self) -> str:
36
+ """
37
+ Obtain the database uri from the environment or the configuration. The
38
+ `VANTAGE6_DB_URI` environment variable is used by the Docker container,
39
+ but can also be set by the user.
40
+
41
+ Returns
42
+ -------
43
+ str
44
+ string representation of the database uri
45
+ """
46
+ return super().get_database_uri(AlgoStoreGlobals.DB_URI_ENV_VAR)
47
+
48
+ @property
49
+ def docker_container_name(self) -> str:
50
+ """
51
+ Name of the docker container that the server is running in.
52
+
53
+ Returns
54
+ -------
55
+ str
56
+ Server's docker container name
57
+ """
58
+ return f"{APPNAME}-{self.name}-{self.scope}-{ServerType.ALGORITHM_STORE}"
59
+
60
+ @classmethod
61
+ def from_external_config_file(
62
+ cls, path: str, system_folders: bool = S_FOL
63
+ ) -> AlgorithmStoreContext:
64
+ """
65
+ Create a server context from an external configuration file. External
66
+ means that the configuration file is not located in the default folders
67
+ but its location is specified by the user.
68
+
69
+ Parameters
70
+ ----------
71
+ path : str
72
+ Path of the configuration file
73
+ system_folders : bool, optional
74
+ System wide or user configuration, by default S_FOL
75
+
76
+ Returns
77
+ -------
78
+ AlgorithmStoreContext
79
+ Server context object
80
+ """
81
+ return super().from_external_config_file(
82
+ path,
83
+ ServerType.ALGORITHM_STORE,
84
+ AlgoStoreGlobals.CONFIG_NAME_ENV_VAR,
85
+ system_folders,
86
+ )
87
+
88
+ @classmethod
89
+ def config_exists(cls, instance_name: str, system_folders: bool = S_FOL) -> bool:
90
+ """
91
+ Check if a configuration file exists.
92
+
93
+ Parameters
94
+ ----------
95
+ instance_name : str
96
+ Name of the configuration instance, corresponds to the filename
97
+ of the configuration file.
98
+ system_folders : bool, optional
99
+ System wide or user configuration, by default S_FOL
100
+
101
+ Returns
102
+ -------
103
+ bool
104
+ Whether the configuration file exists or not
105
+ """
106
+ return super().config_exists(
107
+ InstanceType.ALGORITHM_STORE, instance_name, system_folders
108
+ )
109
+
110
+ @classmethod
111
+ def available_configurations(
112
+ cls, system_folders: bool = S_FOL
113
+ ) -> tuple[list, list]:
114
+ """
115
+ Find all available server configurations in the default folders.
116
+
117
+ Parameters
118
+ ----------
119
+ system_folders : bool, optional
120
+ System wide or user configuration, by default S_FOL
121
+
122
+ Returns
123
+ -------
124
+ tuple[list, list]
125
+ The first list contains validated configuration files, the second
126
+ list contains invalid configuration files.
127
+ """
128
+ return super().available_configurations(
129
+ InstanceType.ALGORITHM_STORE, system_folders
130
+ )
@@ -0,0 +1,89 @@
1
+ from __future__ import annotations
2
+
3
+ import os.path
4
+
5
+ from sqlalchemy.engine.url import make_url
6
+
7
+ from vantage6.common.context import AppContext
8
+ from vantage6.cli.globals import (
9
+ DEFAULT_SERVER_SYSTEM_FOLDERS as S_FOL,
10
+ ServerType,
11
+ )
12
+
13
+
14
+ class BaseServerContext(AppContext):
15
+ """
16
+ Base context for a vantage6 server or algorithm store server
17
+
18
+ Contains functions that the ServerContext and AlgorithmStoreContext have
19
+ in common.
20
+ """
21
+
22
+ def get_database_uri(self, db_env_var: str) -> str:
23
+ """
24
+ Obtain the database uri from the environment or the configuration.
25
+
26
+ Parameters
27
+ ----------
28
+ db_env_var : str
29
+ Name of the environment variable that contains the database uri
30
+
31
+ Returns
32
+ -------
33
+ str
34
+ string representation of the database uri
35
+ """
36
+ uri = os.environ.get(db_env_var) or self.config["uri"]
37
+ url = make_url(uri)
38
+
39
+ if url.host is None and not os.path.isabs(url.database):
40
+ # We're dealing with a relative path here of a local database, when
41
+ # we're running the server outside of docker. Therefore we need to
42
+ # prepend the data directory to the database name, but after the
43
+ # driver name (e.g. sqlite:////db.sqlite ->
44
+ # sqlite:////data_dir>/db.sqlite)
45
+
46
+ # find index of database name
47
+ idx_db_name = str(url).find(url.database)
48
+
49
+ # add the datadir to the right location in the database uri
50
+ return str(url)[:idx_db_name] + str(self.data_dir / url.database)
51
+
52
+ return uri
53
+
54
+ @classmethod
55
+ def from_external_config_file(
56
+ cls,
57
+ path: str,
58
+ server_type: ServerType,
59
+ config_name_env_var: str,
60
+ system_folders: bool = S_FOL,
61
+ ) -> BaseServerContext:
62
+ """
63
+ Create a server context from an external configuration file. External
64
+ means that the configuration file is not located in the default folders
65
+ but its location is specified by the user.
66
+
67
+ Parameters
68
+ ----------
69
+ path : str
70
+ Path of the configuration file
71
+ server_type : ServerType
72
+ Type of server, either 'server' or 'algorithm-store'
73
+ config_name_env_var : str
74
+ Name of the environment variable that contains the name of the
75
+ configuration
76
+ system_folders : bool, optional
77
+ System wide or user configuration, by default S_FOL
78
+
79
+ Returns
80
+ -------
81
+ ServerContext
82
+ Server context object
83
+ """
84
+ cls = super().from_external_config_file(path, server_type, system_folders)
85
+ # if we are running a server in a docker container, the name is taken
86
+ # from the name of the config file (which is usually a default). Get
87
+ # the config name from environment if it is given.
88
+ cls.name = os.environ.get(config_name_env_var) or cls.name
89
+ return cls
@@ -0,0 +1,254 @@
1
+ from __future__ import annotations
2
+
3
+ import os.path
4
+
5
+ from pathlib import Path
6
+
7
+ from vantage6.common.context import AppContext
8
+ from vantage6.common.globals import APPNAME, InstanceType
9
+ from vantage6.cli.configuration_manager import NodeConfigurationManager
10
+ from vantage6.cli.globals import DEFAULT_NODE_SYSTEM_FOLDERS as N_FOL
11
+ from vantage6.cli._version import __version__
12
+
13
+
14
+ class NodeContext(AppContext):
15
+ """
16
+ Node context object for the host system.
17
+
18
+ See DockerNodeContext for the node instance mounts when running as a
19
+ dockerized service.
20
+
21
+ Parameters
22
+ ----------
23
+ instance_name : str
24
+ Name of the configuration instance, corresponds to the filename
25
+ of the configuration file.
26
+ system_folders : bool, optional
27
+ _description_, by default N_FOL
28
+ config_file : str, optional
29
+ _description_, by default None
30
+ """
31
+
32
+ # The server configuration manager is aware of the structure of the server
33
+ # configuration file and makes sure only valid configuration can be loaded.
34
+ INST_CONFIG_MANAGER = NodeConfigurationManager
35
+
36
+ def __init__(
37
+ self, instance_name: str, system_folders: bool = N_FOL, config_file: str = None
38
+ ):
39
+ super().__init__(InstanceType.NODE, instance_name, system_folders, config_file)
40
+ self.log.info("vantage6 version '%s'", __version__)
41
+
42
+ @classmethod
43
+ def from_external_config_file(
44
+ cls, path: str, system_folders: bool = N_FOL
45
+ ) -> NodeContext:
46
+ """
47
+ Create a node context from an external configuration file. External
48
+ means that the configuration file is not located in the default folders
49
+ but its location is specified by the user.
50
+
51
+ Parameters
52
+ ----------
53
+ path : str
54
+ Path of the configuration file
55
+ system_folders : bool, optional
56
+ System wide or user configuration, by default N_FOL
57
+
58
+ Returns
59
+ -------
60
+ NodeContext
61
+ Node context object
62
+ """
63
+ return super().from_external_config_file(
64
+ path, InstanceType.NODE, system_folders
65
+ )
66
+
67
+ @classmethod
68
+ def config_exists(cls, instance_name: str, system_folders: bool = N_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 N_FOL
79
+
80
+ Returns
81
+ -------
82
+ bool
83
+ Whether the configuration file exists or not
84
+ """
85
+ return super().config_exists(
86
+ InstanceType.NODE, instance_name, system_folders=system_folders
87
+ )
88
+
89
+ @classmethod
90
+ def available_configurations(
91
+ cls, system_folders: bool = N_FOL
92
+ ) -> tuple[list, list]:
93
+ """
94
+ Find all available server configurations in the default folders.
95
+
96
+ Parameters
97
+ ----------
98
+ system_folders : bool, optional
99
+ System wide or user configuration, by default N_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.NODE, system_folders)
108
+
109
+ @staticmethod
110
+ def type_data_folder(system_folders: bool = N_FOL) -> Path:
111
+ """
112
+ Obtain OS specific data folder where to store node specific data.
113
+
114
+ Parameters
115
+ ----------
116
+ system_folders : bool, optional
117
+ System wide or user configuration
118
+
119
+ Returns
120
+ -------
121
+ Path
122
+ Path to the data folder
123
+ """
124
+ return AppContext.type_data_folder(InstanceType.NODE, system_folders)
125
+
126
+ @property
127
+ def databases(self) -> dict:
128
+ """
129
+ Dictionary of local databases that are available for this node.
130
+
131
+ Returns
132
+ -------
133
+ dict
134
+ dictionary with database names as keys and their corresponding
135
+ paths as values.
136
+ """
137
+ return self.config["databases"]
138
+
139
+ @property
140
+ def docker_container_name(self) -> str:
141
+ """
142
+ Docker container name of the node.
143
+
144
+ Returns
145
+ -------
146
+ str
147
+ Node's Docker container name
148
+ """
149
+ return f"{APPNAME}-{self.name}-{self.scope}"
150
+
151
+ @property
152
+ def docker_network_name(self) -> str:
153
+ """
154
+ Private Docker network name which is unique for this node.
155
+
156
+ Returns
157
+ -------
158
+ str
159
+ Docker network name
160
+ """
161
+ return f"{APPNAME}-{self.name}-{self.scope}-net"
162
+
163
+ @property
164
+ def docker_volume_name(self) -> str:
165
+ """
166
+ Docker volume in which task data is stored. In case a file based
167
+ database is used, this volume contains the database file as well.
168
+
169
+ Returns
170
+ -------
171
+ str
172
+ Docker volume name
173
+ """
174
+ return os.environ.get("DATA_VOLUME_NAME", f"{self.docker_container_name}-vol")
175
+
176
+ @property
177
+ def docker_vpn_volume_name(self) -> str:
178
+ """
179
+ Docker volume in which the VPN configuration is stored.
180
+
181
+ Returns
182
+ -------
183
+ str
184
+ Docker volume name
185
+ """
186
+ return os.environ.get(
187
+ "VPN_VOLUME_NAME", f"{self.docker_container_name}-vpn-vol"
188
+ )
189
+
190
+ @property
191
+ def docker_ssh_volume_name(self) -> str:
192
+ """
193
+ Docker volume in which the SSH configuration is stored.
194
+
195
+ Returns
196
+ -------
197
+ str
198
+ Docker volume name
199
+ """
200
+ return os.environ.get(
201
+ "SSH_TUNNEL_VOLUME_NAME", f"{self.docker_container_name}-ssh-vol"
202
+ )
203
+
204
+ @property
205
+ def docker_squid_volume_name(self) -> str:
206
+ """
207
+ Docker volume in which the SSH configuration is stored.
208
+
209
+ Returns
210
+ -------
211
+ str
212
+ Docker volume name
213
+ """
214
+ return os.environ.get(
215
+ "SSH_SQUID_VOLUME_NAME", f"{self.docker_container_name}-squid-vol"
216
+ )
217
+
218
+ @property
219
+ def proxy_log_file(self):
220
+ return self.log_file_name(type_="proxy_server")
221
+
222
+ def docker_temporary_volume_name(self, job_id: int) -> str:
223
+ """
224
+ Docker volume in which temporary data is stored. Temporary data is
225
+ linked to a specific run. Multiple algorithm containers can have the
226
+ same run id, and therefore the share same temporary volume.
227
+
228
+ Parameters
229
+ ----------
230
+ job_id : int
231
+ run id provided by the server
232
+
233
+ Returns
234
+ -------
235
+ str
236
+ Docker volume name
237
+ """
238
+ return f"{APPNAME}-{self.name}-{self.scope}-{job_id}-tmpvol"
239
+
240
+ def get_database_uri(self, label: str = "default") -> str:
241
+ """
242
+ Obtain the database URI for a specific database.
243
+
244
+ Parameters
245
+ ----------
246
+ label : str, optional
247
+ Database label, by default "default"
248
+
249
+ Returns
250
+ -------
251
+ str
252
+ URI to the database
253
+ """
254
+ return self.config["databases"][label]
@@ -0,0 +1,127 @@
1
+ from __future__ import annotations
2
+
3
+ from vantage6.common.globals import APPNAME, InstanceType
4
+ from vantage6.cli.configuration_manager import ServerConfigurationManager
5
+ from vantage6.cli.globals import (
6
+ DEFAULT_SERVER_SYSTEM_FOLDERS as S_FOL,
7
+ ServerType,
8
+ ServerGlobals,
9
+ )
10
+ from vantage6.cli._version import __version__
11
+ from vantage6.cli.context.base_server import BaseServerContext
12
+
13
+
14
+ class ServerContext(BaseServerContext):
15
+ """
16
+ Server context
17
+
18
+ Parameters
19
+ ----------
20
+ instance_name : str
21
+ Name of the configuration instance, corresponds to the filename
22
+ of the configuration file.
23
+ system_folders : bool, optional
24
+ System wide or user configuration, by default S_FOL
25
+ """
26
+
27
+ # The server configuration manager is aware of the structure of the server
28
+ # configuration file and makes sure only valid configuration can be loaded.
29
+ INST_CONFIG_MANAGER = ServerConfigurationManager
30
+
31
+ def __init__(self, instance_name: str, system_folders: bool = S_FOL):
32
+ super().__init__(
33
+ InstanceType.SERVER, instance_name, system_folders=system_folders
34
+ )
35
+ self.log.info("vantage6 version '%s'", __version__)
36
+
37
+ def get_database_uri(self) -> str:
38
+ """
39
+ Obtain the database uri from the environment or the configuration. The
40
+ `VANTAGE6_DB_URI` environment variable is used by the Docker container,
41
+ but can also be set by the user.
42
+
43
+ Returns
44
+ -------
45
+ str
46
+ string representation of the database uri
47
+ """
48
+ return super().get_database_uri(ServerGlobals.DB_URI_ENV_VAR)
49
+
50
+ @property
51
+ def docker_container_name(self) -> str:
52
+ """
53
+ Name of the docker container that the server is running in.
54
+
55
+ Returns
56
+ -------
57
+ str
58
+ Server's docker container name
59
+ """
60
+ return f"{APPNAME}-{self.name}-{self.scope}-{ServerType.V6SERVER}"
61
+
62
+ @classmethod
63
+ def from_external_config_file(
64
+ cls, path: str, system_folders: bool = S_FOL
65
+ ) -> ServerContext:
66
+ """
67
+ Create a server context from an external configuration file. External
68
+ means that the configuration file is not located in the default folders
69
+ but its location is specified by the user.
70
+
71
+ Parameters
72
+ ----------
73
+ path : str
74
+ Path of the configuration file
75
+ system_folders : bool, optional
76
+ System wide or user configuration, by default S_FOL
77
+
78
+ Returns
79
+ -------
80
+ ServerContext
81
+ Server context object
82
+ """
83
+ return super().from_external_config_file(
84
+ path, ServerType.V6SERVER, ServerGlobals.CONFIG_NAME_ENV_VAR, system_folders
85
+ )
86
+
87
+ @classmethod
88
+ def config_exists(cls, instance_name: str, system_folders: bool = S_FOL) -> bool:
89
+ """
90
+ Check if a configuration file exists.
91
+
92
+ Parameters
93
+ ----------
94
+ instance_name : str
95
+ Name of the configuration instance, corresponds to the filename
96
+ of the configuration file.
97
+ system_folders : bool, optional
98
+ System wide or user configuration, by default S_FOL
99
+
100
+ Returns
101
+ -------
102
+ bool
103
+ Whether the configuration file exists or not
104
+ """
105
+ return super().config_exists(
106
+ InstanceType.SERVER, instance_name, system_folders=system_folders
107
+ )
108
+
109
+ @classmethod
110
+ def available_configurations(
111
+ cls, system_folders: bool = S_FOL
112
+ ) -> tuple[list, list]:
113
+ """
114
+ Find all available server configurations in the default folders.
115
+
116
+ Parameters
117
+ ----------
118
+ system_folders : bool, optional
119
+ System wide or user configuration, by default S_FOL
120
+
121
+ Returns
122
+ -------
123
+ tuple[list, list]
124
+ The first list contains validated configuration files, the second
125
+ list contains invalid configuration files.
126
+ """
127
+ return super().available_configurations(InstanceType.SERVER, system_folders)