frogml 1.2.40__py3-none-any.whl → 1.2.42__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 (39) 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/core/clients/model_deployment_manager/__init__.py +1 -0
  33. frogml/core/clients/model_deployment_manager/client.py +103 -0
  34. {frogml-1.2.40.dist-info → frogml-1.2.42.dist-info}/METADATA +1 -1
  35. {frogml-1.2.40.dist-info → frogml-1.2.42.dist-info}/RECORD +39 -6
  36. frogml_services_mock/mocks/frogml_mocks.py +11 -3
  37. frogml_services_mock/mocks/model_deployment_manager_service_mock.py +255 -0
  38. frogml_services_mock/services_mock.py +18 -2
  39. {frogml-1.2.40.dist-info → frogml-1.2.42.dist-info}/WHEEL +0 -0
@@ -0,0 +1,27 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
3
+ # source: com/jfrog/ml/model/deployment/v1/resource_configuration.proto
4
+ # Protobuf Python Version: 4.25.1
5
+ """Generated protocol buffer code."""
6
+ from google.protobuf import descriptor as _descriptor
7
+ from google.protobuf import descriptor_pool as _descriptor_pool
8
+ from google.protobuf import symbol_database as _symbol_database
9
+ from google.protobuf.internal import builder as _builder
10
+ # @@protoc_insertion_point(imports)
11
+
12
+ _sym_db = _symbol_database.Default()
13
+
14
+
15
+
16
+
17
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n=com/jfrog/ml/model/deployment/v1/resource_configuration.proto\x12 com.jfrog.ml.model.deployment.v1\"U\n\x15ResourceConfiguration\x12 \n\x16template_specification\x18\x01 \x01(\tH\x00\x42\x1a\n\x18resource_descriptor_typeB(\n$com.jfrog.ml.model.deployment.v1.apiP\x01\x62\x06proto3')
18
+
19
+ _globals = globals()
20
+ _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
21
+ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'com.jfrog.ml.model.deployment.v1.resource_configuration_pb2', _globals)
22
+ if _descriptor._USE_C_DESCRIPTORS == False:
23
+ _globals['DESCRIPTOR']._options = None
24
+ _globals['DESCRIPTOR']._serialized_options = b'\n$com.jfrog.ml.model.deployment.v1.apiP\001'
25
+ _globals['_RESOURCECONFIGURATION']._serialized_start=99
26
+ _globals['_RESOURCECONFIGURATION']._serialized_end=184
27
+ # @@protoc_insertion_point(module_scope)
@@ -0,0 +1,29 @@
1
+ """
2
+ @generated by mypy-protobuf. Do not edit manually!
3
+ isort:skip_file
4
+ """
5
+
6
+ import builtins
7
+ import google.protobuf.descriptor
8
+ import google.protobuf.message
9
+ import typing
10
+
11
+ DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
12
+
13
+ @typing.final
14
+ class ResourceConfiguration(google.protobuf.message.Message):
15
+ DESCRIPTOR: google.protobuf.descriptor.Descriptor
16
+
17
+ TEMPLATE_SPECIFICATION_FIELD_NUMBER: builtins.int
18
+ template_specification: builtins.str
19
+ """A legacy field for describing a compute resources allocation using templated resource sizes."""
20
+ def __init__(
21
+ self,
22
+ *,
23
+ template_specification: builtins.str = ...,
24
+ ) -> None: ...
25
+ def HasField(self, field_name: typing.Literal["resource_descriptor_type", b"resource_descriptor_type", "template_specification", b"template_specification"]) -> builtins.bool: ...
26
+ def ClearField(self, field_name: typing.Literal["resource_descriptor_type", b"resource_descriptor_type", "template_specification", b"template_specification"]) -> None: ...
27
+ def WhichOneof(self, oneof_group: typing.Literal["resource_descriptor_type", b"resource_descriptor_type"]) -> typing.Literal["template_specification"] | None: ...
28
+
29
+ global___ResourceConfiguration = ResourceConfiguration
@@ -0,0 +1,4 @@
1
+ # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
2
+ """Client and server classes corresponding to protobuf-defined services."""
3
+ import grpc
4
+
@@ -0,0 +1 @@
1
+ from .client import ModelDeploymentManagerClient
@@ -0,0 +1,103 @@
1
+ from dependency_injector.wiring import Provide
2
+ from frogml._proto.com.jfrog.ml.model.deployment.v1.deployment_pb2 import (
3
+ Deployment,
4
+ ModelDeploymentInformation,
5
+ MultipleEnvironmentDeployment,
6
+ )
7
+ from frogml._proto.com.jfrog.ml.model.deployment.v1.deployment_service_pb2 import (
8
+ DeploymentIds,
9
+ DeploymentIdToDeploymentSpecMap,
10
+ DeployModelRequest,
11
+ EditModelDeploymentRequest,
12
+ GetModelDeploymentResponse,
13
+ ListModelDeploymentsRequest,
14
+ ListModelDeploymentsResponse,
15
+ UndeployModelRequest,
16
+ )
17
+ from frogml._proto.com.jfrog.ml.model.deployment.v1.deployment_service_pb2_grpc import (
18
+ ModelDeploymentServiceStub,
19
+ )
20
+ from frogml._proto.com.jfrog.ml.model.deployment.v1.model_artifact_identifier_pb2 import (
21
+ ModelArtifactIdentifier,
22
+ ModelBasedArtifactIdentifier,
23
+ )
24
+ from frogml._proto.com.jfrog.ml.model.deployment.v1.model_deployment_brief_pb2 import (
25
+ ModelDeploymentBrief,
26
+ )
27
+ from frogml._proto.com.jfrog.ml.model.deployment.v1.model_deployment_filter_pb2 import (
28
+ ModelDeploymentFilter,
29
+ )
30
+ from frogml._proto.qwak.deployment.deployment_service_pb2 import GetDeploymentRequest
31
+ from frogml.core.inner.di_configuration import FrogmlContainer
32
+ from frogml.core.inner.tool.grpc.grpc_try_wrapping import grpc_try_catch_wrapper
33
+
34
+
35
+ class ModelDeploymentManagerClient:
36
+ def __init__(self, grpc_channel=Provide[FrogmlContainer.core_grpc_channel]):
37
+ self.__client = ModelDeploymentServiceStub(grpc_channel)
38
+
39
+ @grpc_try_catch_wrapper("Failed to deploy LLM for model {model_id}")
40
+ def deploy_llm(
41
+ self,
42
+ model_id: str,
43
+ model_group_id: str,
44
+ image_path: str,
45
+ environment_deployment_configuration: dict[str, Deployment],
46
+ ) -> None:
47
+ llm_model_identifier = ModelBasedArtifactIdentifier(
48
+ model_group_id=model_group_id,
49
+ model_id=model_id,
50
+ image_path=image_path,
51
+ )
52
+ model_artifact_identifier = ModelArtifactIdentifier(
53
+ model_based_artifact_id=llm_model_identifier
54
+ )
55
+ multiple_environment_deployment = MultipleEnvironmentDeployment(
56
+ model_artifact_identifier=model_artifact_identifier,
57
+ deployments=environment_deployment_configuration,
58
+ )
59
+ request = DeployModelRequest(
60
+ multiple_environment_deployment=multiple_environment_deployment
61
+ )
62
+
63
+ self.__client.DeployModel(request)
64
+
65
+ @grpc_try_catch_wrapper("Failed to undeploy")
66
+ def undeploy(self, deployment_ids: list[str]) -> None:
67
+ deployment_ids_proto = DeploymentIds(deployment_id=deployment_ids)
68
+ request = UndeployModelRequest(deployment_ids=deployment_ids_proto)
69
+ self.__client.UndeployModel(request)
70
+
71
+ @grpc_try_catch_wrapper("Failed to edit deployments")
72
+ def edit_deployments(
73
+ self, deployment_id_to_spec_map: dict[str, Deployment]
74
+ ) -> None:
75
+ deployments_map = DeploymentIdToDeploymentSpecMap(
76
+ deployments=deployment_id_to_spec_map
77
+ )
78
+ request = EditModelDeploymentRequest(
79
+ deployment_id_to_deployment_spec_map=deployments_map
80
+ )
81
+ self.__client.EditModelDeployment(request)
82
+
83
+ @grpc_try_catch_wrapper("Failed to list deployments")
84
+ def list_deployments(
85
+ self,
86
+ model_deployment_filter: ModelDeploymentFilter = None,
87
+ ) -> list[ModelDeploymentBrief]:
88
+ if model_deployment_filter is None:
89
+ model_deployment_filter = ModelDeploymentFilter()
90
+
91
+ request = ListModelDeploymentsRequest(
92
+ model_deployment_filter=model_deployment_filter
93
+ )
94
+ response: ListModelDeploymentsResponse = self.__client.ListModelDeployments(
95
+ request
96
+ )
97
+ return list(response.model_deployment_brief)
98
+
99
+ @grpc_try_catch_wrapper("Failed to get deployment with ID {deployment_id}")
100
+ def get_deployment(self, deployment_id: str) -> ModelDeploymentInformation:
101
+ request = GetDeploymentRequest(deployment_id=deployment_id)
102
+ response: GetModelDeploymentResponse = self.__client.GetModelDeployment(request)
103
+ return response.model_deployment_information
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: frogml
3
- Version: 1.2.40
3
+ Version: 1.2.42
4
4
  Summary: frogml contains the necessary objects and communication tools for using the JFrog ml Platform
5
5
  License: Apache-2.0
6
6
  Keywords: mlops,ml,deployment,serving,model
@@ -1,4 +1,34 @@
1
- frogml/__init__.py,sha256=PjA51CtynH2yUX2k_lzDfUDiPya6uCO3uTncfZ3d6cM,741
1
+ frogml/__init__.py,sha256=sJOd_xEn0Cz_WXUSQWRDjwsaTMl7KajIC5Sop94NZe8,741
2
+ frogml/_proto/com/jfrog/ml/model/deployment/v1/auto_scaling_pb2.py,sha256=-SD6RYgn5DFBLlwTpH9YkV8aW_zYymBI68Y-12Fn0I0,4193
3
+ frogml/_proto/com/jfrog/ml/model/deployment/v1/auto_scaling_pb2.pyi,sha256=s0rdjIYw_dOfmuentpri79ls5dC3NqoUq__-XeavaXE,9688
4
+ frogml/_proto/com/jfrog/ml/model/deployment/v1/auto_scaling_pb2_grpc.py,sha256=1oboBPFxaTEXt9Aw7EAj8gXHDCNMhZD2VXqocC9l_gk,159
5
+ frogml/_proto/com/jfrog/ml/model/deployment/v1/deployment_pb2.py,sha256=c1cvdGhas7PyjFa_qWgp8cQBT9FJJatDXpLFaAVqbIo,6441
6
+ frogml/_proto/com/jfrog/ml/model/deployment/v1/deployment_pb2.pyi,sha256=NMwN-k3r1Y3Z_2yrUvfTQvO0rywEMIsyXTpkroNy6X8,12950
7
+ frogml/_proto/com/jfrog/ml/model/deployment/v1/deployment_pb2_grpc.py,sha256=1oboBPFxaTEXt9Aw7EAj8gXHDCNMhZD2VXqocC9l_gk,159
8
+ frogml/_proto/com/jfrog/ml/model/deployment/v1/deployment_service_pb2.py,sha256=MtpCW3ZPBYrpIhMC0XMJRCGDVpI-Ak_jeKQ9DGqYaUQ,6286
9
+ frogml/_proto/com/jfrog/ml/model/deployment/v1/deployment_service_pb2.pyi,sha256=srnR6yTrjo8tnqAmnhxXEbf5EKD-dxMnfXZ-rABtmaY,9569
10
+ frogml/_proto/com/jfrog/ml/model/deployment/v1/deployment_service_pb2_grpc.py,sha256=qvF_o89cqJ9Jz_nZs3n72p_pY2Bo75Sq99ObFsx4Nsw,11599
11
+ frogml/_proto/com/jfrog/ml/model/deployment/v1/environment_variables_configuration_pb2.py,sha256=RPbECbR8DOWfq37aSYm4oWJhlVd-IWKGYEIhjmJ5VlU,2422
12
+ frogml/_proto/com/jfrog/ml/model/deployment/v1/environment_variables_configuration_pb2.pyi,sha256=z3FDspmH0Bfd15x_KnzPDRvBdVbxCPxIz7ckC5wqJPM,3860
13
+ frogml/_proto/com/jfrog/ml/model/deployment/v1/environment_variables_configuration_pb2_grpc.py,sha256=1oboBPFxaTEXt9Aw7EAj8gXHDCNMhZD2VXqocC9l_gk,159
14
+ frogml/_proto/com/jfrog/ml/model/deployment/v1/model_artifact_identifier_pb2.py,sha256=7TCaIZwY3cYX5JKUA1NR8WmkRH0CtLipi4kiaTjeL9E,2331
15
+ frogml/_proto/com/jfrog/ml/model/deployment/v1/model_artifact_identifier_pb2.pyi,sha256=4FFrif0OZFR18xXKuEpZC7sibeKNMMXM49Y-J7VXyGA,4529
16
+ frogml/_proto/com/jfrog/ml/model/deployment/v1/model_artifact_identifier_pb2_grpc.py,sha256=1oboBPFxaTEXt9Aw7EAj8gXHDCNMhZD2VXqocC9l_gk,159
17
+ frogml/_proto/com/jfrog/ml/model/deployment/v1/model_deployment_brief_pb2.py,sha256=r1nMzNPG0MktLtRPTFFif66qEHL0VGHuAoiM2ffXVlk,2306
18
+ frogml/_proto/com/jfrog/ml/model/deployment/v1/model_deployment_brief_pb2.pyi,sha256=H-XA4wfh7t8PLYtfbPINIbWea43ubn8tbFdPN9IjLKs,2628
19
+ frogml/_proto/com/jfrog/ml/model/deployment/v1/model_deployment_brief_pb2_grpc.py,sha256=1oboBPFxaTEXt9Aw7EAj8gXHDCNMhZD2VXqocC9l_gk,159
20
+ frogml/_proto/com/jfrog/ml/model/deployment/v1/model_deployment_filter_pb2.py,sha256=6qhYmErXArD2rOoKeqnlvjwC-6dJo8k0HUcTTMW4oQQ,3889
21
+ frogml/_proto/com/jfrog/ml/model/deployment/v1/model_deployment_filter_pb2.pyi,sha256=gdxw9GSXh-Msfe0ifVSmER-7kHtcU3u0RNCjb93YY-Y,9804
22
+ frogml/_proto/com/jfrog/ml/model/deployment/v1/model_deployment_filter_pb2_grpc.py,sha256=1oboBPFxaTEXt9Aw7EAj8gXHDCNMhZD2VXqocC9l_gk,159
23
+ frogml/_proto/com/jfrog/ml/model/deployment/v1/probes_configuration_pb2.py,sha256=xn_xW0y6JJ0TjyLaJBDVE7UwHO22tQr3nphz7xLGaSM,1833
24
+ frogml/_proto/com/jfrog/ml/model/deployment/v1/probes_configuration_pb2.pyi,sha256=t_EkUDqnMHgXr0ft9IXyfYbIR4vXR3yGzVp-cG0P0G4,2578
25
+ frogml/_proto/com/jfrog/ml/model/deployment/v1/probes_configuration_pb2_grpc.py,sha256=1oboBPFxaTEXt9Aw7EAj8gXHDCNMhZD2VXqocC9l_gk,159
26
+ frogml/_proto/com/jfrog/ml/model/deployment/v1/realtime_deployment_pb2.py,sha256=PhvTR0wld0M7fQFbmQ2vWplyHIDThaM_ZmVHNqcQBCc,1799
27
+ frogml/_proto/com/jfrog/ml/model/deployment/v1/realtime_deployment_pb2.pyi,sha256=tGb_ZZJuwMWmfKBiONnhwxREuREmDpV0x4Ya4DQaqos,2234
28
+ frogml/_proto/com/jfrog/ml/model/deployment/v1/realtime_deployment_pb2_grpc.py,sha256=1oboBPFxaTEXt9Aw7EAj8gXHDCNMhZD2VXqocC9l_gk,159
29
+ frogml/_proto/com/jfrog/ml/model/deployment/v1/resource_configuration_pb2.py,sha256=d3oCCHJywlvPD91GiTB_RveXoUhHyyJOkNJ5d5tGl58,1435
30
+ frogml/_proto/com/jfrog/ml/model/deployment/v1/resource_configuration_pb2.pyi,sha256=FRhxd3AhNEICHElc8iv0gSnRH2zqmIw7Yd98tLWaR78,1253
31
+ frogml/_proto/com/jfrog/ml/model/deployment/v1/resource_configuration_pb2_grpc.py,sha256=1oboBPFxaTEXt9Aw7EAj8gXHDCNMhZD2VXqocC9l_gk,159
2
32
  frogml/_proto/jfml/hosting_gateway/v1/build_upload_url_pb2.py,sha256=pY7-QarLJWbL9uNmZ69RfE7IPVzwpVIhtd3A0wztSNY,1942
3
33
  frogml/_proto/jfml/hosting_gateway/v1/build_upload_url_pb2.pyi,sha256=505I4uUrCmv2hsUw2H5eT-nlkNOCQOWodpvEkH2fHIo,3073
4
34
  frogml/_proto/jfml/hosting_gateway/v1/build_upload_url_pb2_grpc.py,sha256=1oboBPFxaTEXt9Aw7EAj8gXHDCNMhZD2VXqocC9l_gk,159
@@ -692,6 +722,8 @@ frogml/core/clients/location_discovery/__init__.py,sha256=sqGQ75YHFE6nvOcir38fyk
692
722
  frogml/core/clients/location_discovery/client.py,sha256=ZcBbbLqzZ9E7oLyamBTLTpp611LldhfFOSkzWroyIQg,2895
693
723
  frogml/core/clients/logging_client/__init__.py,sha256=1OCHnigQBYThBwGbxCreYA0BgP0HcuLFzNEWd3Yxh-c,34
694
724
  frogml/core/clients/logging_client/client.py,sha256=ZTRRPrcM2cqrZX9T3DvIr0YICrhDK91P4CDP-ei_ZjQ,8599
725
+ frogml/core/clients/model_deployment_manager/__init__.py,sha256=Kp6FTZzsXjvfoCLz8kurr7AIypRGIIdUek7_SBCt7f4,49
726
+ frogml/core/clients/model_deployment_manager/client.py,sha256=VLPgE3WDZOOg9y_mYZSKKYqVSi866vJipvAi5aOlDng,4135
695
727
  frogml/core/clients/model_group_management/__init__.py,sha256=f-nExP4vGWoWMUrRstY8QdtPqXnbsl2Ux0KfFkvGBkg,47
696
728
  frogml/core/clients/model_group_management/client.py,sha256=F8YCbfyphcljb8WxpeY7H7wnPpksyaKQ2ZOKi03RU6M,2016
697
729
  frogml/core/clients/model_management/__init__.py,sha256=vjWVP8MjmK4_A70WOgJqa6x24AeLK-ABjGJtogGzw9w,43
@@ -1123,7 +1155,7 @@ frogml_services_mock/mocks/features_operator_v3_service.py,sha256=v6XdUpiI5T5mog
1123
1155
  frogml_services_mock/mocks/features_set_state_service_api.py,sha256=YaF3X12gCFDKFYFUAH3ZsK2jjbxU1aYYyExwe-F1Zdg,2293
1124
1156
  frogml_services_mock/mocks/feedback_service.py,sha256=yHItKZnlrN75F7D2rIGVrffipRaBCyMIvxK5ZmMVckE,1142
1125
1157
  frogml_services_mock/mocks/file_versioning_service.py,sha256=PF_XyipSF5I8SfCNDYv298p3lMCizgDTZORlSuo4RYQ,2609
1126
- frogml_services_mock/mocks/frogml_mocks.py,sha256=KpIMhgwmboLM08vo6SYep9Vj_tnGL2GiBD2UGwGJjt0,6143
1158
+ frogml_services_mock/mocks/frogml_mocks.py,sha256=16-x7m3pHl9C51SbuVYwDWmBWv4vzEAwEjfykQaSlfM,6336
1127
1159
  frogml_services_mock/mocks/fs_offline_serving_service.py,sha256=rzxL_G8t3PIM-IFuchqkHuUUzlOZfiP5A5IMSeSQynA,2096
1128
1160
  frogml_services_mock/mocks/instance_template_management_service.py,sha256=AZ-QCzrx4d4g5E4XIPqFNhOJPBwb4S90mfVzsn6oNe4,4766
1129
1161
  frogml_services_mock/mocks/integration_management_service.py,sha256=cw45A8EadycTyq3Okx1sgcuWZ-Lz2iPMRin6f4e_0Ws,2775
@@ -1133,6 +1165,7 @@ frogml_services_mock/mocks/job_registry_service_api.py,sha256=gbytsg5mc5yjOYE_LP
1133
1165
  frogml_services_mock/mocks/kube_captain_service_api.py,sha256=0zRthbKSWeIl1qj16tqTg4jiTbUZoJRyPpEOXiESK2A,1598
1134
1166
  frogml_services_mock/mocks/location_discovery_service_api.py,sha256=i_alD-qEZ1SsIFgQew9gibGN47MrPhTfMqnxapJhTbo,3685
1135
1167
  frogml_services_mock/mocks/logging_service.py,sha256=-1FrXhGO5_NNUW7pzajTwGSf1soQC1feLuMwkOAXD7A,7389
1168
+ frogml_services_mock/mocks/model_deployment_manager_service_mock.py,sha256=83BtdT3FLhewmEjvqMLw7hrrKOxp_lLe_hlDIZ72ukI,9743
1136
1169
  frogml_services_mock/mocks/model_group_management_service.py,sha256=tEtBQPExusWI1NiigqEToSDIAforCP1DpVCGXiqfppc,1540
1137
1170
  frogml_services_mock/mocks/model_management_service.py,sha256=3byRc-8Fb5WnXTrWkHj1-S6RA2yfqK1yzX-7fqq_ZNk,4169
1138
1171
  frogml_services_mock/mocks/model_version_manager_service.py,sha256=XzRnAnn0VMY5hW8jP1ngWF-6OYIq8OgatZQ79JyxeMQ,3759
@@ -1144,9 +1177,9 @@ frogml_services_mock/mocks/system_secret_service.py,sha256=ceOR1nfQOGW4ZBcry4Q_l
1144
1177
  frogml_services_mock/mocks/user_application_instance_service_api.py,sha256=Es3s9MnutY0Qsd_FOq_ctKvT-3wHn7-fxah1fvr5Jv4,4100
1145
1178
  frogml_services_mock/mocks/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1146
1179
  frogml_services_mock/mocks/utils/exception_handlers.py,sha256=k_8mez3cwjNjKE9yGQRJUuK95qNQyk_slotIF08IIEE,308
1147
- frogml_services_mock/services_mock.py,sha256=y1_h189Ldu5MdVUW4nj-WMBtvUfkM_aKse7UfAb6Rxk,19419
1180
+ frogml_services_mock/services_mock.py,sha256=hciz4Q2NvjT84DE08sgxfVVDELfD4hitqgoDrZugcjg,19961
1148
1181
  frogml_services_mock/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1149
1182
  frogml_services_mock/utils/service_utils.py,sha256=ZlB0CnB1J6oBn6_m7fQO2U8tKoboHdUa6ljjkRMYNXU,265
1150
- frogml-1.2.40.dist-info/METADATA,sha256=gPjSmQKhg_oYhCMNfkKU7i5mTcFMOr6CAiOGCl6wD5w,5599
1151
- frogml-1.2.40.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
1152
- frogml-1.2.40.dist-info/RECORD,,
1183
+ frogml-1.2.42.dist-info/METADATA,sha256=fTkHE_LzeDdRqF9rzohysGaAPkGhd9tYbv1o5WK2KiM,5599
1184
+ frogml-1.2.42.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
1185
+ frogml-1.2.42.dist-info/RECORD,,
@@ -56,7 +56,9 @@ from frogml_services_mock.mocks.integration_management_service import (
56
56
  from frogml_services_mock.mocks.internal_build_orchestrator_service import (
57
57
  InternalBuildOrchestratorServiceMock,
58
58
  )
59
- from frogml_services_mock.mocks.jfrog_tenant_info_service_mock import JFrogTenantInfoServiceMock
59
+ from frogml_services_mock.mocks.jfrog_tenant_info_service_mock import (
60
+ JFrogTenantInfoServiceMock,
61
+ )
60
62
  from frogml_services_mock.mocks.job_registry_service_api import (
61
63
  JobRegistryServiceApiMock,
62
64
  )
@@ -67,15 +69,20 @@ from frogml_services_mock.mocks.location_discovery_service_api import (
67
69
  LocationDiscoveryServiceApiMock,
68
70
  )
69
71
  from frogml_services_mock.mocks.logging_service import LoggingServiceApiMock
70
- from frogml_services_mock.mocks.model_group_management_service import ModelGroupManagementServiceMock
72
+ from frogml_services_mock.mocks.model_deployment_manager_service_mock import (
73
+ ModelDeploymentManagerMock,
74
+ )
75
+ from frogml_services_mock.mocks.model_group_management_service import (
76
+ ModelGroupManagementServiceMock,
77
+ )
71
78
  from frogml_services_mock.mocks.model_management_service import (
72
79
  ModelsManagementServiceMock,
73
80
  )
74
81
  from frogml_services_mock.mocks.model_version_manager_service import (
75
82
  ModelVersionManagerServiceMock,
76
83
  )
77
- from frogml_services_mock.mocks.repository_service_mock import RepositoryServiceMock
78
84
  from frogml_services_mock.mocks.project_manager_service import ProjectManagerServiceMock
85
+ from frogml_services_mock.mocks.repository_service_mock import RepositoryServiceMock
79
86
  from frogml_services_mock.mocks.secret_service import SecretServiceMock
80
87
  from frogml_services_mock.mocks.self_service_user_service import (
81
88
  SelfServiceUserServiceMock,
@@ -127,3 +134,4 @@ class FrogmlMocks:
127
134
  repository_service: RepositoryServiceMock
128
135
  location_discovery_service: LocationDiscoveryServiceApiMock
129
136
  jfrog_tenant_info_service: JFrogTenantInfoServiceMock
137
+ model_deployment_manager_mock: ModelDeploymentManagerMock
@@ -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
  )