frogml 1.2.50__py3-none-any.whl → 2.0.0__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.
- frogml/__init__.py +1 -1
- frogml/core/clients/batch_job_management/client.py +269 -257
- frogml/core/clients/batch_job_management/executions_config.py +10 -3
- frogml/core/clients/build_orchestrator/build_model_request_getter.py +7 -1
- frogml/core/clients/build_orchestrator/client.py +108 -67
- frogml/core/clients/build_orchestrator/internal_client.py +42 -38
- frogml/core/clients/feature_store/management_client.py +58 -39
- frogml/core/clients/feature_store/operator_client.py +6 -4
- frogml/core/clients/model_group_management/client.py +5 -2
- frogml/core/clients/model_management/client.py +25 -8
- frogml/core/clients/model_version_manager/build_model_version_dto.py +4 -1
- frogml/core/clients/model_version_manager/client.py +67 -68
- frogml/core/exceptions/__init__.py +20 -2
- frogml/core/exceptions/frogml_exception.py +35 -5
- frogml/core/exceptions/frogml_general_build_exception.py +19 -11
- frogml/core/exceptions/frogml_grpc_address_exception.py +15 -4
- frogml/core/exceptions/frogml_http_exception.py +3 -1
- frogml/core/exceptions/frogml_login_exception.py +16 -5
- frogml/core/exceptions/frogml_not_found_exception.py +16 -3
- frogml/core/exceptions/frogml_remote_build_failed.py +1 -1
- frogml/core/exceptions/frogml_token_exception.py +17 -5
- frogml/core/exceptions/grpc_status_mapping.py +43 -0
- frogml/core/inner/build_logic/phases/phase_010_fetch_model/fetch_strategy_manager/strategy/git/git_strategy.py +10 -2
- frogml/core/inner/build_logic/phases/phase_010_fetch_model/pre_fetch_validation_step.py +3 -2
- frogml/core/inner/build_logic/phases/phase_020_remote_register_frogml_build/upload_step.py +13 -10
- frogml/core/inner/build_logic/run_handlers/programmatic_phase_run_handler.py +8 -3
- frogml/core/inner/build_logic/tools/files.py +1 -2
- frogml/core/inner/model_loggers_utils.py +21 -8
- frogml/core/inner/tool/auth/auth_client.py +1 -1
- frogml/core/inner/tool/grpc/grpc_try_wrapping.py +51 -72
- frogml/core/inner/tool/protobuf_factory.py +8 -2
- frogml/sdk/frogml_client/client.py +29 -10
- frogml/sdk/model/adapters/input_adapters/numpy_input_adapter.py +6 -1
- frogml/sdk/model/adapters/output_adapters/numpy_output_adapter.py +4 -1
- frogml/sdk/model/decorators/api.py +6 -1
- frogml/sdk/model/tools/adapters/output.py +6 -2
- frogml/sdk/model_version/catboost/__init__.py +4 -1
- frogml/sdk/model_version/huggingface/__init__.py +4 -1
- frogml/sdk/model_version/model_loggers/catboost_model_version_manager.py +4 -1
- frogml/sdk/model_version/model_loggers/huggingface_model_version_manager.py +10 -2
- frogml/sdk/model_version/model_loggers/onnx_model_version_manager.py +4 -1
- frogml/sdk/model_version/model_loggers/pytorch_model_version_manager.py +4 -1
- frogml/sdk/model_version/model_loggers/scikit_learn_model_version_manager.py +4 -1
- frogml/sdk/model_version/onnx/__init__.py +4 -1
- frogml/sdk/model_version/pytorch/__init__.py +4 -1
- frogml/sdk/model_version/scikit_learn/__init__.py +4 -1
- frogml/sdk/model_version/utils/jml/customer_client.py +1 -1
- frogml/sdk/model_version/utils/storage.py +4 -1
- frogml/sdk/model_version/utils/validations.py +10 -2
- {frogml-1.2.50.dist-info → frogml-2.0.0.dist-info}/METADATA +1 -1
- {frogml-1.2.50.dist-info → frogml-2.0.0.dist-info}/RECORD +58 -61
- frogml_services_mock/mocks/batch_job_manager_service.py +11 -9
- frogml_services_mock/mocks/build_orchestrator_service_api.py +4 -0
- frogml_services_mock/mocks/ecosystem_service_api.py +1 -2
- frogml_services_mock/mocks/model_group_management_service.py +20 -9
- frogml_services_mock/mocks/model_version_manager_service.py +3 -1
- frogml_services_mock/mocks/project_manager_service.py +6 -2
- frogml/core/exceptions/frogml_decode_exception.py +0 -7
- frogml/core/exceptions/frogml_external_exception.py +0 -11
- frogml/core/exceptions/frogml_load_model_failed_exception.py +0 -10
- frogml/core/exceptions/quiet_error.py +0 -22
- {frogml-1.2.50.dist-info → frogml-2.0.0.dist-info}/WHEEL +0 -0
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from typing import Any, Callable
|
|
2
|
+
|
|
1
3
|
from dependency_injector.wiring import Provide
|
|
2
4
|
from frogml._proto.qwak.feature_store.entities.entity_pb2 import EntitySpec
|
|
3
5
|
from frogml._proto.qwak.feature_store.entities.entity_service_pb2 import (
|
|
@@ -93,7 +95,8 @@ class FeatureRegistryClient:
|
|
|
93
95
|
)
|
|
94
96
|
|
|
95
97
|
@grpc_try_catch_wrapper(
|
|
96
|
-
"Failed to get a presigned url",
|
|
98
|
+
error_message="Failed to get a presigned url",
|
|
99
|
+
operation="Get Feature Store Presigned URL",
|
|
97
100
|
)
|
|
98
101
|
def get_datasource_source_code_presign_url(
|
|
99
102
|
self, ds_name: str, repository_name: str
|
|
@@ -105,7 +108,8 @@ class FeatureRegistryClient:
|
|
|
105
108
|
)
|
|
106
109
|
|
|
107
110
|
@grpc_try_catch_wrapper(
|
|
108
|
-
"Failed to list features",
|
|
111
|
+
error_message="Failed to list features",
|
|
112
|
+
operation="List Feature Store Feature Sets",
|
|
109
113
|
)
|
|
110
114
|
def list_feature_sets(self) -> ListFeatureSetsResponse:
|
|
111
115
|
"""
|
|
@@ -130,7 +134,8 @@ class FeatureRegistryClient:
|
|
|
130
134
|
)
|
|
131
135
|
|
|
132
136
|
@grpc_try_catch_wrapper(
|
|
133
|
-
"Failed to delete feature",
|
|
137
|
+
error_message="Failed to delete feature",
|
|
138
|
+
operation="Delete Feature Store Feature Set",
|
|
134
139
|
)
|
|
135
140
|
def delete_feature_set(self, feature_set_id: str) -> DeleteFeatureSetResponse:
|
|
136
141
|
"""
|
|
@@ -144,7 +149,7 @@ class FeatureRegistryClient:
|
|
|
144
149
|
)
|
|
145
150
|
|
|
146
151
|
@grpc_try_catch_wrapper(
|
|
147
|
-
"Failed to delete entity",
|
|
152
|
+
error_message="Failed to delete entity", operation="Delete Feature Store Entity"
|
|
148
153
|
)
|
|
149
154
|
def delete_entity(self, entity_id: str) -> DeleteEntityResponse:
|
|
150
155
|
"""
|
|
@@ -158,7 +163,8 @@ class FeatureRegistryClient:
|
|
|
158
163
|
)
|
|
159
164
|
|
|
160
165
|
@grpc_try_catch_wrapper(
|
|
161
|
-
"Failed to delete data source",
|
|
166
|
+
error_message="Failed to delete data source",
|
|
167
|
+
operation="Delete Feature Store Data Source",
|
|
162
168
|
)
|
|
163
169
|
def delete_data_source(self, data_source_id: str) -> DeleteDataSourceResponse:
|
|
164
170
|
"""
|
|
@@ -172,7 +178,7 @@ class FeatureRegistryClient:
|
|
|
172
178
|
)
|
|
173
179
|
|
|
174
180
|
@grpc_try_catch_wrapper(
|
|
175
|
-
"Failed to run feature",
|
|
181
|
+
error_message="Failed to run feature", operation="Run Feature Store Feature Set"
|
|
176
182
|
)
|
|
177
183
|
def run_feature_set(self, feature_set_name: str) -> RunBatchFeatureSetResponse:
|
|
178
184
|
"""
|
|
@@ -187,7 +193,8 @@ class FeatureRegistryClient:
|
|
|
187
193
|
)
|
|
188
194
|
|
|
189
195
|
@grpc_try_catch_wrapper(
|
|
190
|
-
"Failed to run feature",
|
|
196
|
+
error_message="Failed to run feature",
|
|
197
|
+
operation="Run Feature Store Parquet Batch Feature Set",
|
|
191
198
|
)
|
|
192
199
|
def run_parquet_batch_feature_set(
|
|
193
200
|
self, feature_set_name: str, parquet_location: str, timestamp_column: str
|
|
@@ -210,7 +217,7 @@ class FeatureRegistryClient:
|
|
|
210
217
|
)
|
|
211
218
|
|
|
212
219
|
@grpc_try_catch_wrapper(
|
|
213
|
-
"Failed to update entity",
|
|
220
|
+
error_message="Failed to update entity", operation="Update Feature Store Entity"
|
|
214
221
|
)
|
|
215
222
|
def update_entity(
|
|
216
223
|
self, entity_id: str, proto_entity_spec: EntitySpec
|
|
@@ -227,7 +234,7 @@ class FeatureRegistryClient:
|
|
|
227
234
|
)
|
|
228
235
|
|
|
229
236
|
@grpc_try_catch_wrapper(
|
|
230
|
-
"Failed to create entity",
|
|
237
|
+
error_message="Failed to create entity", operation="Create Feature Store Entity"
|
|
231
238
|
)
|
|
232
239
|
def create_entity(self, proto_entity_spec: EntitySpec) -> CreateEntityResponse:
|
|
233
240
|
"""
|
|
@@ -241,7 +248,7 @@ class FeatureRegistryClient:
|
|
|
241
248
|
)
|
|
242
249
|
|
|
243
250
|
@grpc_try_catch_wrapper(
|
|
244
|
-
"Failed to list entities",
|
|
251
|
+
error_message="Failed to list entities", operation="List Feature Store Entities"
|
|
245
252
|
)
|
|
246
253
|
def list_entities(self) -> ListEntitiesResponse:
|
|
247
254
|
"""
|
|
@@ -251,7 +258,8 @@ class FeatureRegistryClient:
|
|
|
251
258
|
return self._entity_service.ListEntities(ListEntitiesRequest())
|
|
252
259
|
|
|
253
260
|
@grpc_try_catch_wrapper(
|
|
254
|
-
"Failed to list data sources",
|
|
261
|
+
error_message="Failed to list data sources",
|
|
262
|
+
operation="List Feature Store Data Sources",
|
|
255
263
|
)
|
|
256
264
|
def list_data_sources(self) -> ListDataSourcesResponse:
|
|
257
265
|
"""
|
|
@@ -278,7 +286,8 @@ class FeatureRegistryClient:
|
|
|
278
286
|
)
|
|
279
287
|
|
|
280
288
|
@grpc_try_catch_wrapper(
|
|
281
|
-
"Failed to update data source",
|
|
289
|
+
error_message="Failed to update data source",
|
|
290
|
+
operation="Update Feature Store Data Source",
|
|
282
291
|
)
|
|
283
292
|
def update_data_source(
|
|
284
293
|
self,
|
|
@@ -300,7 +309,8 @@ class FeatureRegistryClient:
|
|
|
300
309
|
)
|
|
301
310
|
|
|
302
311
|
@grpc_try_catch_wrapper(
|
|
303
|
-
"Failed to create data source",
|
|
312
|
+
error_message="Failed to create data source",
|
|
313
|
+
operation="Create Feature Store Data Source",
|
|
304
314
|
)
|
|
305
315
|
def create_data_source(
|
|
306
316
|
self, proto_data_source: FeatureSetSpec
|
|
@@ -331,7 +341,8 @@ class FeatureRegistryClient:
|
|
|
331
341
|
)
|
|
332
342
|
|
|
333
343
|
@grpc_try_catch_wrapper(
|
|
334
|
-
"Failed to update feature set",
|
|
344
|
+
error_message="Failed to update feature set",
|
|
345
|
+
operation="Update Feature Store Feature Set",
|
|
335
346
|
)
|
|
336
347
|
def update_feature_set(
|
|
337
348
|
self,
|
|
@@ -352,7 +363,8 @@ class FeatureRegistryClient:
|
|
|
352
363
|
)
|
|
353
364
|
|
|
354
365
|
@grpc_try_catch_wrapper(
|
|
355
|
-
"Failed to create feature set",
|
|
366
|
+
error_message="Failed to create feature set",
|
|
367
|
+
operation="Create Feature Store Feature Set",
|
|
356
368
|
)
|
|
357
369
|
def create_feature_set(
|
|
358
370
|
self, proto_feature_set: FeatureSetSpec
|
|
@@ -368,7 +380,9 @@ class FeatureRegistryClient:
|
|
|
368
380
|
)
|
|
369
381
|
|
|
370
382
|
@staticmethod
|
|
371
|
-
def _fetch_by_name(
|
|
383
|
+
def _fetch_by_name(
|
|
384
|
+
extract_function: Callable[[str], Any], name: str, fs_object_type: str
|
|
385
|
+
) -> Any:
|
|
372
386
|
"""
|
|
373
387
|
Args:
|
|
374
388
|
extract_function: function to run on name param
|
|
@@ -384,7 +398,8 @@ class FeatureRegistryClient:
|
|
|
384
398
|
return None
|
|
385
399
|
else:
|
|
386
400
|
raise FrogmlException(
|
|
387
|
-
f"Failed to fetch {fs_object_type} by name
|
|
401
|
+
error_message=f"Failed to fetch {fs_object_type} by name {name}: {e.details()}",
|
|
402
|
+
operation=f"Get Feature Store {fs_object_type.title()}",
|
|
388
403
|
)
|
|
389
404
|
|
|
390
405
|
def get_presigned_url_v1(
|
|
@@ -408,13 +423,13 @@ class FeatureRegistryClient:
|
|
|
408
423
|
).upload_url
|
|
409
424
|
except RpcError as e:
|
|
410
425
|
raise FrogmlException(
|
|
411
|
-
f"Failed to get presigned url for featureset name {feature_set_name}
|
|
412
|
-
|
|
426
|
+
error_message=f"Failed to get presigned url for featureset name {feature_set_name}: {e.details()}",
|
|
427
|
+
operation="Get Feature Store Presigned URL",
|
|
413
428
|
)
|
|
414
429
|
|
|
415
430
|
@grpc_try_catch_wrapper(
|
|
416
|
-
"Failed to get presigned url for data source: {data_source_name}, object name: {object_name}",
|
|
417
|
-
|
|
431
|
+
error_message="Failed to get presigned url for data source: {data_source_name}, object name: {object_name}",
|
|
432
|
+
operation="Get Feature Store Data Source Presigned URL",
|
|
418
433
|
)
|
|
419
434
|
def get_data_source_presigned_url_v1(
|
|
420
435
|
self, data_source_name: str, object_name: str
|
|
@@ -436,8 +451,8 @@ class FeatureRegistryClient:
|
|
|
436
451
|
).upload_url
|
|
437
452
|
|
|
438
453
|
@grpc_try_catch_wrapper(
|
|
439
|
-
"Failed to query scheduling state for Featureset {feature_set_name}",
|
|
440
|
-
|
|
454
|
+
error_message="Failed to query scheduling state for Featureset {feature_set_name}",
|
|
455
|
+
operation="Get Feature Store FeatureSet Scheduling State",
|
|
441
456
|
)
|
|
442
457
|
def get_feature_set_scheduling_state(
|
|
443
458
|
self, feature_set_name: str
|
|
@@ -447,26 +462,26 @@ class FeatureRegistryClient:
|
|
|
447
462
|
)
|
|
448
463
|
|
|
449
464
|
@grpc_try_catch_wrapper(
|
|
450
|
-
"Failed to pause Featureset {feature_set_name}",
|
|
451
|
-
|
|
465
|
+
error_message="Failed to pause Featureset {feature_set_name}",
|
|
466
|
+
operation="Pause Feature Store FeatureSet",
|
|
452
467
|
)
|
|
453
|
-
def pause_feature_set(self, feature_set_name: str):
|
|
468
|
+
def pause_feature_set(self, feature_set_name: str) -> None:
|
|
454
469
|
self._features_service.PauseFeatureset(
|
|
455
470
|
PauseFeaturesetRequest(featureset_name=feature_set_name)
|
|
456
471
|
)
|
|
457
472
|
|
|
458
473
|
@grpc_try_catch_wrapper(
|
|
459
|
-
"Failed to resume Featureset {feature_set_name}",
|
|
460
|
-
|
|
474
|
+
error_message="Failed to resume Featureset {feature_set_name}",
|
|
475
|
+
operation="Resume Feature Store FeatureSet",
|
|
461
476
|
)
|
|
462
|
-
def resume_feature_set(self, feature_set_name: str):
|
|
477
|
+
def resume_feature_set(self, feature_set_name: str) -> None:
|
|
463
478
|
self._features_service.ResumeFeatureset(
|
|
464
479
|
ResumeFeaturesetRequest(featureset_name=feature_set_name)
|
|
465
480
|
)
|
|
466
481
|
|
|
467
482
|
@grpc_try_catch_wrapper(
|
|
468
|
-
"Failed list Featureset versions for Featureset: {featureset_name}",
|
|
469
|
-
|
|
483
|
+
error_message="Failed list Featureset versions for Featureset: {featureset_name}",
|
|
484
|
+
operation="List Feature Store FeatureSet Versions",
|
|
470
485
|
)
|
|
471
486
|
def list_featureset_versions(
|
|
472
487
|
self, featureset_name: str
|
|
@@ -476,10 +491,12 @@ class FeatureRegistryClient:
|
|
|
476
491
|
)
|
|
477
492
|
|
|
478
493
|
@grpc_try_catch_wrapper(
|
|
479
|
-
"Failed to set active version: {version_number} for Featureset: {featureset_name}",
|
|
480
|
-
|
|
494
|
+
error_message="Failed to set active version: {version_number} for Featureset: {featureset_name}",
|
|
495
|
+
operation="Set Feature Store Active FeatureSet Version",
|
|
481
496
|
)
|
|
482
|
-
def set_active_featureset_version(
|
|
497
|
+
def set_active_featureset_version(
|
|
498
|
+
self, featureset_name: str, version_number: int
|
|
499
|
+
) -> None:
|
|
483
500
|
self._features_service.SetActiveFeaturesetVersion(
|
|
484
501
|
SetActiveFeaturesetVersionRequest(
|
|
485
502
|
featureset_name=featureset_name,
|
|
@@ -488,10 +505,12 @@ class FeatureRegistryClient:
|
|
|
488
505
|
)
|
|
489
506
|
|
|
490
507
|
@grpc_try_catch_wrapper(
|
|
491
|
-
"Failed to delete version: {version_number} for Featureset: {featureset_name}",
|
|
492
|
-
|
|
508
|
+
error_message="Failed to delete version: {version_number} for Featureset: {featureset_name}",
|
|
509
|
+
operation="Delete Feature Store FeatureSet Version",
|
|
493
510
|
)
|
|
494
|
-
def delete_featureset_version(
|
|
511
|
+
def delete_featureset_version(
|
|
512
|
+
self, featureset_name: str, version_number: int
|
|
513
|
+
) -> None:
|
|
495
514
|
self._features_service.DeleteFeaturesetVersion(
|
|
496
515
|
DeleteFeaturesetVersionRequest(
|
|
497
516
|
featureset_name=featureset_name,
|
|
@@ -500,8 +519,8 @@ class FeatureRegistryClient:
|
|
|
500
519
|
)
|
|
501
520
|
|
|
502
521
|
@grpc_try_catch_wrapper(
|
|
503
|
-
"Failed to get env to featuresets mapping",
|
|
504
|
-
|
|
522
|
+
error_message="Failed to get env to featuresets mapping",
|
|
523
|
+
operation="Get Feature Store Env To FeatureSets Mapping",
|
|
505
524
|
)
|
|
506
525
|
def get_env_to_featuresets_mapping(self) -> GetEnvToFeatureSetsMappingResponse:
|
|
507
526
|
return self._features_service.GetEnvToFeatureSetsMapping(
|
|
@@ -42,7 +42,8 @@ class FeaturesOperatorClient:
|
|
|
42
42
|
self._v3_client = FeaturesOperatorAsyncServiceStub(grpc_channel)
|
|
43
43
|
|
|
44
44
|
@grpc_try_catch_wrapper(
|
|
45
|
-
"Failed to validate DataSource",
|
|
45
|
+
error_message="Failed to validate DataSource",
|
|
46
|
+
operation="Validate Feature Store DataSource",
|
|
46
47
|
)
|
|
47
48
|
def validate_data_source(
|
|
48
49
|
self,
|
|
@@ -63,7 +64,8 @@ class FeaturesOperatorClient:
|
|
|
63
64
|
return response.request_id
|
|
64
65
|
|
|
65
66
|
@grpc_try_catch_wrapper(
|
|
66
|
-
"Failed to validate FeatureSet",
|
|
67
|
+
error_message="Failed to validate FeatureSet",
|
|
68
|
+
operation="Validate Feature Store FeatureSet",
|
|
67
69
|
)
|
|
68
70
|
def validate_featureset(
|
|
69
71
|
self,
|
|
@@ -87,8 +89,8 @@ class FeaturesOperatorClient:
|
|
|
87
89
|
return response.request_id
|
|
88
90
|
|
|
89
91
|
@grpc_try_catch_wrapper(
|
|
90
|
-
"Failed to fetch validation result",
|
|
91
|
-
|
|
92
|
+
error_message="Failed to fetch validation result",
|
|
93
|
+
operation="Get Feature Store Validation Result",
|
|
92
94
|
)
|
|
93
95
|
def get_result(self, request_handle: str) -> GetValidationResultResponse:
|
|
94
96
|
"""
|
|
@@ -29,7 +29,9 @@ class ModelGroupManagementClient:
|
|
|
29
29
|
ProjectsManagementServiceStub(grpc_channel)
|
|
30
30
|
)
|
|
31
31
|
|
|
32
|
-
@grpc_try_catch_wrapper(
|
|
32
|
+
@grpc_try_catch_wrapper(
|
|
33
|
+
error_message="Failed to create model group", operation="Create Model Group"
|
|
34
|
+
)
|
|
33
35
|
def create_if_not_exists_model_group(
|
|
34
36
|
self: Self, project_key: str
|
|
35
37
|
) -> ModelGroupBriefInfoResponse:
|
|
@@ -43,7 +45,8 @@ class ModelGroupManagementClient:
|
|
|
43
45
|
)
|
|
44
46
|
|
|
45
47
|
@grpc_try_catch_wrapper(
|
|
46
|
-
"Failed to get model group with model_group_id '{model_group_id}' and model_group_name '{model_group_name}'"
|
|
48
|
+
error_message="Failed to get model group with model_group_id '{model_group_id}' and model_group_name '{model_group_name}'",
|
|
49
|
+
operation="Get Model Group",
|
|
47
50
|
)
|
|
48
51
|
def get_model_group(
|
|
49
52
|
self, model_group_id: str = "", model_group_name: str = ""
|
|
@@ -46,7 +46,10 @@ class ModelsManagementClient:
|
|
|
46
46
|
except grpc.RpcError as e:
|
|
47
47
|
if e.code() == grpc.StatusCode.NOT_FOUND and not exception_on_missing:
|
|
48
48
|
return None
|
|
49
|
-
raise FrogmlException(
|
|
49
|
+
raise FrogmlException(
|
|
50
|
+
error_message=f"Failed to get model: {e.details()}",
|
|
51
|
+
operation="Get Model",
|
|
52
|
+
)
|
|
50
53
|
|
|
51
54
|
def get_model_by_uuid(
|
|
52
55
|
self, model_uuid, exception_on_missing: bool = True
|
|
@@ -59,13 +62,18 @@ class ModelsManagementClient:
|
|
|
59
62
|
except grpc.RpcError as e:
|
|
60
63
|
if e.code() == grpc.StatusCode.NOT_FOUND and not exception_on_missing:
|
|
61
64
|
return None
|
|
62
|
-
raise FrogmlException(
|
|
65
|
+
raise FrogmlException(
|
|
66
|
+
error_message=f"Failed to get model: {e.details()}",
|
|
67
|
+
operation="Get Model",
|
|
68
|
+
)
|
|
63
69
|
|
|
64
70
|
def get_model_uuid(self, model_id: str) -> str:
|
|
65
71
|
model: Optional[Model] = self.get_model(model_id)
|
|
66
72
|
return model.uuid
|
|
67
73
|
|
|
68
|
-
@grpc_try_catch_wrapper(
|
|
74
|
+
@grpc_try_catch_wrapper(
|
|
75
|
+
error_message="Failed to create model", operation="Create Model"
|
|
76
|
+
)
|
|
69
77
|
def create_model(
|
|
70
78
|
self,
|
|
71
79
|
project_id: str,
|
|
@@ -87,7 +95,9 @@ class ModelsManagementClient:
|
|
|
87
95
|
)
|
|
88
96
|
)
|
|
89
97
|
|
|
90
|
-
@grpc_try_catch_wrapper(
|
|
98
|
+
@grpc_try_catch_wrapper(
|
|
99
|
+
error_message="Failed to delete model", operation="Delete Model"
|
|
100
|
+
)
|
|
91
101
|
def delete_model(self, project_id: str, model_id: str) -> DeleteModelResponse:
|
|
92
102
|
return self._models_management_service.DeleteModel(
|
|
93
103
|
DeleteModelRequest(model_id=model_id, project_id=project_id)
|
|
@@ -111,22 +121,29 @@ class ModelsManagementClient:
|
|
|
111
121
|
if e.code() == grpc.StatusCode.NOT_FOUND:
|
|
112
122
|
return False
|
|
113
123
|
raise FrogmlException(
|
|
114
|
-
f"Failed to check if model {model_id}
|
|
124
|
+
error_message=f"Failed to check if model {model_id} exists: {e.details()}",
|
|
125
|
+
operation="Check Model Exists",
|
|
115
126
|
)
|
|
116
127
|
|
|
117
|
-
@grpc_try_catch_wrapper(
|
|
128
|
+
@grpc_try_catch_wrapper(
|
|
129
|
+
error_message="Failed to list models metadata", operation="List Models Metadata"
|
|
130
|
+
)
|
|
118
131
|
def list_models_metadata(self, project_id: str) -> ListModelsMetadataResponse:
|
|
119
132
|
return self._models_management_service.ListModelsMetadata(
|
|
120
133
|
ListModelsMetadataRequest(project_id=project_id)
|
|
121
134
|
)
|
|
122
135
|
|
|
123
|
-
@grpc_try_catch_wrapper(
|
|
136
|
+
@grpc_try_catch_wrapper(
|
|
137
|
+
error_message="Failed to list models", operation="List Models"
|
|
138
|
+
)
|
|
124
139
|
def list_models(self, project_id: str) -> ListModelsResponse:
|
|
125
140
|
return self._models_management_service.ListModels(
|
|
126
141
|
ListModelsRequest(project_id=project_id)
|
|
127
142
|
)
|
|
128
143
|
|
|
129
|
-
@grpc_try_catch_wrapper(
|
|
144
|
+
@grpc_try_catch_wrapper(
|
|
145
|
+
error_message="Failed to get model metadata", operation="Get Model Metadata"
|
|
146
|
+
)
|
|
130
147
|
def get_model_metadata(self, model_id: str) -> GetModelMetadataResponse:
|
|
131
148
|
return self._models_management_service.GetModelMetadata(
|
|
132
149
|
GetModelMetadataRequest(model_id=model_id)
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from http import HTTPStatus
|
|
1
2
|
from typing import Optional, List
|
|
2
3
|
from pydantic import BaseModel, model_validator
|
|
3
4
|
from typing_extensions import Self
|
|
@@ -61,7 +62,9 @@ class PodResourcesDTO(BaseModel):
|
|
|
61
62
|
|
|
62
63
|
if fields_set != 1:
|
|
63
64
|
raise FrogmlException(
|
|
64
|
-
"Exactly one of template_spec, cpu_resources, or gpu_resources must be set"
|
|
65
|
+
error_message="Exactly one of template_spec, cpu_resources, or gpu_resources must be set",
|
|
66
|
+
status_code=HTTPStatus.BAD_REQUEST,
|
|
67
|
+
operation="Validate Model Version Pod Resources",
|
|
65
68
|
)
|
|
66
69
|
|
|
67
70
|
return self
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import logging
|
|
2
|
+
from http import HTTPStatus
|
|
2
3
|
from platform import python_version
|
|
3
4
|
from typing import List, Optional, Dict, Union, Tuple
|
|
4
5
|
|
|
5
6
|
from dependency_injector.wiring import Provide
|
|
6
|
-
from grpc import RpcError
|
|
7
7
|
from typing_extensions import Self
|
|
8
8
|
|
|
9
9
|
from frogml._proto.jfml.model_version.v1.artifact_pb2 import Artifact as ArtifactProto
|
|
@@ -116,6 +116,10 @@ class ModelVersionManagerClient:
|
|
|
116
116
|
ml_bom_data=MlBomData(**kwargs),
|
|
117
117
|
)
|
|
118
118
|
|
|
119
|
+
@grpc_try_catch_wrapper(
|
|
120
|
+
error_message="Failed to validate model version '{model_version_name}' for model '{model_name}'",
|
|
121
|
+
operation="Validate Model Version",
|
|
122
|
+
)
|
|
119
123
|
def validate_create_model_version(
|
|
120
124
|
self,
|
|
121
125
|
repository_key: str,
|
|
@@ -128,36 +132,30 @@ class ModelVersionManagerClient:
|
|
|
128
132
|
parameters: Optional[Dict[str, str]] = None,
|
|
129
133
|
metrics: Optional[Dict[str, str]] = None,
|
|
130
134
|
):
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
) = self.convert_artifacts(
|
|
137
|
-
model_artifact, dependency_artifacts, code_artifacts
|
|
138
|
-
)
|
|
139
|
-
|
|
140
|
-
create_model_request = self.__build_create_model_version_request(
|
|
141
|
-
repository_key=repository_key,
|
|
142
|
-
model_name=model_name,
|
|
143
|
-
model_version_name=model_version_name,
|
|
144
|
-
model_version_framework=model_version_framework,
|
|
145
|
-
dry_run=True,
|
|
146
|
-
model_artifacts=model_artifact_proto,
|
|
147
|
-
dependency_artifacts=dependency_artifacts_proto,
|
|
148
|
-
code_artifacts=code_artifacts_proto,
|
|
149
|
-
parameters=parameters,
|
|
150
|
-
metrics=metrics,
|
|
151
|
-
)
|
|
152
|
-
self.__model_version_manager_stub.CreateModelVersion(create_model_request)
|
|
153
|
-
except RpcError as e:
|
|
154
|
-
message = f"Failed to validate model version, details [{e.details()}]"
|
|
155
|
-
raise FrogmlException(message)
|
|
135
|
+
(
|
|
136
|
+
code_artifacts_proto,
|
|
137
|
+
dependency_artifacts_proto,
|
|
138
|
+
model_artifact_proto,
|
|
139
|
+
) = self.convert_artifacts(model_artifact, dependency_artifacts, code_artifacts)
|
|
156
140
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
141
|
+
create_model_request = self.__build_create_model_version_request(
|
|
142
|
+
repository_key=repository_key,
|
|
143
|
+
model_name=model_name,
|
|
144
|
+
model_version_name=model_version_name,
|
|
145
|
+
model_version_framework=model_version_framework,
|
|
146
|
+
dry_run=True,
|
|
147
|
+
model_artifacts=model_artifact_proto,
|
|
148
|
+
dependency_artifacts=dependency_artifacts_proto,
|
|
149
|
+
code_artifacts=code_artifacts_proto,
|
|
150
|
+
parameters=parameters,
|
|
151
|
+
metrics=metrics,
|
|
152
|
+
)
|
|
153
|
+
self.__model_version_manager_stub.CreateModelVersion(create_model_request)
|
|
160
154
|
|
|
155
|
+
@grpc_try_catch_wrapper(
|
|
156
|
+
error_message="Failed to create model version '{model_version_name}' for model '{model_name}'",
|
|
157
|
+
operation="Create Model Version",
|
|
158
|
+
)
|
|
161
159
|
def create_model_version(
|
|
162
160
|
self,
|
|
163
161
|
repository_key: str,
|
|
@@ -170,41 +168,27 @@ class ModelVersionManagerClient:
|
|
|
170
168
|
parameters: Optional[Dict[str, str]] = None,
|
|
171
169
|
metrics: Optional[Dict[str, str]] = None,
|
|
172
170
|
) -> CreateModelVersionResponse:
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
) = self.convert_artifacts(
|
|
179
|
-
model_artifact, dependency_artifacts, code_artifacts
|
|
180
|
-
)
|
|
181
|
-
|
|
182
|
-
create_model_request = self.__build_create_model_version_request(
|
|
183
|
-
repository_key=repository_key,
|
|
184
|
-
model_name=model_name,
|
|
185
|
-
model_version_name=model_version_name,
|
|
186
|
-
model_version_framework=model_version_framework,
|
|
187
|
-
dry_run=False,
|
|
188
|
-
model_artifacts=model_artifact_proto,
|
|
189
|
-
dependency_artifacts=dependency_artifacts_proto,
|
|
190
|
-
code_artifacts=code_artifacts_proto,
|
|
191
|
-
parameters=parameters,
|
|
192
|
-
metrics=metrics,
|
|
193
|
-
)
|
|
194
|
-
create_model_version_response: CreateModelVersionResponse = (
|
|
195
|
-
self.__model_version_manager_stub.CreateModelVersion(
|
|
196
|
-
create_model_request
|
|
197
|
-
)
|
|
198
|
-
)
|
|
199
|
-
|
|
200
|
-
return create_model_version_response
|
|
201
|
-
except RpcError as e:
|
|
202
|
-
message = f"Failed to validate model version, details [{e.details()}]"
|
|
203
|
-
raise FrogmlException(message)
|
|
171
|
+
(
|
|
172
|
+
code_artifacts_proto,
|
|
173
|
+
dependency_artifacts_proto,
|
|
174
|
+
model_artifact_proto,
|
|
175
|
+
) = self.convert_artifacts(model_artifact, dependency_artifacts, code_artifacts)
|
|
204
176
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
177
|
+
create_model_request = self.__build_create_model_version_request(
|
|
178
|
+
repository_key=repository_key,
|
|
179
|
+
model_name=model_name,
|
|
180
|
+
model_version_name=model_version_name,
|
|
181
|
+
model_version_framework=model_version_framework,
|
|
182
|
+
dry_run=False,
|
|
183
|
+
model_artifacts=model_artifact_proto,
|
|
184
|
+
dependency_artifacts=dependency_artifacts_proto,
|
|
185
|
+
code_artifacts=code_artifacts_proto,
|
|
186
|
+
parameters=parameters,
|
|
187
|
+
metrics=metrics,
|
|
188
|
+
)
|
|
189
|
+
return self.__model_version_manager_stub.CreateModelVersion(
|
|
190
|
+
create_model_request
|
|
191
|
+
)
|
|
208
192
|
|
|
209
193
|
@staticmethod
|
|
210
194
|
def convert_artifacts(
|
|
@@ -231,7 +215,6 @@ class ModelVersionManagerClient:
|
|
|
231
215
|
)
|
|
232
216
|
return code_artifacts_proto, dependency_artifacts_proto, model_artifact_proto
|
|
233
217
|
|
|
234
|
-
@grpc_try_catch_wrapper("Failed to promote model version to build")
|
|
235
218
|
def promote_to_build(
|
|
236
219
|
self: Self,
|
|
237
220
|
build_config: BuildConfigDTO,
|
|
@@ -248,15 +231,31 @@ class ModelVersionManagerClient:
|
|
|
248
231
|
:return The build ID of the promoted model version
|
|
249
232
|
:raises FrogmlException: If the promotion fails or parameters are invalid
|
|
250
233
|
"""
|
|
251
|
-
|
|
252
|
-
is_missing_required_model_version_params: bool = not model_version_id and (
|
|
234
|
+
is_missing_required_params = not model_version_id and (
|
|
253
235
|
not model_id or not model_version_name
|
|
254
236
|
)
|
|
255
|
-
if
|
|
237
|
+
if is_missing_required_params:
|
|
256
238
|
raise FrogmlException(
|
|
257
|
-
"Either model_version_id must be provided, or both model_id and model_version_name must be provided"
|
|
239
|
+
error_message="Either model_version_id must be provided, or both model_id and model_version_name must be provided",
|
|
240
|
+
status_code=HTTPStatus.BAD_REQUEST,
|
|
241
|
+
operation="Promote Model Version",
|
|
258
242
|
)
|
|
243
|
+
return self._promote_to_build_grpc(
|
|
244
|
+
build_config, model_version_id, model_id, model_version_name
|
|
245
|
+
)
|
|
259
246
|
|
|
247
|
+
@grpc_try_catch_wrapper(
|
|
248
|
+
error_message="Failed to promote model version '{model_version_name}' (id: {model_version_id}) to build",
|
|
249
|
+
operation="Promote Model Version",
|
|
250
|
+
)
|
|
251
|
+
def _promote_to_build_grpc(
|
|
252
|
+
self: Self,
|
|
253
|
+
build_config: BuildConfigDTO,
|
|
254
|
+
model_version_id: Optional[str],
|
|
255
|
+
model_id: Optional[str],
|
|
256
|
+
model_version_name: Optional[str],
|
|
257
|
+
) -> str:
|
|
258
|
+
logger.info("Promote model version to build %s", build_config)
|
|
260
259
|
build_spec: BuildSpec = map_build_conf_to_build_spec(build_config)
|
|
261
260
|
logger.debug("build_spec = %s", build_spec)
|
|
262
261
|
|
|
@@ -1,14 +1,32 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
from types import TracebackType
|
|
3
|
+
from typing import Optional
|
|
4
|
+
|
|
1
5
|
from .frogml_exception import FrogmlException
|
|
2
6
|
from .frogml_general_build_exception import FrogmlGeneralBuildException
|
|
3
7
|
from .frogml_grpc_address_exception import FrogmlGrpcAddressException
|
|
4
8
|
from .frogml_http_exception import FrogmlHTTPException
|
|
5
9
|
from .frogml_inference_exception import FrogmlInferenceException
|
|
6
10
|
from .frogml_load_configuration_exception import LoadConfigurationException
|
|
7
|
-
from .frogml_load_model_failed_exception import FrogmlLoadModelFailedException
|
|
8
11
|
from .frogml_login_exception import FrogmlLoginException
|
|
9
12
|
from .frogml_mock_http_exception import MockHttpException
|
|
10
13
|
from .frogml_model_initialization_exception import FrogmlModelInitializationException
|
|
11
14
|
from .frogml_not_found_exception import FrogmlNotFoundException
|
|
12
15
|
from .frogml_remote_build_failed import FrogmlRemoteBuildFailedException
|
|
13
16
|
from .frogml_suggestion_exception import FrogmlSuggestionException
|
|
14
|
-
from .
|
|
17
|
+
from .grpc_status_mapping import grpc_to_http_status
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def _quiet_hook(
|
|
21
|
+
kind: type[BaseException],
|
|
22
|
+
message: BaseException,
|
|
23
|
+
traceback: Optional[TracebackType],
|
|
24
|
+
) -> None:
|
|
25
|
+
"""Custom exception hook that suppresses tracebacks for FrogmlException."""
|
|
26
|
+
if issubclass(kind, FrogmlException):
|
|
27
|
+
print(f"{message}")
|
|
28
|
+
else:
|
|
29
|
+
sys.__excepthook__(kind, message, traceback)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
sys.excepthook = _quiet_hook
|