Skip to content

Commit 2f6ea8c

Browse files
authored
Merge pull request #114 from dataiku/feature/mes
MES public API
2 parents c6b6f11 + 44db93c commit 2f6ea8c

File tree

3 files changed

+348
-0
lines changed

3 files changed

+348
-0
lines changed

dataikuapi/dss/flow.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from .dataset import DSSDataset
33
from .managedfolder import DSSManagedFolder
44
from .savedmodel import DSSSavedModel
5+
from .modelevaluationstore import DSSModelEvaluationStore
56
from .recipe import DSSRecipe, DSSRecipeDefinitionAndPayload
67
from .future import DSSFuture
78
from .streaming_endpoint import DSSStreamingEndpoint
@@ -144,6 +145,8 @@ def _to_smart_ref(self, obj):
144145
ot = "MANAGED_FOLDER"
145146
elif isinstance(obj, DSSSavedModel):
146147
ot = "SAVED_MODEL"
148+
elif isinstance(obj, DSSModelEvaluationStore):
149+
ot = "MODEL_EVALUATION_STORE"
147150
elif isinstance(obj, DSSRecipe):
148151
ot = "RECIPE"
149152
elif isinstance(obj, DSSStreamingEndpoint):
Lines changed: 298 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,298 @@
1+
from .discussion import DSSObjectDiscussions
2+
3+
from requests import utils
4+
5+
try:
6+
basestring
7+
except NameError:
8+
basestring = str
9+
10+
class DSSModelEvaluationStore(object):
11+
"""
12+
A handle to interact with a model evaluation store on the DSS instance.
13+
14+
Do not create this directly, use :meth:`dataikuapi.dss.DSSProject.get_model_evaluation_store`
15+
"""
16+
def __init__(self, client, project_key, mes_id):
17+
self.client = client
18+
self.project = client.get_project(project_key)
19+
self.project_key = project_key
20+
self.mes_id = mes_id
21+
22+
@property
23+
def id(self):
24+
return self.mes_id
25+
26+
def get_settings(self):
27+
"""
28+
Returns the settings of this model evaluation store.
29+
30+
:rtype: DSSModelEvaluationStoreSettings
31+
"""
32+
data = self.client._perform_json(
33+
"GET", "/projects/%s/modelevaluationstores/%s" % (self.project_key, self.mes_id))
34+
return DSSModelEvaluationStoreSettings(self, data)
35+
36+
37+
########################################################
38+
# Misc
39+
########################################################
40+
41+
def get_zone(self):
42+
"""
43+
Gets the flow zone of this model evaluation store
44+
45+
:rtype: :class:`dataikuapi.dss.flow.DSSFlowZone`
46+
"""
47+
return self.project.get_flow().get_zone_of_object(self)
48+
49+
def move_to_zone(self, zone):
50+
"""
51+
Moves this object to a flow zone
52+
53+
:param object zone: a :class:`dataikuapi.dss.flow.DSSFlowZone` where to move the object
54+
"""
55+
if isinstance(zone, basestring):
56+
zone = self.project.get_flow().get_zone(zone)
57+
zone.add_item(self)
58+
59+
def share_to_zone(self, zone):
60+
"""
61+
Share this object to a flow zone
62+
63+
:param object zone: a :class:`dataikuapi.dss.flow.DSSFlowZone` where to share the object
64+
"""
65+
if isinstance(zone, basestring):
66+
zone = self.project.get_flow().get_zone(zone)
67+
zone.add_shared(self)
68+
69+
def unshare_from_zone(self, zone):
70+
"""
71+
Unshare this object from a flow zone
72+
73+
:param object zone: a :class:`dataikuapi.dss.flow.DSSFlowZone` from where to unshare the object
74+
"""
75+
if isinstance(zone, basestring):
76+
zone = self.project.get_flow().get_zone(zone)
77+
zone.remove_shared(self)
78+
79+
def get_usages(self):
80+
"""
81+
Get the recipes referencing this model evaluation store
82+
83+
Returns:
84+
a list of usages
85+
"""
86+
return self.client._perform_json("GET", "/projects/%s/modelevaluationstores/%s/usages" % (self.project_key, self.mes_id))
87+
88+
def get_object_discussions(self):
89+
"""
90+
Get a handle to manage discussions on the model evaluation store
91+
92+
:returns: the handle to manage discussions
93+
:rtype: :class:`dataikuapi.discussion.DSSObjectDiscussions`
94+
"""
95+
return DSSObjectDiscussions(self.client, self.project_key, "MODEL_EVALUATION_STORE", self.mes_id)
96+
97+
########################################################
98+
# Deletion
99+
########################################################
100+
101+
def delete(self):
102+
"""
103+
Delete the model evaluation store
104+
105+
"""
106+
return self.client._perform_empty("DELETE", "/projects/%s/modelevaluationstores/%s" % (self.project_key, self.mes_id))
107+
108+
109+
########################################################
110+
# Runs
111+
########################################################
112+
113+
def list_model_evaluations(self, as_type=None):
114+
"""
115+
List the model evaluations in this model evaluation store.
116+
117+
:returns: The list of the model evaluations
118+
:rtype: list
119+
"""
120+
items = self.client._perform_json("GET", "/projects/%s/modelevaluationstores/%s/runs/" % (self.project_key, self.mes_id))
121+
if as_type == "objects" or as_type == "object":
122+
return [DSSModelEvaluation(self, item["ref"]["runId"]) for item in items]
123+
else:
124+
return items
125+
126+
def get_model_evaluation(self, run_id):
127+
"""
128+
Get a handle to interact with a specific model evaluations
129+
130+
:param string run_id: the id of the desired model evaluation
131+
132+
:returns: A :class:`dataikuapi.dss.modelevaluationstore.DSSModelEvaluation` model evaluation handle
133+
"""
134+
return DSSModelEvaluation(self, run_id)
135+
136+
def delete_model_evaluations(self, evaluations):
137+
"""
138+
Remove model evaluations from this store
139+
"""
140+
obj = []
141+
for evaluation in evaluations:
142+
if isinstance(evaluation, DSSModelEvaluation):
143+
obj.append(evaluation.run_id)
144+
elif isinstance(evaluation, dict):
145+
obj.append(evaluation['run_id'])
146+
else:
147+
obj.append(evaluation)
148+
self.model_evaluation_store.client._perform_json(
149+
"DELETE", "/projects/%s/modelevaluationstores/%s/runs/" % (self.project_key, self.mes_id, self.run_id), body=obj)
150+
151+
152+
def create_model_evaluation(self, labels=None, prediction_type=None, model_type=None, model_params=None, data_type=None, data_params=None, metric_params=None, active_classifier_threshold=None):
153+
"""
154+
Create a new model evaluation in the model evaluation store, and return a handle to interact with it.
155+
156+
:returns: A :class:`dataikuapi.dss.modelevaluationstore.DSSModelEvaluation` model evaluation handle
157+
"""
158+
obj = {
159+
"labels": labels,
160+
"modelType": model_type,
161+
"modelParams": model_params if model_params is not None else {},
162+
"dataType": data_type,
163+
"dataParams": data_params if data_params is not None else {},
164+
"predictionType": prediction_type,
165+
"activeClassifierThreshold": active_classifier_threshold,
166+
"metricParams": metric_params if metric_params is not None else {}
167+
}
168+
res = self.client._perform_json("POST", "/projects/%s/modelevaluationstores/%s/runs/" % (self.project_key, self.mes_id),
169+
body = obj)
170+
run_id = res['id']
171+
return DSSModelEvaluation(self, run_id)
172+
173+
174+
class DSSModelEvaluationStoreSettings:
175+
"""
176+
A handle on the settings of a model evaluation store
177+
178+
Do not create this class directly, instead use :meth:`dataikuapi.dss.DSSModelEvaluationStore.get_settings`
179+
"""
180+
181+
def __init__(self, model_evaluation_store, settings):
182+
self.model_evaluation_store = model_evaluation_store
183+
self.settings = settings
184+
185+
def get_raw(self):
186+
return self.settings
187+
188+
def save(self):
189+
self.model_evaluation_store.client._perform_empty(
190+
"PUT", "/projects/%s/modelevaluationstores/%s" % (self.model_evaluation_store.project_key, self.model_evaluation_store.mes_id),
191+
body=self.settings)
192+
193+
class DSSModelEvaluation:
194+
"""
195+
A handle on a model evaluation
196+
197+
Do not create this class directly, instead use :meth:`dataikuapi.dss.DSSModelEvaluationStore.get_model_evaluation`
198+
"""
199+
200+
def __init__(self, model_evaluation_store, run_id):
201+
self.model_evaluation_store = model_evaluation_store
202+
self.client = model_evaluation_store.client
203+
# unpack some fields
204+
self.run_id = run_id
205+
self.project_key = model_evaluation_store.project_key
206+
self.mes_id = model_evaluation_store.mes_id
207+
208+
def get_full_info(self):
209+
"""
210+
Retrieve the model evaluation with its performance data
211+
"""
212+
return self.client._perform_json(
213+
"GET", "/projects/%s/modelevaluationstores/%s/runs/%s" % (self.project_key, self.mes_id, self.run_id))
214+
215+
def get_settings(self):
216+
"""
217+
Set the definition of this model evaluation
218+
"""
219+
data = self.client._perform_json(
220+
"GET", "/projects/%s/modelevaluationstores/%s/runs/%s/settings" % (self.project_key, self.mes_id, self.run_id))
221+
return DSSModelEvaluationSettings(self, data)
222+
223+
def delete(self):
224+
"""
225+
Remove this model evaluation
226+
"""
227+
obj = [self.run_id]
228+
self.client._perform_json(
229+
"DELETE", "/projects/%s/modelevaluationstores/%s/runs/" % (self.project_key, self.mes_id), body=obj)
230+
231+
########################################################
232+
# Model evaluation contents
233+
########################################################
234+
235+
def list_contents(self):
236+
"""
237+
Get the list of files in the model evaluation
238+
239+
Returns:
240+
the list of files, as a JSON object
241+
"""
242+
return self.client._perform_json(
243+
"GET", "/projects/%s/modelevaluationstores/%s/runs/%s/contents" % (self.project_key, self.mes_id, self.run_id))
244+
245+
def get_file(self, path):
246+
"""
247+
Get a file from the model evaluation
248+
249+
Returns:
250+
the file's content, as a stream
251+
"""
252+
return self.client._perform_raw(
253+
"GET", "/projects/%s/modelevaluationstores/%s/runs/%s/contents/%s" % (self.project_key, self.mes_id, self.run_id, utils.quote(path)))
254+
255+
def delete_file(self, path):
256+
"""
257+
Delete a file from the model evaluation
258+
"""
259+
return self.client._perform_empty(
260+
"DELETE", "/projects/%s/modelevaluationstores/%s/runs/%s/contents/%s" % (self.project_key, self.mes_id, self.run_id, utils.quote(path)))
261+
262+
def put_file(self, path, f):
263+
"""
264+
Upload the file to the model evaluation
265+
266+
Args:
267+
f: the file contents, as a stream
268+
path: the path of the file
269+
"""
270+
return self.client._perform_json_upload(
271+
"POST", "/projects/%s/modelevaluationstores/%s/runs/%s/contents/%s" % (self.project_key, self.mes_id, self.run_id, utils.quote(path)),
272+
"", f)
273+
274+
class DSSModelEvaluationSettings:
275+
"""
276+
A handle on the settings of a model evaluation
277+
278+
Do not create this class directly, instead use :meth:`dataikuapi.dss.DSSModelEvaluation.get_settings`
279+
"""
280+
281+
def __init__(self, model_evaluation, settings):
282+
self.model_evaluation = model_evaluation
283+
self.settings = settings
284+
# unpack some fields
285+
self.client = model_evaluation.client
286+
self.run_id = model_evaluation.run_id
287+
self.project_key = model_evaluation.project_key
288+
self.mes_id = model_evaluation.mes_id
289+
290+
def get_raw(self):
291+
return self.settings
292+
293+
def save(self):
294+
return self.client._perform_json(
295+
"PUT", "/projects/%s/modelevaluationstores/%s/runs/%s/settings" % (self.project_key, self.mes_id, self.run_id),
296+
body=self.settings)
297+
298+

dataikuapi/dss/project.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from . import recipe
66
from .managedfolder import DSSManagedFolder
77
from .savedmodel import DSSSavedModel
8+
from .modelevaluationstore import DSSModelEvaluationStore
89
from .job import DSSJob, DSSJobWaiter
910
from .scenario import DSSScenario, DSSScenarioListItem
1011
from .continuousactivity import DSSContinuousActivity
@@ -694,6 +695,52 @@ def create_managed_folder(self, name, folder_type=None, connection_name="filesys
694695
return DSSManagedFolder(self.client, self.project_key, odb_id)
695696

696697

698+
########################################################
699+
# Model evaluation stores
700+
########################################################
701+
702+
def list_model_evaluation_stores(self, as_type=None):
703+
"""
704+
List the model evaluation stores in this project.
705+
706+
:returns: The list of the model evaluation stores
707+
:rtype: list
708+
"""
709+
items = self.client._perform_json("GET", "/projects/%s/modelevaluationstores/" % self.project_key)
710+
if as_type == "objects" or as_type == "object":
711+
return [DSSModelEvaluationStore(self.client, self.project_key, item["id"]) for item in items]
712+
else:
713+
return items
714+
715+
def get_model_evaluation_store(self, mes_id):
716+
"""
717+
Get a handle to interact with a specific model evaluation store
718+
719+
:param string mes_id: the id of the desired model evaluation store
720+
721+
:returns: A :class:`dataikuapi.dss.modelevaluationstore.DSSModelEvaluationStore` model evaluation store handle
722+
"""
723+
return DSSModelEvaluationStore(self.client, self.project_key, mes_id)
724+
725+
def create_model_evaluation_store(self, name, mes_id=None):
726+
"""
727+
Create a new model evaluation store in the project, and return a handle to interact with it.
728+
729+
:param string name: the name for the new model evaluation store
730+
:param string mes_id optional: the id for the new model evaluation store
731+
732+
:returns: A :class:`dataikuapi.dss.modelevaluationstore.DSSModelEvaluationStore` model evaluation store handle
733+
"""
734+
obj = {
735+
"id" : mes_id,
736+
"projectKey" : self.project_key,
737+
"name" : name
738+
}
739+
res = self.client._perform_json("POST", "/projects/%s/modelevaluationstores/" % self.project_key,
740+
body = obj)
741+
mes_id = res['id']
742+
return DSSModelEvaluationStore(self.client, self.project_key, mes_id)
743+
697744
########################################################
698745
# Jobs
699746
########################################################

0 commit comments

Comments
 (0)