Skip to content

Commit effe779

Browse files
committed
Merge remote-tracking branch 'origin/release/5.1'
2 parents a0c1266 + 403f77f commit effe779

File tree

4 files changed

+173
-0
lines changed

4 files changed

+173
-0
lines changed

dataikuapi/dss/ml.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,50 @@ def get_coefficient_paths(self):
548548
raise ValueError("This model has no coefficient paths")
549549
return DSSCoefficientPaths(data)
550550

551+
## Model export
552+
553+
def get_scoring_jar_stream(self, model_class="model.Model", include_libs=False):
554+
"""
555+
Get a scoring jar for this trained model,
556+
provided that you have the license to do so and that the model is compatible with optimized scoring.
557+
You need to close the stream after download. Failure to do so will result in the DSSClient becoming unusable.
558+
559+
:param str model_class: fully-qualified class name, e.g. "com.company.project.Model"
560+
:param bool include_libs: if True, also packs the required dependencies;
561+
if False, runtime will require the scoring libs given by :func:`DSSClient.scoring_libs`
562+
:returns: a jar file, as a stream
563+
:rtype: file-like
564+
"""
565+
include_libs = "true" if include_libs else "false"
566+
if self.mltask is not None:
567+
return self.mltask.client._perform_raw(
568+
"GET", "/projects/%s/models/lab/%s/%s/models/%s/scoring-jar?fullClassName=%s&includeLibs=%s" %
569+
(self.mltask.project_key, self.mltask.analysis_id, self.mltask.mltask_id, self.mltask_model_id,
570+
model_class, include_libs))
571+
else:
572+
return self.saved_model.client._perform_raw(
573+
"GET", "/projects/%s/savedmodels/%s/versions/%s/scoring-jar?fullClassName=%s&includeLibs=%s" %
574+
(self.saved_model.project_key, self.saved_model.sm_id, self.saved_model_version,
575+
model_class, include_libs))
576+
577+
def get_scoring_pmml_stream(self):
578+
"""
579+
Get a scoring PMML for this trained model,
580+
provided that you have the license to do so and that the model is compatible with PMML scoring
581+
You need to close the stream after download. Failure to do so will result in the DSSClient becoming unusable.
582+
583+
:returns: a PMML file, as a stream
584+
:rtype: file-like
585+
"""
586+
if self.mltask is not None:
587+
return self.mltask.client._perform_raw(
588+
"GET", "/projects/%s/models/lab/%s/%s/models/%s/scoring-pmml" %
589+
(self.mltask.project_key, self.mltask.analysis_id, self.mltask.mltask_id, self.mltask_model_id))
590+
else:
591+
return self.saved_model.client._perform_raw(
592+
"GET", "/projects/%s/savedmodels/%s/versions/%s/scoring-pmml" %
593+
(self.saved_model.project_key, self.saved_model.sm_id, self.saved_model_version))
594+
551595

552596
class DSSClustersFacts(object):
553597
def __init__(self, clusters_facts):

dataikuapi/dss/project.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,47 @@ def export_to_file(self, path, options={}):
7474
f.write(chunk)
7575
f.flush()
7676

77+
########################################################
78+
# Project duplicate
79+
########################################################
80+
81+
def duplicate(self, target_project_key,
82+
target_project_name,
83+
duplication_mode="MINIMAL",
84+
export_analysis_models=True,
85+
export_saved_models=True,
86+
export_git_repository=True,
87+
export_insights_data=True,
88+
remapping={}):
89+
"""
90+
Duplicate the project
91+
92+
:param string target_project_key: The key of the new project
93+
:param string target_project_name: The name of the new project
94+
:param string duplication_mode: can be one of the following values: MINIMAL, SHARING, FULL, NONE
95+
:param bool export_analysis_models:
96+
:param bool export_saved_models:
97+
:param bool export_git_repository:
98+
:param bool export_insights_data:
99+
:param dict remapping: dict of connections to be remapped for the new project
100+
:returns: A dict containing the original and duplicated project's keys
101+
:rtype: :class:`ProjectDuplicateResult`
102+
"""
103+
104+
obj = {
105+
"targetProjectName": target_project_name,
106+
"targetProjectKey": target_project_key,
107+
"duplicationMode": duplication_mode,
108+
"exportAnalysisModels": export_analysis_models,
109+
"exportSavedModels": export_saved_models,
110+
"exportGitRepository": export_git_repository,
111+
"exportInsightsData": export_insights_data,
112+
"remapping": remapping
113+
}
114+
115+
ref = self.client._perform_json("POST", "/projects/%s/duplicate/" % self.project_key, body = obj)
116+
return ref
117+
77118
########################################################
78119
# Project infos
79120
########################################################

dataikuapi/dss/recipe.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,21 @@ def set_definition_and_payload(self, definition):
4949
"PUT", "/projects/%s/recipes/%s" % (self.project_key, self.recipe_name),
5050
body=definition.data)
5151

52+
########################################################
53+
# Recipe status
54+
########################################################
55+
56+
def get_status(self):
57+
"""
58+
Gets the status of this recipe (status messages, engines status, ...)
59+
60+
:return: an object to interact
61+
:rtype: :class:`dataikuapi.dss.recipe.DSSRecipeStatus`
62+
"""
63+
data = self.client._perform_json(
64+
"GET", "/projects/%s/recipes/%s/status" % (self.project_key, self.recipe_name))
65+
return DSSRecipeStatus(self.client, data)
66+
5267
########################################################
5368
# Recipe metadata
5469
########################################################
@@ -89,6 +104,54 @@ def get_object_discussions(self):
89104
"""
90105
return DSSObjectDiscussions(self.client, self.project_key, "RECIPE", self.recipe_name)
91106

107+
class DSSRecipeStatus(object):
108+
def __init__(self, client, data):
109+
"""Do not call that directly, use :meth:`dataikuapi.dss.recipe.DSSRecipe.get_status`"""
110+
self.client = client
111+
self.data = data
112+
113+
def get_selected_engine_details(self):
114+
"""
115+
Gets the selected engine for this recipe (for recipes that support engines)
116+
117+
:returns: a dict of the details of the selected recipe. The dict will contain at least fields 'type' indicating
118+
which engine it is, "statusWarnLevel" which indicates whether the engine is OK / WARN / ERROR
119+
:rtype: dict
120+
"""
121+
if not "selectedEngine" in self.data:
122+
raise ValueError("This recipe doesn't have a selected engine")
123+
return self.data["selectedEngine"]
124+
125+
def get_engines_details(self):
126+
"""
127+
Gets details about all possible engines for this recipe (for recipes that support engines)
128+
129+
:returns: a list of dict of the details of each possible engine. The dict for each engine
130+
will contain at least fields 'type' indicating
131+
which engine it is, "statusWarnLevel" which indicates whether the engine is OK / WARN / ERROR
132+
:rtype: list
133+
"""
134+
if not "engines" in self.data:
135+
raise ValueError("This recipe doesn't have engines")
136+
return self.data["engines"]
137+
138+
def get_status_severity(self):
139+
"""Returns whether the recipe is in SUCCESS, WARNING or ERROR status
140+
141+
:rtype: string
142+
"""
143+
return self.data["allMessagesForFrontend"]["maxSeverity"]
144+
145+
def get_status_messages(self):
146+
"""
147+
Returns status messages for this recipe.
148+
149+
:returns: a list of dict, for each status message. Each dict represents a single message,
150+
and contains at least a "severity" field (SUCCESS, WARNING or ERROR)
151+
and a "message" field
152+
:rtype: list
153+
"""
154+
return self.data["allMessagesForFrontend"]["messages"]
92155

93156
class DSSRecipeDefinitionAndPayload(object):
94157
"""

dataikuapi/dssclient.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -706,6 +706,18 @@ def catalog_index_connections(self, connection_names=[], all_connections=False,
706706
"indexingMode": indexing_mode
707707
})
708708

709+
########################################################
710+
# Model export
711+
########################################################
712+
def get_scoring_libs_stream(self):
713+
"""
714+
Get the scoring libraries jar required for scoring with model jars that don't include libraries.
715+
You need to close the stream after download. Failure to do so will result in the DSSClient becoming unusable.
716+
717+
:returns: a jar file, as a stream
718+
:rtype: file-like
719+
"""
720+
return self._perform_raw("GET", "/resources/scoring-lib-jar")
709721

710722
########################################################
711723
# Auth
@@ -749,6 +761,19 @@ def get_auth_info_from_browser_headers(self, headers_dict, with_secrets=False):
749761
return self._perform_json("POST", "/auth/info-from-browser-headers",
750762
params={"withSecrets": with_secrets}, body=headers_dict)
751763

764+
def create_personal_api_key(self, label):
765+
"""
766+
Creates a personal API key corresponding to the user doing the request.
767+
This can be called if the DSSClient was initialized with an internal
768+
ticket or with a personal API key
769+
770+
:param: label string: Label for the new API key
771+
:returns: a dict of the new API key, containing at least "secret", i.e. the actual secret API key
772+
:rtype dict
773+
"""
774+
return self._perform_json("POST", "/auth/personal-api-keys",
775+
params={"label": label})
776+
752777
########################################################
753778
# Internal Request handling
754779
########################################################

0 commit comments

Comments
 (0)