frogml 1.2.35__py3-none-any.whl → 1.2.41__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 (46) 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/logging/log_source_pb2.py +31 -25
  33. frogml/_proto/qwak/logging/log_source_pb2.pyi +28 -14
  34. frogml/_proto/qwak/models/models_pb2.py +81 -79
  35. frogml/_proto/qwak/models/models_pb2.pyi +24 -0
  36. frogml/_proto/qwak/models/models_pb2_grpc.py +34 -0
  37. frogml/core/clients/batch_job_management/client.py +14 -6
  38. frogml/core/clients/logging_client/client.py +118 -33
  39. frogml/core/clients/model_deployment_manager/__init__.py +1 -0
  40. frogml/core/clients/model_deployment_manager/client.py +103 -0
  41. {frogml-1.2.35.dist-info → frogml-1.2.41.dist-info}/METADATA +1 -1
  42. {frogml-1.2.35.dist-info → frogml-1.2.41.dist-info}/RECORD +46 -13
  43. frogml_services_mock/mocks/frogml_mocks.py +11 -3
  44. frogml_services_mock/mocks/model_deployment_manager_service_mock.py +255 -0
  45. frogml_services_mock/services_mock.py +18 -2
  46. {frogml-1.2.35.dist-info → frogml-1.2.41.dist-info}/WHEEL +0 -0
@@ -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,7 +3,9 @@ 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
  )
@@ -189,6 +191,9 @@ from frogml_services_mock.mocks.location_discovery_service_api import (
189
191
  LocationDiscoveryServiceApiMock,
190
192
  )
191
193
  from frogml_services_mock.mocks.logging_service import LoggingServiceApiMock
194
+ from frogml_services_mock.mocks.model_deployment_manager_service_mock import (
195
+ ModelDeploymentManagerMock,
196
+ )
192
197
  from frogml_services_mock.mocks.model_group_management_service import (
193
198
  ModelGroupManagementServiceMock,
194
199
  )
@@ -248,13 +253,18 @@ def frogml_container():
248
253
  kube_deployment_captain,
249
254
  location_discovery,
250
255
  logging_client,
256
+ model_deployment_manager,
251
257
  model_group_management,
252
258
  model_management,
253
259
  model_version_manager,
254
260
  secret_service,
255
261
  user_application_instance,
256
262
  )
257
- from frogml.core.clients.administration import eco_system, self_service, authentication
263
+ from frogml.core.clients.administration import (
264
+ authentication,
265
+ eco_system,
266
+ self_service,
267
+ )
258
268
  from frogml.core.clients.integration_management import integration_manager_client
259
269
  from frogml.core.clients.system_secret import system_secret_client
260
270
 
@@ -287,6 +297,7 @@ def frogml_container():
287
297
  model_version_manager,
288
298
  jfrog_gateway,
289
299
  location_discovery,
300
+ model_deployment_manager,
290
301
  ]
291
302
  )
292
303
 
@@ -501,6 +512,11 @@ def attach_servicers(free_port, server):
501
512
  JFrogTenantInfoServiceMock,
502
513
  add_JFrogTenantInfoServiceServicer_to_server,
503
514
  ),
515
+ (
516
+ "model_deployment_manager_mock",
517
+ ModelDeploymentManagerMock,
518
+ add_ModelDeploymentServiceServicer_to_server,
519
+ ),
504
520
  ("port", free_port, None),
505
521
  ],
506
522
  )