frogml 1.2.38__py3-none-any.whl → 1.2.47__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 (66) hide show
  1. frogml/__init__.py +1 -1
  2. frogml/_proto/com/jfrog/ml/model/deployment/v1/auto_scaling_pb2.py +43 -0
  3. frogml/_proto/com/jfrog/ml/model/deployment/v1/auto_scaling_pb2.pyi +218 -0
  4. frogml/_proto/com/jfrog/ml/model/deployment/v1/auto_scaling_pb2_grpc.py +4 -0
  5. frogml/_proto/com/jfrog/ml/model/deployment/v1/deployment_pb2.py +53 -0
  6. frogml/_proto/com/jfrog/ml/model/deployment/v1/deployment_pb2.pyi +258 -0
  7. frogml/_proto/com/jfrog/ml/model/deployment/v1/deployment_pb2_grpc.py +4 -0
  8. frogml/_proto/com/jfrog/ml/model/deployment/v1/deployment_service_pb2.py +58 -0
  9. frogml/_proto/com/jfrog/ml/model/deployment/v1/deployment_service_pb2.pyi +224 -0
  10. frogml/_proto/com/jfrog/ml/model/deployment/v1/deployment_service_pb2_grpc.py +206 -0
  11. frogml/_proto/com/jfrog/ml/model/deployment/v1/environment_variables_configuration_pb2.py +33 -0
  12. frogml/_proto/com/jfrog/ml/model/deployment/v1/environment_variables_configuration_pb2.pyi +99 -0
  13. frogml/_proto/com/jfrog/ml/model/deployment/v1/environment_variables_configuration_pb2_grpc.py +4 -0
  14. frogml/_proto/com/jfrog/ml/model/deployment/v1/model_artifact_identifier_pb2.py +31 -0
  15. frogml/_proto/com/jfrog/ml/model/deployment/v1/model_artifact_identifier_pb2.pyi +99 -0
  16. frogml/_proto/com/jfrog/ml/model/deployment/v1/model_artifact_identifier_pb2_grpc.py +4 -0
  17. frogml/_proto/com/jfrog/ml/model/deployment/v1/model_deployment_brief_pb2.py +30 -0
  18. frogml/_proto/com/jfrog/ml/model/deployment/v1/model_deployment_brief_pb2.pyi +55 -0
  19. frogml/_proto/com/jfrog/ml/model/deployment/v1/model_deployment_brief_pb2_grpc.py +4 -0
  20. frogml/_proto/com/jfrog/ml/model/deployment/v1/model_deployment_filter_pb2.py +42 -0
  21. frogml/_proto/com/jfrog/ml/model/deployment/v1/model_deployment_filter_pb2.pyi +204 -0
  22. frogml/_proto/com/jfrog/ml/model/deployment/v1/model_deployment_filter_pb2_grpc.py +4 -0
  23. frogml/_proto/com/jfrog/ml/model/deployment/v1/probes_configuration_pb2.py +29 -0
  24. frogml/_proto/com/jfrog/ml/model/deployment/v1/probes_configuration_pb2.pyi +60 -0
  25. frogml/_proto/com/jfrog/ml/model/deployment/v1/probes_configuration_pb2_grpc.py +4 -0
  26. frogml/_proto/com/jfrog/ml/model/deployment/v1/realtime_deployment_pb2.py +28 -0
  27. frogml/_proto/com/jfrog/ml/model/deployment/v1/realtime_deployment_pb2.pyi +47 -0
  28. frogml/_proto/com/jfrog/ml/model/deployment/v1/realtime_deployment_pb2_grpc.py +4 -0
  29. frogml/_proto/com/jfrog/ml/model/deployment/v1/resource_configuration_pb2.py +27 -0
  30. frogml/_proto/com/jfrog/ml/model/deployment/v1/resource_configuration_pb2.pyi +29 -0
  31. frogml/_proto/com/jfrog/ml/model/deployment/v1/resource_configuration_pb2_grpc.py +4 -0
  32. frogml/_proto/qwak/administration/cluster/v2/cluster_service_pb2.py +52 -0
  33. frogml/_proto/qwak/administration/cluster/v2/cluster_service_pb2.pyi +208 -0
  34. frogml/_proto/qwak/administration/cluster/v2/cluster_service_pb2_grpc.py +237 -0
  35. frogml/_proto/qwak/administration/v1/environments/environment_pb2.py +29 -0
  36. frogml/_proto/qwak/administration/v1/environments/environment_pb2.pyi +35 -0
  37. frogml/_proto/qwak/administration/v1/environments/environment_pb2_grpc.py +4 -0
  38. frogml/_proto/qwak/administration/v1/environments/environment_service_pb2.py +33 -0
  39. frogml/_proto/qwak/administration/v1/environments/environment_service_pb2.pyi +59 -0
  40. frogml/_proto/qwak/administration/v1/environments/environment_service_pb2_grpc.py +67 -0
  41. frogml/_proto/qwak/admiral/secret/v0/account_secret_pb2.py +33 -0
  42. frogml/_proto/qwak/admiral/secret/v0/account_secret_pb2.pyi +76 -0
  43. frogml/_proto/qwak/admiral/secret/v0/account_secret_pb2_grpc.py +4 -0
  44. frogml/_proto/qwak/admiral/secret/v0/system_secret_service_pb2.py +28 -15
  45. frogml/_proto/qwak/admiral/secret/v0/system_secret_service_pb2.pyi +89 -0
  46. frogml/_proto/qwak/admiral/secret/v0/system_secret_service_pb2_grpc.py +102 -0
  47. frogml/_proto/qwak/models/models_pb2.py +81 -79
  48. frogml/_proto/qwak/models/models_pb2.pyi +24 -0
  49. frogml/_proto/qwak/models/models_pb2_grpc.py +34 -0
  50. frogml/core/clients/administration/cluster_v2/__init__.py +1 -0
  51. frogml/core/clients/administration/cluster_v2/client.py +122 -0
  52. frogml/core/clients/administration/environment/client.py +28 -0
  53. frogml/core/clients/administration/environment_v1/__init__.py +1 -0
  54. frogml/core/clients/administration/environment_v1/client.py +53 -0
  55. frogml/core/clients/model_deployment_manager/__init__.py +1 -0
  56. frogml/core/clients/model_deployment_manager/client.py +103 -0
  57. frogml/core/inner/di_configuration/dependency_wiring.py +18 -16
  58. {frogml-1.2.38.dist-info → frogml-1.2.47.dist-info}/METADATA +1 -1
  59. {frogml-1.2.38.dist-info → frogml-1.2.47.dist-info}/RECORD +66 -14
  60. frogml_services_mock/mocks/cluster_v2_service.py +146 -0
  61. frogml_services_mock/mocks/environment_v0_service.py +175 -0
  62. frogml_services_mock/mocks/environment_v1_service.py +37 -0
  63. frogml_services_mock/mocks/frogml_mocks.py +17 -3
  64. frogml_services_mock/mocks/model_deployment_manager_service_mock.py +255 -0
  65. frogml_services_mock/services_mock.py +51 -2
  66. {frogml-1.2.38.dist-info → frogml-1.2.47.dist-info}/WHEEL +0 -0
@@ -0,0 +1,175 @@
1
+ from typing import Optional
2
+
3
+ import grpc
4
+
5
+ from frogml._proto.qwak.administration.v0.environments.environment_pb2 import (
6
+ QwakEnvironment,
7
+ )
8
+ from frogml._proto.qwak.administration.v0.environments.environment_service_pb2 import (
9
+ CreateEnvironmentResponse,
10
+ GetEnvironmentApplicationUserCredentialsResponse,
11
+ GetEnvironmentResponse,
12
+ ListEnvironmentsResponse,
13
+ SetEnvironmentApplicationUserCredentialsResponse,
14
+ UpdateEnvironmentConfigurationResponse,
15
+ UpdateEnvironmentPersonalizationResponse,
16
+ )
17
+ from frogml._proto.qwak.administration.v0.environments.environment_service_pb2_grpc import (
18
+ EnvironmentServiceServicer,
19
+ )
20
+
21
+
22
+ class EnvironmentV0ServiceMock(EnvironmentServiceServicer):
23
+ def __init__(self):
24
+ super().__init__()
25
+ self.__create_environment_response: Optional[CreateEnvironmentResponse] = None
26
+ self.__create_environment_error: Optional[grpc.StatusCode] = None
27
+
28
+ self.__get_environment_response: Optional[GetEnvironmentResponse] = None
29
+ self.__get_environment_error: Optional[grpc.StatusCode] = None
30
+
31
+ self.__update_environment_configuration_response: Optional[
32
+ UpdateEnvironmentConfigurationResponse
33
+ ] = None
34
+ self.__update_environment_configuration_error: Optional[grpc.StatusCode] = None
35
+
36
+ self.__update_environment_personalization_response: Optional[
37
+ UpdateEnvironmentPersonalizationResponse
38
+ ] = None
39
+ self.__update_environment_personalization_error: Optional[grpc.StatusCode] = (
40
+ None
41
+ )
42
+
43
+ self.__list_environments_response: Optional[ListEnvironmentsResponse] = None
44
+ self.__list_environments_error: Optional[grpc.StatusCode] = None
45
+
46
+ self.__get_credentials_response: Optional[
47
+ GetEnvironmentApplicationUserCredentialsResponse
48
+ ] = None
49
+ self.__get_credentials_error: Optional[grpc.StatusCode] = None
50
+
51
+ self.__set_credentials_response: Optional[
52
+ SetEnvironmentApplicationUserCredentialsResponse
53
+ ] = None
54
+ self.__set_credentials_error: Optional[grpc.StatusCode] = None
55
+
56
+ def given_create_environment(
57
+ self,
58
+ response: Optional[CreateEnvironmentResponse] = None,
59
+ error_code: Optional[grpc.StatusCode] = None,
60
+ ):
61
+ self.__create_environment_response = response
62
+ self.__create_environment_error = error_code
63
+
64
+ def given_get_environment(
65
+ self,
66
+ response: Optional[GetEnvironmentResponse] = None,
67
+ error_code: Optional[grpc.StatusCode] = None,
68
+ ):
69
+ self.__get_environment_response = response
70
+ self.__get_environment_error = error_code
71
+
72
+ def given_update_environment_configuration(
73
+ self,
74
+ response: Optional[UpdateEnvironmentConfigurationResponse] = None,
75
+ error_code: Optional[grpc.StatusCode] = None,
76
+ ):
77
+ self.__update_environment_configuration_response = response
78
+ self.__update_environment_configuration_error = error_code
79
+
80
+ def given_update_environment_personalization(
81
+ self,
82
+ response: Optional[UpdateEnvironmentPersonalizationResponse] = None,
83
+ error_code: Optional[grpc.StatusCode] = None,
84
+ ):
85
+ self.__update_environment_personalization_response = response
86
+ self.__update_environment_personalization_error = error_code
87
+
88
+ def given_list_environments(
89
+ self,
90
+ response: Optional[ListEnvironmentsResponse] = None,
91
+ error_code: Optional[grpc.StatusCode] = None,
92
+ ):
93
+ self.__list_environments_response = response
94
+ self.__list_environments_error = error_code
95
+
96
+ def given_get_credentials(
97
+ self,
98
+ response: Optional[GetEnvironmentApplicationUserCredentialsResponse] = None,
99
+ error_code: Optional[grpc.StatusCode] = None,
100
+ ):
101
+ self.__get_credentials_response = response
102
+ self.__get_credentials_error = error_code
103
+
104
+ def given_set_credentials(
105
+ self,
106
+ response: Optional[SetEnvironmentApplicationUserCredentialsResponse] = None,
107
+ error_code: Optional[grpc.StatusCode] = None,
108
+ ):
109
+ self.__set_credentials_response = response
110
+ self.__set_credentials_error = error_code
111
+
112
+ def CreateEnvironment(self, request, context):
113
+ if self.__create_environment_error:
114
+ context.set_code(self.__create_environment_error)
115
+ context.set_details("Failed to create environment")
116
+ return CreateEnvironmentResponse()
117
+ if self.__create_environment_response:
118
+ return self.__create_environment_response
119
+ return CreateEnvironmentResponse(environment=QwakEnvironment(id="mock-env-id"))
120
+
121
+ def GetEnvironment(self, request, context):
122
+ if self.__get_environment_error:
123
+ context.set_code(self.__get_environment_error)
124
+ context.set_details("Failed to get environment")
125
+ return GetEnvironmentResponse()
126
+ if self.__get_environment_response:
127
+ return self.__get_environment_response
128
+ return GetEnvironmentResponse(
129
+ environment=QwakEnvironment(id=request.environment_id)
130
+ )
131
+
132
+ def UpdateEnvironmentConfiguration(self, request, context):
133
+ if self.__update_environment_configuration_error:
134
+ context.set_code(self.__update_environment_configuration_error)
135
+ context.set_details("Failed to update environment configuration")
136
+ return UpdateEnvironmentConfigurationResponse()
137
+ if self.__update_environment_configuration_response:
138
+ return self.__update_environment_configuration_response
139
+ return UpdateEnvironmentConfigurationResponse()
140
+
141
+ def UpdateEnvironmentPersonalization(self, request, context):
142
+ if self.__update_environment_personalization_error:
143
+ context.set_code(self.__update_environment_personalization_error)
144
+ context.set_details("Failed to update environment personalization")
145
+ return UpdateEnvironmentPersonalizationResponse()
146
+ if self.__update_environment_personalization_response:
147
+ return self.__update_environment_personalization_response
148
+ return UpdateEnvironmentPersonalizationResponse()
149
+
150
+ def ListEnvironments(self, request, context):
151
+ if self.__list_environments_error:
152
+ context.set_code(self.__list_environments_error)
153
+ context.set_details("Failed to list environments")
154
+ return ListEnvironmentsResponse()
155
+ if self.__list_environments_response:
156
+ return self.__list_environments_response
157
+ return ListEnvironmentsResponse()
158
+
159
+ def GetEnvironmentApplicationUserCredentials(self, request, context):
160
+ if self.__get_credentials_error:
161
+ context.set_code(self.__get_credentials_error)
162
+ context.set_details("Failed to get credentials")
163
+ return GetEnvironmentApplicationUserCredentialsResponse()
164
+ if self.__get_credentials_response:
165
+ return self.__get_credentials_response
166
+ return GetEnvironmentApplicationUserCredentialsResponse()
167
+
168
+ def SetEnvironmentApplicationUserCredentials(self, request, context):
169
+ if self.__set_credentials_error:
170
+ context.set_code(self.__set_credentials_error)
171
+ context.set_details("Failed to set credentials")
172
+ return SetEnvironmentApplicationUserCredentialsResponse()
173
+ if self.__set_credentials_response:
174
+ return self.__set_credentials_response
175
+ return SetEnvironmentApplicationUserCredentialsResponse()
@@ -0,0 +1,37 @@
1
+ from typing import Optional
2
+
3
+ import grpc
4
+
5
+ from frogml._proto.qwak.administration.v0.environments.environment_pb2 import (
6
+ QwakEnvironment,
7
+ )
8
+ from frogml._proto.qwak.administration.v1.environments.environment_service_pb2 import (
9
+ CreateEnvironmentResponse,
10
+ )
11
+ from frogml._proto.qwak.administration.v1.environments.environment_service_pb2_grpc import (
12
+ EnvironmentServiceServicer,
13
+ )
14
+
15
+
16
+ class EnvironmentV1ServiceMock(EnvironmentServiceServicer):
17
+ def __init__(self):
18
+ super().__init__()
19
+ self.__create_environment_response: Optional[CreateEnvironmentResponse] = None
20
+ self.__create_environment_error: Optional[grpc.StatusCode] = None
21
+
22
+ def given_create_environment(
23
+ self,
24
+ response: Optional[CreateEnvironmentResponse] = None,
25
+ error_code: Optional[grpc.StatusCode] = None,
26
+ ):
27
+ self.__create_environment_response = response
28
+ self.__create_environment_error = error_code
29
+
30
+ def CreateEnvironment(self, request, context):
31
+ if self.__create_environment_error:
32
+ context.set_code(self.__create_environment_error)
33
+ context.set_details("Failed to create environment")
34
+ return CreateEnvironmentResponse()
35
+ if self.__create_environment_response:
36
+ return self.__create_environment_response
37
+ return CreateEnvironmentResponse(environment=QwakEnvironment(id="mock-env-id"))
@@ -23,11 +23,14 @@ from frogml_services_mock.mocks.build_orchestrator_build_settings_api import (
23
23
  from frogml_services_mock.mocks.build_orchestrator_service_api import (
24
24
  BuildOrchestratorServiceApiMock,
25
25
  )
26
+ from frogml_services_mock.mocks.cluster_v2_service import ClusterV2ServiceMock
26
27
  from frogml_services_mock.mocks.data_versioning_service import DataVersioningServiceMock
27
28
  from frogml_services_mock.mocks.deployment_management_service import (
28
29
  DeploymentManagementServiceMock,
29
30
  )
30
31
  from frogml_services_mock.mocks.ecosystem_service_api import EcoSystemServiceMock
32
+ from frogml_services_mock.mocks.environment_v0_service import EnvironmentV0ServiceMock
33
+ from frogml_services_mock.mocks.environment_v1_service import EnvironmentV1ServiceMock
31
34
  from frogml_services_mock.mocks.execution_management_service import (
32
35
  ExecutionManagementServiceMock,
33
36
  )
@@ -56,7 +59,9 @@ from frogml_services_mock.mocks.integration_management_service import (
56
59
  from frogml_services_mock.mocks.internal_build_orchestrator_service import (
57
60
  InternalBuildOrchestratorServiceMock,
58
61
  )
59
- from frogml_services_mock.mocks.jfrog_tenant_info_service_mock import JFrogTenantInfoServiceMock
62
+ from frogml_services_mock.mocks.jfrog_tenant_info_service_mock import (
63
+ JFrogTenantInfoServiceMock,
64
+ )
60
65
  from frogml_services_mock.mocks.job_registry_service_api import (
61
66
  JobRegistryServiceApiMock,
62
67
  )
@@ -67,15 +72,20 @@ from frogml_services_mock.mocks.location_discovery_service_api import (
67
72
  LocationDiscoveryServiceApiMock,
68
73
  )
69
74
  from frogml_services_mock.mocks.logging_service import LoggingServiceApiMock
70
- from frogml_services_mock.mocks.model_group_management_service import ModelGroupManagementServiceMock
75
+ from frogml_services_mock.mocks.model_deployment_manager_service_mock import (
76
+ ModelDeploymentManagerMock,
77
+ )
78
+ from frogml_services_mock.mocks.model_group_management_service import (
79
+ ModelGroupManagementServiceMock,
80
+ )
71
81
  from frogml_services_mock.mocks.model_management_service import (
72
82
  ModelsManagementServiceMock,
73
83
  )
74
84
  from frogml_services_mock.mocks.model_version_manager_service import (
75
85
  ModelVersionManagerServiceMock,
76
86
  )
77
- from frogml_services_mock.mocks.repository_service_mock import RepositoryServiceMock
78
87
  from frogml_services_mock.mocks.project_manager_service import ProjectManagerServiceMock
88
+ from frogml_services_mock.mocks.repository_service_mock import RepositoryServiceMock
79
89
  from frogml_services_mock.mocks.secret_service import SecretServiceMock
80
90
  from frogml_services_mock.mocks.self_service_user_service import (
81
91
  SelfServiceUserServiceMock,
@@ -127,3 +137,7 @@ class FrogmlMocks:
127
137
  repository_service: RepositoryServiceMock
128
138
  location_discovery_service: LocationDiscoveryServiceApiMock
129
139
  jfrog_tenant_info_service: JFrogTenantInfoServiceMock
140
+ model_deployment_manager_mock: ModelDeploymentManagerMock
141
+ cluster_v2_service_mock: ClusterV2ServiceMock
142
+ environment_v0_service_mock: EnvironmentV0ServiceMock
143
+ environment_v1_service_mock: EnvironmentV1ServiceMock
@@ -0,0 +1,255 @@
1
+ import uuid
2
+ from datetime import datetime, timezone
3
+ from typing import Callable, Optional
4
+
5
+ import grpc
6
+ from frogml._proto.com.jfrog.ml.model.deployment.v1.deployment_pb2 import (
7
+ Deployment,
8
+ DeploymentMetadata,
9
+ ModelDeploymentInformation,
10
+ ModelDeploymentStatus,
11
+ ModelDeploymentStatusSuccessful,
12
+ MultipleEnvironmentDeployment,
13
+ )
14
+ from frogml._proto.com.jfrog.ml.model.deployment.v1.deployment_service_pb2 import (
15
+ DeployModelRequest,
16
+ DeployModelResponse,
17
+ EditModelDeploymentRequest,
18
+ EditModelDeploymentResponse,
19
+ GetModelDeploymentRequest,
20
+ GetModelDeploymentResponse,
21
+ ListModelDeploymentsRequest,
22
+ ListModelDeploymentsResponse,
23
+ UndeployModelRequest,
24
+ UndeployModelResponse,
25
+ )
26
+ from frogml._proto.com.jfrog.ml.model.deployment.v1.deployment_service_pb2_grpc import (
27
+ ModelDeploymentServiceServicer,
28
+ )
29
+ from frogml._proto.com.jfrog.ml.model.deployment.v1.model_artifact_identifier_pb2 import (
30
+ ModelArtifactIdentifier,
31
+ ModelBasedArtifactIdentifier,
32
+ )
33
+ from frogml._proto.com.jfrog.ml.model.deployment.v1.model_deployment_brief_pb2 import (
34
+ ModelDeploymentBrief,
35
+ )
36
+ from google.protobuf.timestamp_pb2 import Timestamp
37
+ from pydantic import BaseModel, ConfigDict
38
+
39
+
40
+ class DeploymentInformation(BaseModel):
41
+ model_config = ConfigDict(arbitrary_types_allowed=True)
42
+
43
+ deployment_id: uuid.UUID
44
+ model_id: str
45
+ model_group_id: str
46
+ path: str
47
+ environment_id: uuid.UUID
48
+ deployment_config: Deployment
49
+ created_at: datetime
50
+
51
+
52
+ class ModelDeploymentManagerMock(ModelDeploymentServiceServicer):
53
+ def __init__(self):
54
+ self.__deployment_id_to_spec: dict[str, DeploymentInformation] = {}
55
+
56
+ @staticmethod
57
+ def __get_model_identifier_details(
58
+ model_artifact_identifier: ModelArtifactIdentifier,
59
+ ) -> tuple[str, str, str]:
60
+ identifier_type = model_artifact_identifier.WhichOneof("identifier_type")
61
+
62
+ if identifier_type == "model_based_artifact_id":
63
+ artifact = model_artifact_identifier.model_based_artifact_id
64
+ return (
65
+ artifact.model_id,
66
+ artifact.model_group_id,
67
+ artifact.image_path,
68
+ )
69
+ elif identifier_type == "custom_model_artifact_id":
70
+ artifact = model_artifact_identifier.custom_model_artifact_id
71
+ return (
72
+ artifact.model_id,
73
+ artifact.model_group_id,
74
+ artifact.build_id,
75
+ )
76
+
77
+ raise Exception("No Model Artifact Identifier found")
78
+
79
+ def DeployModel(
80
+ self, request: DeployModelRequest, context: grpc.ServicerContext
81
+ ) -> DeployModelResponse:
82
+ multiple_environment_deployment: MultipleEnvironmentDeployment = (
83
+ request.multiple_environment_deployment
84
+ )
85
+ model_artifact_identifier: ModelArtifactIdentifier = (
86
+ multiple_environment_deployment.model_artifact_identifier
87
+ )
88
+ model_id, model_group_id, path = self.__get_model_identifier_details(
89
+ model_artifact_identifier
90
+ )
91
+
92
+ self.__deployment_id_to_spec.update(
93
+ {
94
+ (deployment_id := str(uuid.uuid4())): DeploymentInformation(
95
+ deployment_id=uuid.UUID(deployment_id),
96
+ model_id=model_id,
97
+ model_group_id=model_group_id,
98
+ path=path,
99
+ environment_id=uuid.UUID(env_id),
100
+ deployment_config=deployment,
101
+ created_at=datetime.now(tz=timezone.utc),
102
+ )
103
+ for env_id, deployment in multiple_environment_deployment.deployments.items()
104
+ }
105
+ )
106
+
107
+ return DeployModelResponse()
108
+
109
+ def UndeployModel(
110
+ self, request: UndeployModelRequest, context: grpc.ServicerContext
111
+ ) -> UndeployModelResponse:
112
+ deployment_ids = list(request.deployment_ids.deployment_id)
113
+ for deployment_id in deployment_ids:
114
+ self.__deployment_id_to_spec.pop(deployment_id)
115
+
116
+ return UndeployModelResponse()
117
+
118
+ def EditModelDeployment(
119
+ self, request: EditModelDeploymentRequest, context: grpc.ServicerContext
120
+ ) -> EditModelDeploymentResponse:
121
+ deployment_map = dict(request.deployment_id_to_deployment_spec_map.deployments)
122
+ for deployment_id, new_spec in deployment_map.items():
123
+ if deployment_id not in self.__deployment_id_to_spec:
124
+ raise Exception("Deployment id does not exist")
125
+ self.__deployment_id_to_spec[deployment_id].deployment_config = new_spec
126
+
127
+ return EditModelDeploymentResponse()
128
+
129
+ @staticmethod
130
+ def __build_filter_predicates(
131
+ request: ListModelDeploymentsRequest,
132
+ ) -> list[Callable[[DeploymentInformation], bool]]:
133
+ """Build a list of filter predicates from the request."""
134
+ predicates: list[Callable[[DeploymentInformation], bool]] = []
135
+
136
+ if not request.model_deployment_filter.HasField(
137
+ "simple_model_deployment_filter"
138
+ ):
139
+ return predicates
140
+
141
+ simple_filter = request.model_deployment_filter.simple_model_deployment_filter
142
+
143
+ if simple_filter.HasField("model_identifier_filter"):
144
+ model_group_id = simple_filter.model_identifier_filter.model_group_id
145
+ model_id = simple_filter.model_identifier_filter.model_id
146
+ predicates.append(
147
+ lambda d, model_group_id=model_group_id, model_id=model_id: d.model_group_id
148
+ == model_group_id
149
+ and d.model_id == model_id
150
+ )
151
+
152
+ if simple_filter.HasField("model_group_ids"):
153
+ allowed_model_group_ids = set(simple_filter.model_group_ids.model_group_id)
154
+ predicates.append(
155
+ lambda d, allowed=allowed_model_group_ids: d.model_group_id in allowed
156
+ )
157
+
158
+ if simple_filter.HasField("model_ids"):
159
+ allowed_model_ids = set(simple_filter.model_ids.model_id)
160
+ predicates.append(
161
+ lambda d, allowed=allowed_model_ids: d.model_id in allowed
162
+ )
163
+
164
+ if simple_filter.HasField("environment_ids"):
165
+ allowed_environment_ids = set(simple_filter.environment_ids.environment_id)
166
+ predicates.append(
167
+ lambda d, allowed=allowed_environment_ids: str(d.environment_id)
168
+ in allowed
169
+ )
170
+
171
+ return predicates
172
+
173
+ @staticmethod
174
+ def _deployment_to_brief(
175
+ deployment_info: DeploymentInformation,
176
+ ) -> ModelDeploymentBrief:
177
+ """Convert a DeploymentInformation to a ModelDeploymentBrief."""
178
+ timestamp = Timestamp()
179
+ timestamp.FromDatetime(deployment_info.created_at)
180
+
181
+ return ModelDeploymentBrief(
182
+ status=ModelDeploymentStatus(
183
+ model_deployment_status_successful=ModelDeploymentStatusSuccessful()
184
+ ),
185
+ environment=str(deployment_info.environment_id),
186
+ created_at=timestamp,
187
+ deployment_id=str(deployment_info.deployment_id),
188
+ model_artifact_identifier=ModelArtifactIdentifier(
189
+ model_based_artifact_id=ModelBasedArtifactIdentifier(
190
+ model_id=deployment_info.model_id,
191
+ model_group_id=deployment_info.model_group_id,
192
+ image_path=deployment_info.path,
193
+ )
194
+ ),
195
+ )
196
+
197
+ def ListModelDeployments(
198
+ self, request: ListModelDeploymentsRequest, context: grpc.ServicerContext
199
+ ) -> ListModelDeploymentsResponse:
200
+ predicates: list[Callable[[DeploymentInformation], bool]] = (
201
+ self.__build_filter_predicates(request)
202
+ )
203
+
204
+ result = [
205
+ self._deployment_to_brief(deployment)
206
+ for deployment in self.__deployment_id_to_spec.values()
207
+ if all(predicate(deployment) for predicate in predicates)
208
+ ]
209
+
210
+ return ListModelDeploymentsResponse(model_deployment_brief=result)
211
+
212
+ def GetModelDeployment(
213
+ self, request: GetModelDeploymentRequest, context: grpc.ServicerContext
214
+ ) -> GetModelDeploymentResponse:
215
+ deployment_id = request.deployment_id
216
+ deployment_info = self.__deployment_id_to_spec.get(deployment_id)
217
+
218
+ if deployment_info is None:
219
+ return GetModelDeploymentResponse()
220
+
221
+ timestamp = Timestamp()
222
+ timestamp.FromDatetime(deployment_info.created_at)
223
+
224
+ model_artifact_identifier = ModelArtifactIdentifier(
225
+ model_based_artifact_id=ModelBasedArtifactIdentifier(
226
+ model_id=deployment_info.model_id,
227
+ model_group_id=deployment_info.model_group_id,
228
+ image_path=deployment_info.path,
229
+ )
230
+ )
231
+
232
+ model_deployment_info = ModelDeploymentInformation(
233
+ model_artifact_identifier=model_artifact_identifier,
234
+ model_deployment_spec=deployment_info.deployment_config,
235
+ model_deployment_metadata=DeploymentMetadata(
236
+ deployment_id=str(deployment_info.deployment_id),
237
+ status=ModelDeploymentStatus(
238
+ model_deployment_status_successful=ModelDeploymentStatusSuccessful()
239
+ ),
240
+ environment=str(deployment_info.environment_id),
241
+ created_at=timestamp,
242
+ ),
243
+ )
244
+
245
+ return GetModelDeploymentResponse(
246
+ model_deployment_information=model_deployment_info
247
+ )
248
+
249
+ def get_deployment_by_id(
250
+ self, deployment_id: str
251
+ ) -> Optional[DeploymentInformation]:
252
+ return self.__deployment_id_to_spec.get(deployment_id)
253
+
254
+ def get_all_deployments(self) -> list[DeploymentInformation]:
255
+ return list(self.__deployment_id_to_spec.values())
@@ -3,13 +3,24 @@ from typing import Any, Generator, List, Tuple
3
3
 
4
4
  import grpc
5
5
  import pytest
6
-
6
+ from frogml._proto.com.jfrog.ml.model.deployment.v1.deployment_service_pb2_grpc import (
7
+ add_ModelDeploymentServiceServicer_to_server,
8
+ )
7
9
  from frogml._proto.jfml.model_version.v1.model_version_manager_service_pb2_grpc import (
8
10
  add_ModelVersionManagerServiceServicer_to_server,
9
11
  )
10
12
  from frogml._proto.qwak.administration.v0.authentication.authentication_service_pb2_grpc import (
11
13
  add_AuthenticationServiceServicer_to_server,
12
14
  )
15
+ from frogml._proto.qwak.administration.cluster.v2.cluster_service_pb2_grpc import (
16
+ add_ClusterServiceServicer_to_server,
17
+ )
18
+ from frogml._proto.qwak.administration.v0.environments.environment_service_pb2_grpc import (
19
+ add_EnvironmentServiceServicer_to_server as add_EnvironmentV0ServiceServicer_to_server,
20
+ )
21
+ from frogml._proto.qwak.administration.v1.environments.environment_service_pb2_grpc import (
22
+ add_EnvironmentServiceServicer_to_server as add_EnvironmentV1ServiceServicer_to_server,
23
+ )
13
24
  from frogml._proto.qwak.admiral.secret.v0.system_secret_service_pb2_grpc import (
14
25
  add_SystemSecretServiceServicer_to_server,
15
26
  )
@@ -142,11 +153,14 @@ from frogml_services_mock.mocks.build_orchestrator_build_settings_api import (
142
153
  from frogml_services_mock.mocks.build_orchestrator_service_api import (
143
154
  BuildOrchestratorServiceApiMock,
144
155
  )
156
+ from frogml_services_mock.mocks.cluster_v2_service import ClusterV2ServiceMock
145
157
  from frogml_services_mock.mocks.data_versioning_service import DataVersioningServiceMock
146
158
  from frogml_services_mock.mocks.deployment_management_service import (
147
159
  DeploymentManagementServiceMock,
148
160
  )
149
161
  from frogml_services_mock.mocks.ecosystem_service_api import EcoSystemServiceMock
162
+ from frogml_services_mock.mocks.environment_v0_service import EnvironmentV0ServiceMock
163
+ from frogml_services_mock.mocks.environment_v1_service import EnvironmentV1ServiceMock
150
164
  from frogml_services_mock.mocks.execution_management_service import (
151
165
  ExecutionManagementServiceMock,
152
166
  )
@@ -189,6 +203,9 @@ from frogml_services_mock.mocks.location_discovery_service_api import (
189
203
  LocationDiscoveryServiceApiMock,
190
204
  )
191
205
  from frogml_services_mock.mocks.logging_service import LoggingServiceApiMock
206
+ from frogml_services_mock.mocks.model_deployment_manager_service_mock import (
207
+ ModelDeploymentManagerMock,
208
+ )
192
209
  from frogml_services_mock.mocks.model_group_management_service import (
193
210
  ModelGroupManagementServiceMock,
194
211
  )
@@ -248,13 +265,21 @@ def frogml_container():
248
265
  kube_deployment_captain,
249
266
  location_discovery,
250
267
  logging_client,
268
+ model_deployment_manager,
251
269
  model_group_management,
252
270
  model_management,
253
271
  model_version_manager,
254
272
  secret_service,
255
273
  user_application_instance,
256
274
  )
257
- from frogml.core.clients.administration import eco_system, self_service, authentication
275
+ from frogml.core.clients.administration import (
276
+ authentication,
277
+ cluster_v2,
278
+ eco_system,
279
+ environment,
280
+ environment_v1,
281
+ self_service,
282
+ )
258
283
  from frogml.core.clients.integration_management import integration_manager_client
259
284
  from frogml.core.clients.system_secret import system_secret_client
260
285
 
@@ -268,8 +293,11 @@ def frogml_container():
268
293
  analytics,
269
294
  batch_job_management,
270
295
  build_orchestrator,
296
+ cluster_v2,
271
297
  data_versioning,
272
298
  deployment,
299
+ environment,
300
+ environment_v1,
273
301
  instance_template,
274
302
  feature_store,
275
303
  file_versioning,
@@ -287,6 +315,7 @@ def frogml_container():
287
315
  model_version_manager,
288
316
  jfrog_gateway,
289
317
  location_discovery,
318
+ model_deployment_manager,
290
319
  ]
291
320
  )
292
321
 
@@ -501,6 +530,26 @@ def attach_servicers(free_port, server):
501
530
  JFrogTenantInfoServiceMock,
502
531
  add_JFrogTenantInfoServiceServicer_to_server,
503
532
  ),
533
+ (
534
+ "model_deployment_manager_mock",
535
+ ModelDeploymentManagerMock,
536
+ add_ModelDeploymentServiceServicer_to_server,
537
+ ),
538
+ (
539
+ "cluster_v2_service_mock",
540
+ ClusterV2ServiceMock,
541
+ add_ClusterServiceServicer_to_server,
542
+ ),
543
+ (
544
+ "environment_v0_service_mock",
545
+ EnvironmentV0ServiceMock,
546
+ add_EnvironmentV0ServiceServicer_to_server,
547
+ ),
548
+ (
549
+ "environment_v1_service_mock",
550
+ EnvironmentV1ServiceMock,
551
+ add_EnvironmentV1ServiceServicer_to_server,
552
+ ),
504
553
  ("port", free_port, None),
505
554
  ],
506
555
  )