qwak-core 0.4.272__py3-none-any.whl → 0.4.274__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.
Files changed (64) hide show
  1. frogml_storage/__init__.py +1 -0
  2. frogml_storage/artifactory/__init__.py +1 -0
  3. frogml_storage/artifactory/_artifactory_api.py +315 -0
  4. frogml_storage/authentication/login/__init__.py +1 -0
  5. frogml_storage/authentication/login/_login_cli.py +239 -0
  6. frogml_storage/authentication/login/_login_command.py +74 -0
  7. frogml_storage/authentication/models/__init__.py +3 -0
  8. frogml_storage/authentication/models/_auth.py +24 -0
  9. frogml_storage/authentication/models/_auth_config.py +70 -0
  10. frogml_storage/authentication/models/_login.py +22 -0
  11. frogml_storage/authentication/utils/__init__.py +17 -0
  12. frogml_storage/authentication/utils/_authentication_utils.py +281 -0
  13. frogml_storage/authentication/utils/_login_checks_utils.py +114 -0
  14. frogml_storage/base_storage.py +140 -0
  15. frogml_storage/constants.py +56 -0
  16. frogml_storage/exceptions/checksum_verification_error.py +3 -0
  17. frogml_storage/exceptions/validation_error.py +4 -0
  18. frogml_storage/frog_ml.py +668 -0
  19. frogml_storage/http/__init__.py +1 -0
  20. frogml_storage/http/http_client.py +83 -0
  21. frogml_storage/logging/__init__.py +1 -0
  22. frogml_storage/logging/_log_config.py +45 -0
  23. frogml_storage/logging/log_utils.py +21 -0
  24. frogml_storage/models/__init__.py +1 -0
  25. frogml_storage/models/_download_context.py +54 -0
  26. frogml_storage/models/dataset_manifest.py +13 -0
  27. frogml_storage/models/entity_manifest.py +93 -0
  28. frogml_storage/models/frogml_dataset_version.py +21 -0
  29. frogml_storage/models/frogml_entity_type_info.py +50 -0
  30. frogml_storage/models/frogml_entity_version.py +34 -0
  31. frogml_storage/models/frogml_model_version.py +21 -0
  32. frogml_storage/models/model_manifest.py +60 -0
  33. frogml_storage/models/serialization_metadata.py +15 -0
  34. frogml_storage/utils/__init__.py +12 -0
  35. frogml_storage/utils/_environment.py +21 -0
  36. frogml_storage/utils/_input_checks_utility.py +104 -0
  37. frogml_storage/utils/_storage_utils.py +15 -0
  38. frogml_storage/utils/_url_utils.py +27 -0
  39. qwak/__init__.py +1 -1
  40. qwak/clients/batch_job_management/client.py +39 -0
  41. qwak/clients/instance_template/client.py +6 -4
  42. qwak/clients/prompt_manager/model_descriptor_mapper.py +21 -19
  43. qwak/feature_store/_common/artifact_utils.py +3 -3
  44. qwak/feature_store/data_sources/base.py +4 -4
  45. qwak/feature_store/data_sources/batch/athena.py +3 -3
  46. qwak/feature_store/feature_sets/streaming.py +3 -3
  47. qwak/feature_store/feature_sets/streaming_backfill.py +1 -1
  48. qwak/feature_store/online/client.py +6 -6
  49. qwak/feature_store/sinks/streaming/factory.py +1 -1
  50. qwak/inner/build_logic/phases/phase_010_fetch_model/fetch_strategy_manager/strategy/git/git_strategy.py +3 -3
  51. qwak/inner/di_configuration/account.py +23 -24
  52. qwak/inner/tool/auth.py +2 -2
  53. qwak/llmops/provider/openai/provider.py +3 -3
  54. qwak/model/tools/adapters/output.py +1 -1
  55. qwak/model/utils/feature_utils.py +12 -8
  56. qwak/model_loggers/artifact_logger.py +7 -7
  57. qwak/tools/logger/logger.py +1 -1
  58. qwak_core-0.4.274.dist-info/METADATA +415 -0
  59. {qwak_core-0.4.272.dist-info → qwak_core-0.4.274.dist-info}/RECORD +61 -25
  60. qwak_services_mock/mocks/batch_job_manager_service.py +24 -1
  61. _qwak_proto/__init__.py +0 -0
  62. _qwak_proto/qwak/__init__.py +0 -0
  63. qwak_core-0.4.272.dist-info/METADATA +0 -53
  64. {qwak_core-0.4.272.dist-info → qwak_core-0.4.274.dist-info}/WHEEL +0 -0
@@ -0,0 +1,70 @@
1
+ from typing import Optional
2
+
3
+ from frogml_storage.constants import (
4
+ FROG_ML_CONFIG_ACCESS_TOKEN,
5
+ FROG_ML_CONFIG_ARTIFACTORY_URL,
6
+ FROG_ML_CONFIG_PASSWORD,
7
+ FROG_ML_CONFIG_USER,
8
+ SERVER_ID,
9
+ )
10
+
11
+
12
+ class AuthConfig(object):
13
+ def __init__(
14
+ self,
15
+ artifactory_url: Optional[str] = None,
16
+ access_token: Optional[str] = None,
17
+ user: Optional[str] = None,
18
+ password: Optional[str] = None,
19
+ server_id: Optional[str] = None,
20
+ ) -> None:
21
+ self.artifactory_url = artifactory_url
22
+ self.user = user
23
+ self.password = password
24
+ self.access_token = access_token
25
+ self.server_id = server_id
26
+
27
+ def to_json(self):
28
+ include_keys = [
29
+ FROG_ML_CONFIG_ARTIFACTORY_URL,
30
+ FROG_ML_CONFIG_USER,
31
+ FROG_ML_CONFIG_PASSWORD,
32
+ FROG_ML_CONFIG_ACCESS_TOKEN,
33
+ SERVER_ID,
34
+ ]
35
+ return {
36
+ key: getattr(self, key)
37
+ for key in include_keys
38
+ if getattr(self, key) is not None
39
+ }
40
+
41
+ @classmethod
42
+ def by_access_token(cls, artifactory_url: str, access_token: str) -> "AuthConfig":
43
+ return cls(
44
+ artifactory_url=artifactory_url,
45
+ access_token=access_token,
46
+ )
47
+
48
+ @classmethod
49
+ def by_basic_auth(
50
+ cls, artifactory_url: str, user: str, password: str
51
+ ) -> "AuthConfig":
52
+ return cls(
53
+ artifactory_url=artifactory_url,
54
+ user=user,
55
+ password=password,
56
+ )
57
+
58
+ @classmethod
59
+ def by_server_id(cls, server_id: str) -> "AuthConfig":
60
+ return cls(server_id=server_id)
61
+
62
+ @classmethod
63
+ def from_dict(cls, data: dict) -> "AuthConfig":
64
+ return cls(
65
+ artifactory_url=data.get(FROG_ML_CONFIG_ARTIFACTORY_URL),
66
+ access_token=data.get(FROG_ML_CONFIG_ACCESS_TOKEN),
67
+ server_id=data.get(SERVER_ID),
68
+ user=data.get(FROG_ML_CONFIG_USER),
69
+ password=data.get(FROG_ML_CONFIG_PASSWORD),
70
+ )
@@ -0,0 +1,22 @@
1
+ from typing import Optional
2
+
3
+
4
+ class LoginArguments(object):
5
+ isAnonymous: bool = False
6
+ server_id: Optional[str] = None
7
+ username: Optional[str] = None
8
+ password: Optional[str] = None
9
+ access_token: Optional[str] = None
10
+ artifactory_url: Optional[str] = None
11
+
12
+ def __eq__(self, other):
13
+ if not isinstance(other, LoginArguments):
14
+ return False
15
+ return (
16
+ self.isAnonymous == other.isAnonymous
17
+ and self.server_id == other.server_id
18
+ and self.username == other.username
19
+ and self.password == other.password
20
+ and self.access_token == other.access_token
21
+ and self.artifactory_url == other.artifactory_url
22
+ )
@@ -0,0 +1,17 @@
1
+ from ._authentication_utils import (
2
+ get_credentials,
3
+ get_frogml_configuration,
4
+ parse_cli_config_server,
5
+ read_jfrog_cli_config,
6
+ get_encrypted_password,
7
+ save_auth_config,
8
+ get_list_of_servers_from_config,
9
+ read_frogml_config,
10
+ )
11
+ from ._login_checks_utils import (
12
+ login_input_checks,
13
+ is_login_without_params,
14
+ is_username_password_login,
15
+ is_access_token_login,
16
+ is_anonymous_login,
17
+ )
@@ -0,0 +1,281 @@
1
+ import http
2
+ import json
3
+ import os
4
+ from typing import Optional, Tuple, Union, List
5
+
6
+ import requests
7
+ from requests.auth import AuthBase, HTTPBasicAuth
8
+
9
+ from frogml_storage.utils import join_url
10
+ from frogml_storage.artifactory import ArtifactoryApi
11
+ from frogml_storage.authentication.models import (
12
+ BearerAuth,
13
+ EmptyAuth,
14
+ AuthConfig,
15
+ LoginArguments,
16
+ )
17
+ from frogml_storage.constants import (
18
+ CONFIG_FILE_PATH,
19
+ FROG_ML_CONFIG_ACCESS_TOKEN,
20
+ FROG_ML_CONFIG_ARTIFACTORY_URL,
21
+ FROG_ML_CONFIG_PASSWORD,
22
+ FROG_ML_CONFIG_USER,
23
+ JF_ACCESS_TOKEN,
24
+ JF_URL,
25
+ JFROG_CLI_CONFIG_ACCESS_TOKEN,
26
+ JFROG_CLI_CONFIG_ARTIFACTORY_URL,
27
+ JFROG_CLI_CONFIG_FILE_PATH,
28
+ JFROG_CLI_CONFIG_PASSWORD,
29
+ JFROG_CLI_CONFIG_URL,
30
+ JFROG_CLI_CONFIG_USER,
31
+ SERVER_ID,
32
+ )
33
+ from frogml_storage.logging import logger
34
+
35
+
36
+ def read_jfrog_cli_config() -> Union[dict, None]:
37
+ try:
38
+ with open(JFROG_CLI_CONFIG_FILE_PATH, "r") as file:
39
+ config_data = json.load(file)
40
+ return config_data
41
+ except FileNotFoundError:
42
+ logger.debug("JFrog cli config file was not found.")
43
+ return None
44
+ except json.JSONDecodeError as e:
45
+ print(f"JFrog cli config file is not a valid JSON {e}.")
46
+ return None
47
+
48
+
49
+ def read_frogml_config() -> Union[dict, None]:
50
+ try:
51
+ with open(CONFIG_FILE_PATH, "r") as file:
52
+ config_data = json.load(file)
53
+ return config_data
54
+ except FileNotFoundError:
55
+ logger.debug("FrogMl config file was not found.")
56
+ return None
57
+ except json.JSONDecodeError as e:
58
+ print(f"FrogMl config file is not a valid JSON {e}.")
59
+ return None
60
+
61
+
62
+ def parse_cli_config_server(server_config: dict) -> Union[LoginArguments, None]:
63
+ login_args = LoginArguments()
64
+ login_args.server_id = server_config.get(SERVER_ID)
65
+
66
+ if JFROG_CLI_CONFIG_ARTIFACTORY_URL in server_config:
67
+ login_args.artifactory_url = server_config.get(JFROG_CLI_CONFIG_ARTIFACTORY_URL)
68
+ elif (
69
+ JFROG_CLI_CONFIG_URL in server_config
70
+ and server_config.get(JFROG_CLI_CONFIG_URL) is not None
71
+ ):
72
+ login_args.artifactory_url = join_url(
73
+ server_config[JFROG_CLI_CONFIG_URL], "artifactory"
74
+ )
75
+ else:
76
+ logger.debug(
77
+ "Invalid JFrog CLI file, expected either artifactoryUrl or url in jfrog cli config file"
78
+ )
79
+ return None
80
+
81
+ if JFROG_CLI_CONFIG_ACCESS_TOKEN in server_config:
82
+ login_args.access_token = server_config.get(JFROG_CLI_CONFIG_ACCESS_TOKEN)
83
+ elif (
84
+ JFROG_CLI_CONFIG_USER in server_config
85
+ and JFROG_CLI_CONFIG_PASSWORD in server_config
86
+ ):
87
+ login_args.username = server_config.get(JFROG_CLI_CONFIG_USER)
88
+ login_args.password = server_config.get(JFROG_CLI_CONFIG_PASSWORD)
89
+ else:
90
+ logger.debug(
91
+ "Expected either accessToken or user/password in jfrog cli config file"
92
+ )
93
+ return None
94
+
95
+ return login_args
96
+
97
+
98
+ def get_frogml_configuration() -> Union[LoginArguments, None]:
99
+ frog_ml_config = read_frogml_config()
100
+ if (
101
+ frog_ml_config is not None
102
+ and frog_ml_config.get("servers") is not None
103
+ and len(frog_ml_config["servers"]) > 0
104
+ ):
105
+ server_config = frog_ml_config["servers"][0]
106
+ login_args = LoginArguments()
107
+ if FROG_ML_CONFIG_ARTIFACTORY_URL in server_config:
108
+ login_args.artifactory_url = server_config.get(
109
+ FROG_ML_CONFIG_ARTIFACTORY_URL
110
+ )
111
+ else:
112
+ logger.debug(
113
+ "Invalid FrogMl authentication file, expected either artifactory_url in FrogMl authentication file"
114
+ )
115
+ return None
116
+
117
+ if FROG_ML_CONFIG_ACCESS_TOKEN in server_config:
118
+ login_args.access_token = server_config.get(FROG_ML_CONFIG_ACCESS_TOKEN)
119
+ elif (
120
+ FROG_ML_CONFIG_USER in server_config
121
+ and FROG_ML_CONFIG_PASSWORD in server_config
122
+ ):
123
+ login_args.username = server_config.get(FROG_ML_CONFIG_USER)
124
+ login_args.password = server_config.get(FROG_ML_CONFIG_PASSWORD)
125
+ elif (
126
+ FROG_ML_CONFIG_USER in server_config
127
+ and FROG_ML_CONFIG_PASSWORD not in server_config
128
+ or (
129
+ FROG_ML_CONFIG_USER not in server_config
130
+ and FROG_ML_CONFIG_PASSWORD in server_config
131
+ )
132
+ ):
133
+ logger.debug(
134
+ "Invalid FrogMl authentication file, username or password is missing in FrogMl authentication file"
135
+ )
136
+ return None
137
+ elif (
138
+ login_args.username is None
139
+ and login_args.password is None
140
+ and login_args.access_token is None
141
+ ):
142
+ login_args.isAnonymous = True
143
+ return login_args
144
+ else:
145
+ return None
146
+
147
+
148
+ def get_encrypted_password(
149
+ auth_config: AuthConfig, auth_token: AuthBase
150
+ ) -> Optional[str]:
151
+ try:
152
+ response = ArtifactoryApi(
153
+ auth_config.artifactory_url, auth_token
154
+ ).encrypt_password()
155
+ if response.status_code != http.HTTPStatus.OK:
156
+ logger.debug(
157
+ f"Expected {http.HTTPStatus.OK} status but got {response.status_code} "
158
+ f"when using url {auth_config.artifactory_url}"
159
+ )
160
+ print("Error while trying to encrypt password.")
161
+ return None
162
+ return response.text
163
+ except requests.exceptions.RequestException as e:
164
+ print(f"Error while trying to encrypt password: {e}.")
165
+ return None
166
+
167
+
168
+ def save_auth_config(auth_config: AuthConfig) -> None:
169
+ file_content: dict[str, list] = {}
170
+ file_content.setdefault("servers", []).append(auth_config.to_json())
171
+ os.makedirs(os.path.dirname(CONFIG_FILE_PATH), exist_ok=True)
172
+ with open(CONFIG_FILE_PATH, "w") as file:
173
+ json.dump(file_content, file, indent=2)
174
+
175
+
176
+ def get_credentials(auth_config: Optional[AuthConfig] = None) -> Tuple[str, AuthBase]:
177
+ if not __should_use_file_auth(auth_config):
178
+ __validate_credentials(auth_config)
179
+ return __auth_config_to_auth_tuple(auth_config)
180
+ logger.debug(
181
+ "Login configuration not supplied, attempting to find environment variables"
182
+ )
183
+
184
+ if __should_use_environment_variables():
185
+ return get_environment_variables()
186
+
187
+ logger.debug(
188
+ "Environment variables not supplied, attempting to load configuration from file"
189
+ )
190
+
191
+ if os.path.exists(CONFIG_FILE_PATH):
192
+ return __read_credentials_from_file(CONFIG_FILE_PATH)
193
+ raise ValueError(
194
+ f"Configuration were not provided and configuration file not found in {CONFIG_FILE_PATH},"
195
+ f" either pass configuration in the constructor, add env variables or create the configuration file by "
196
+ f"running `frogml login`"
197
+ )
198
+
199
+
200
+ def __should_use_environment_variables() -> bool:
201
+ return os.getenv("JF_URL") is not None
202
+
203
+
204
+ def get_environment_variables() -> Tuple[str, AuthBase]:
205
+ auth_config: AuthConfig = AuthConfig(
206
+ artifactory_url=os.getenv(JF_URL),
207
+ access_token=os.getenv(JF_ACCESS_TOKEN),
208
+ )
209
+
210
+ return __auth_config_to_auth_tuple(auth_config)
211
+
212
+
213
+ def __should_use_file_auth(credentials: Optional[AuthConfig] = None) -> bool:
214
+ return credentials is None or (
215
+ credentials.artifactory_url is None
216
+ and credentials.user is None
217
+ and credentials.password is None
218
+ and credentials.access_token is None
219
+ )
220
+
221
+
222
+ def __validate_credentials(credentials: Optional[AuthConfig]) -> None:
223
+ if credentials is None:
224
+ raise ValueError("Credentials must be provided.")
225
+ if credentials.artifactory_url is None:
226
+ raise ValueError("Credentials must contain artifactory url.")
227
+ return None
228
+
229
+
230
+ def __read_credentials_from_file(file_path: str) -> Tuple[str, AuthBase]:
231
+ try:
232
+ with open(file_path, "r") as file:
233
+ config_content: dict = json.load(file)
234
+ servers = config_content.get("servers")
235
+ if servers is None or len(servers) == 0:
236
+ raise ValueError(
237
+ "Configuration file was found but it's empty, failing authentication"
238
+ )
239
+ server = servers[0]
240
+ return __auth_config_to_auth_tuple(AuthConfig.from_dict(server))
241
+ except json.JSONDecodeError:
242
+ raise ValueError(f"Error when reading {file_path}, please recreate the file.")
243
+
244
+
245
+ def __auth_config_to_auth_tuple(
246
+ auth_config: Optional[AuthConfig],
247
+ ) -> Tuple[str, AuthBase]:
248
+
249
+ if auth_config is None:
250
+ raise ValueError("No authentication configuration provided")
251
+
252
+ auth: AuthBase = EmptyAuth()
253
+ if auth_config.access_token is not None:
254
+ auth = BearerAuth(auth_config.access_token)
255
+ elif auth_config.user is not None and auth_config.password is not None:
256
+ auth = HTTPBasicAuth(auth_config.user, auth_config.password)
257
+ elif auth_config.user is not None or auth_config.password is not None:
258
+ raise ValueError("User and password must be provided together")
259
+
260
+ if auth_config.artifactory_url is None:
261
+ raise ValueError("No artifactory URL provided")
262
+
263
+ return auth_config.artifactory_url, auth
264
+
265
+
266
+ def get_list_of_servers_from_config(jfrog_cli_config: dict) -> List[str]:
267
+ if jfrog_cli_config is not None:
268
+ servers = jfrog_cli_config.get("servers")
269
+ if servers is not None:
270
+ return list(map(__map_server_ids, servers))
271
+
272
+ return []
273
+
274
+
275
+ def __map_server_ids(server: dict) -> str:
276
+ server_id = ""
277
+ if server is not None:
278
+ server_id = str(server.get("serverId"))
279
+ if server.get("isDefault") is not None and bool(server.get("isDefault")):
280
+ server_id = server_id + " (Default)"
281
+ return server_id
@@ -0,0 +1,114 @@
1
+ from typing import Optional
2
+
3
+ from frogml_storage.authentication.models import AuthConfig
4
+
5
+
6
+ def login_input_checks(
7
+ url: Optional[str] = None,
8
+ username: Optional[str] = None,
9
+ password: Optional[str] = None,
10
+ token: Optional[str] = None,
11
+ anonymous: bool = False,
12
+ ) -> bool:
13
+ return (
14
+ __is_user_name_password_command(url, username, password, token, anonymous)
15
+ or __is_access_token_command(url, username, password, token, anonymous)
16
+ or __is_anonymous_command(url, username, password, token, anonymous)
17
+ )
18
+
19
+
20
+ def is_login_without_params(
21
+ url: Optional[str] = None,
22
+ username: Optional[str] = None,
23
+ password: Optional[str] = None,
24
+ token: Optional[str] = None,
25
+ anonymous: bool = False,
26
+ ) -> bool:
27
+ return (
28
+ all(params is None for params in [url, username, password, token])
29
+ and not anonymous
30
+ )
31
+
32
+
33
+ def is_username_password_login(
34
+ auth_config: AuthConfig, anonymous: Optional[bool] = False
35
+ ) -> bool:
36
+ return __is_user_name_password_command(
37
+ url=auth_config.artifactory_url,
38
+ username=auth_config.user,
39
+ password=auth_config.password,
40
+ token=auth_config.access_token,
41
+ anonymous=anonymous,
42
+ )
43
+
44
+
45
+ def is_access_token_login(
46
+ auth_config: AuthConfig, anonymous: Optional[bool] = False
47
+ ) -> bool:
48
+ if anonymous is None:
49
+ anonymous = False
50
+ return __is_access_token_command(
51
+ url=auth_config.artifactory_url,
52
+ username=auth_config.user,
53
+ password=auth_config.password,
54
+ token=auth_config.access_token,
55
+ anonymous=anonymous,
56
+ )
57
+
58
+
59
+ def is_anonymous_login(
60
+ auth_config: AuthConfig, anonymous: Optional[bool] = False
61
+ ) -> bool:
62
+ if anonymous is None:
63
+ anonymous = False
64
+ return __is_anonymous_command(
65
+ url=auth_config.artifactory_url,
66
+ username=auth_config.user,
67
+ password=auth_config.password,
68
+ token=auth_config.access_token,
69
+ anonymous=anonymous,
70
+ )
71
+
72
+
73
+ def __is_anonymous_command(
74
+ url: Optional[str],
75
+ username: Optional[str],
76
+ password: Optional[str],
77
+ token: Optional[str],
78
+ anonymous: bool,
79
+ ) -> bool:
80
+ return (
81
+ anonymous
82
+ and all(params is None for params in [username, password, token])
83
+ and url is not None
84
+ )
85
+
86
+
87
+ def __is_access_token_command(
88
+ url: Optional[str],
89
+ username: Optional[str],
90
+ password: Optional[str],
91
+ token: Optional[str],
92
+ anonymous: bool,
93
+ ) -> bool:
94
+ if anonymous:
95
+ return False
96
+ return all(params is None for params in [username, password]) and all(
97
+ params is not None for params in [url, token]
98
+ )
99
+
100
+
101
+ def __is_user_name_password_command(
102
+ url: Optional[str],
103
+ username: Optional[str],
104
+ password: Optional[str],
105
+ token: Optional[str],
106
+ anonymous: Optional[bool] = False,
107
+ ) -> bool:
108
+ return (
109
+ not anonymous
110
+ and url is not None
111
+ and username is not None
112
+ and password is not None
113
+ and token is None
114
+ )
@@ -0,0 +1,140 @@
1
+ from abc import ABC, abstractmethod
2
+ from typing import Dict, List, Optional, Union
3
+
4
+ from frogml_storage.models.frogml_dataset_version import FrogMLDatasetVersion
5
+ from frogml_storage.models.frogml_model_version import FrogMLModelVersion
6
+ from frogml_storage.models.serialization_metadata import SerializationMetadata
7
+
8
+
9
+ class BaseStorage(ABC):
10
+ """
11
+ Repository storage to download or store model | dataset artifacts,
12
+ metrics and relation between these in an Artifactory repository.
13
+ """
14
+
15
+ @abstractmethod
16
+ def upload_model_version(
17
+ self,
18
+ repository: str,
19
+ model_name: str,
20
+ model_path: str,
21
+ model_type: Union[SerializationMetadata, Dict],
22
+ namespace: Optional[str] = None,
23
+ version: Optional[str] = None,
24
+ properties: Optional[dict[str, str]] = None,
25
+ dependencies_files_paths: Optional[List[str]] = None,
26
+ code_archive_file_path: Optional[str] = None,
27
+ ) -> FrogMLModelVersion:
28
+ """Upload model to a repository in Artifactory. Uploaded models should be stored with the following layout:
29
+ ├── REPO
30
+ ├── models
31
+ ├── ${NAMESPACE}
32
+ ├── ${MODEL_NAME}
33
+ ├── ${MODEL_VERSION}
34
+ ├── model-manifest.json
35
+ ├── model
36
+ ├── model.pkl
37
+ ├── evidence.json
38
+ ├── ...
39
+ ├── code
40
+ ├── code.zip
41
+ ├── requirements.txt
42
+ :param repository: the repository to upload the model to
43
+ :param model_name: the name of the model
44
+ :param model_path: the source path of the model
45
+ :param model_type: the type of the model (PyTorch, HuggingFace, Catboost)
46
+ :param namespace: the namespace to upload the model to
47
+ :param version: the version of the model
48
+ :param properties: tags to associate with the model
49
+ :param dependencies_files_paths: the list of dependencies files paths
50
+ :param code_archive_file_path: the path to the code archive file
51
+ """
52
+ pass
53
+
54
+ @abstractmethod
55
+ def download_model_version(
56
+ self,
57
+ repository: str,
58
+ model_name: str,
59
+ version: str,
60
+ target_path: str,
61
+ namespace: Optional[str] = None,
62
+ ) -> None:
63
+ """Downloads a model from an Artifactory repository
64
+ :param repository: the repository to download the model from
65
+ :param model_name: the name of the model to download
66
+ :param version: the version of the model to download
67
+ :param target_path: the target local path to store the model in
68
+ :param namespace: the namespace of the model to download
69
+
70
+ """
71
+ pass
72
+
73
+ def download_model_single_artifact(
74
+ self,
75
+ repository: str,
76
+ model_name: str,
77
+ version: str,
78
+ target_path: str,
79
+ source_artifact_path: str,
80
+ namespace: Optional[str] = None,
81
+ ) -> None:
82
+ """Downloads an artifact from an Artifactory repository
83
+ :param repository: the repository to download the artifact from
84
+ :param model_name: the model to download artifact from
85
+ :param version: the model's version to download artifact from
86
+ :param target_path: the target local path to store the artifact in
87
+ :param source_artifact_path: the path of the artifact under the model's version directory
88
+ :param namespace: the namespace of the artifact
89
+ """
90
+ pass
91
+
92
+ @abstractmethod
93
+ def upload_dataset_version(
94
+ self,
95
+ repository: str,
96
+ dataset_name: str,
97
+ source_path: str,
98
+ namespace: Optional[str] = None,
99
+ version: Optional[str] = None,
100
+ tags: Optional[dict[str, str]] = None,
101
+ ) -> FrogMLDatasetVersion:
102
+ """Uploads a dataset to a repository in Artifactory. Uploaded datasets should be stored with
103
+ the following layout:
104
+ ├── REPO
105
+ ├── datasets
106
+ ├── ${NAMESPACE}
107
+ ├── ${DATASET_NAME}
108
+ ├── ${DATASET_VERSION}
109
+ ├── dataset-manifest.json
110
+ ├── dataset
111
+ ├── cli_docs_1.csv
112
+ ├── cli_docs_2.csv
113
+ ├── ...
114
+ :param repository: the repository to upload the dataset to
115
+ :param dataset_name: the name of the dataset
116
+ :param source_path: the source path of the dataset
117
+ :param namespace: the namespace to upload the dataset to
118
+ :param version: the version of the dataset
119
+ :param tags: tags to associate with the dataset
120
+ """
121
+ pass
122
+
123
+ @abstractmethod
124
+ def download_dataset_version(
125
+ self,
126
+ repository: str,
127
+ dataset_name: str,
128
+ version: str,
129
+ target_path: str,
130
+ namespace: Optional[str] = None,
131
+ ) -> None:
132
+ """Downloads a dataset from an Artifactory repository
133
+ :param repository: the repository to download the dataset from
134
+ :param dataset_name: the name of the dataset to download
135
+ :param version: the version of the dataset to download
136
+ :param target_path: the target local path to store the dataset in
137
+ :param namespace: the namespace of the dataset to download
138
+
139
+ """
140
+ pass
@@ -0,0 +1,56 @@
1
+ import os
2
+
3
+ home_dir = os.path.expanduser("~")
4
+
5
+ JFROG_CLI_CONFIG_FILE_PATH = os.path.join(home_dir, ".jfrog", "jfrog-cli.conf.v6")
6
+ CONFIG_FILE_PATH = os.path.join(home_dir, ".frogml", "config.json")
7
+
8
+ FROG_ML_CONFIG_USER = "user"
9
+ FROG_ML_CONFIG_ARTIFACTORY_URL = "artifactory_url"
10
+ FROG_ML_CONFIG_PASSWORD = "password" # nosec B105
11
+ FROG_ML_CONFIG_ACCESS_TOKEN = "access_token" # nosec B105
12
+ FROG_ML_DEFAULT_HTTP_THREADS_COUNT = 5
13
+ FROG_ML_MAX_CHARS_FOR_NAME = 60
14
+
15
+ SERVER_ID = "server_id"
16
+
17
+ JFROG_CLI_CONFIG_ARTIFACTORY_URL = "artifactoryUrl"
18
+ JFROG_CLI_CONFIG_URL = "url"
19
+ JFROG_CLI_CONFIG_USER = "user"
20
+ JFROG_CLI_CONFIG_PASSWORD = "password" # nosec B105
21
+ JFROG_CLI_CONFIG_ACCESS_TOKEN = "accessToken" # nosec B105
22
+
23
+ MODEL = "model"
24
+ ROOT_FROGML_MODEL_UI_DIRECTORY = "models"
25
+ MODEL_UI_DIRECTORY = "model"
26
+ MODEL_METADATA_FILE_NAME = "model-manifest.json"
27
+ BODY_PART_MODEL_MANIFEST_STREAM = "modelManifest"
28
+
29
+ DATASET = "dataset"
30
+ ROOT_FROGML_DATASET_UI_DIRECTORY = "datasets"
31
+ DATASET_UI_DIRECTORY = "dataset"
32
+ DATASET_METADATA_FILE_NAME = "dataset-manifest.json"
33
+ BODY_PART_DATASET_MANIFEST_STREAM = "datasetManifest"
34
+
35
+ CHECKSUM_SHA2_HEADER = "X-Checksum-Sha256"
36
+
37
+ JFML_THREAD_COUNT = "JFML_THREAD_COUNT"
38
+ JF_URL = "JF_URL"
39
+ JF_ACCESS_TOKEN = "JF_ACCESS_TOKEN" # nosec B105
40
+
41
+ FROG_ML_IGNORED_FILES = [
42
+ ".DS_Store",
43
+ "CVS",
44
+ ".cvsignore",
45
+ "SCCS",
46
+ "vssver.scc",
47
+ ".svn",
48
+ ".git",
49
+ ".gitignore",
50
+ ".gitattributes",
51
+ ".gitmodules",
52
+ ".gitkeep",
53
+ ".gitconfig",
54
+ MODEL_METADATA_FILE_NAME,
55
+ DATASET_METADATA_FILE_NAME,
56
+ ]