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.
- frogml/__init__.py +1 -1
- frogml/_proto/com/jfrog/ml/model/deployment/v1/auto_scaling_pb2.py +43 -0
- frogml/_proto/com/jfrog/ml/model/deployment/v1/auto_scaling_pb2.pyi +218 -0
- frogml/_proto/com/jfrog/ml/model/deployment/v1/auto_scaling_pb2_grpc.py +4 -0
- frogml/_proto/com/jfrog/ml/model/deployment/v1/deployment_pb2.py +53 -0
- frogml/_proto/com/jfrog/ml/model/deployment/v1/deployment_pb2.pyi +258 -0
- frogml/_proto/com/jfrog/ml/model/deployment/v1/deployment_pb2_grpc.py +4 -0
- frogml/_proto/com/jfrog/ml/model/deployment/v1/deployment_service_pb2.py +58 -0
- frogml/_proto/com/jfrog/ml/model/deployment/v1/deployment_service_pb2.pyi +224 -0
- frogml/_proto/com/jfrog/ml/model/deployment/v1/deployment_service_pb2_grpc.py +206 -0
- frogml/_proto/com/jfrog/ml/model/deployment/v1/environment_variables_configuration_pb2.py +33 -0
- frogml/_proto/com/jfrog/ml/model/deployment/v1/environment_variables_configuration_pb2.pyi +99 -0
- frogml/_proto/com/jfrog/ml/model/deployment/v1/environment_variables_configuration_pb2_grpc.py +4 -0
- frogml/_proto/com/jfrog/ml/model/deployment/v1/model_artifact_identifier_pb2.py +31 -0
- frogml/_proto/com/jfrog/ml/model/deployment/v1/model_artifact_identifier_pb2.pyi +99 -0
- frogml/_proto/com/jfrog/ml/model/deployment/v1/model_artifact_identifier_pb2_grpc.py +4 -0
- frogml/_proto/com/jfrog/ml/model/deployment/v1/model_deployment_brief_pb2.py +30 -0
- frogml/_proto/com/jfrog/ml/model/deployment/v1/model_deployment_brief_pb2.pyi +55 -0
- frogml/_proto/com/jfrog/ml/model/deployment/v1/model_deployment_brief_pb2_grpc.py +4 -0
- frogml/_proto/com/jfrog/ml/model/deployment/v1/model_deployment_filter_pb2.py +42 -0
- frogml/_proto/com/jfrog/ml/model/deployment/v1/model_deployment_filter_pb2.pyi +204 -0
- frogml/_proto/com/jfrog/ml/model/deployment/v1/model_deployment_filter_pb2_grpc.py +4 -0
- frogml/_proto/com/jfrog/ml/model/deployment/v1/probes_configuration_pb2.py +29 -0
- frogml/_proto/com/jfrog/ml/model/deployment/v1/probes_configuration_pb2.pyi +60 -0
- frogml/_proto/com/jfrog/ml/model/deployment/v1/probes_configuration_pb2_grpc.py +4 -0
- frogml/_proto/com/jfrog/ml/model/deployment/v1/realtime_deployment_pb2.py +28 -0
- frogml/_proto/com/jfrog/ml/model/deployment/v1/realtime_deployment_pb2.pyi +47 -0
- frogml/_proto/com/jfrog/ml/model/deployment/v1/realtime_deployment_pb2_grpc.py +4 -0
- frogml/_proto/com/jfrog/ml/model/deployment/v1/resource_configuration_pb2.py +27 -0
- frogml/_proto/com/jfrog/ml/model/deployment/v1/resource_configuration_pb2.pyi +29 -0
- frogml/_proto/com/jfrog/ml/model/deployment/v1/resource_configuration_pb2_grpc.py +4 -0
- frogml/_proto/qwak/logging/log_source_pb2.py +31 -25
- frogml/_proto/qwak/logging/log_source_pb2.pyi +28 -14
- frogml/_proto/qwak/models/models_pb2.py +81 -79
- frogml/_proto/qwak/models/models_pb2.pyi +24 -0
- frogml/_proto/qwak/models/models_pb2_grpc.py +34 -0
- frogml/core/clients/batch_job_management/client.py +14 -6
- frogml/core/clients/logging_client/client.py +118 -33
- frogml/core/clients/model_deployment_manager/__init__.py +1 -0
- frogml/core/clients/model_deployment_manager/client.py +103 -0
- {frogml-1.2.35.dist-info → frogml-1.2.41.dist-info}/METADATA +1 -1
- {frogml-1.2.35.dist-info → frogml-1.2.41.dist-info}/RECORD +46 -13
- frogml_services_mock/mocks/frogml_mocks.py +11 -3
- frogml_services_mock/mocks/model_deployment_manager_service_mock.py +255 -0
- frogml_services_mock/services_mock.py +18 -2
- {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
|
|
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
|
)
|
|
File without changes
|