Skip to content

Commit 1d62772

Browse files
committed
Initial API client for flow zones
1 parent 26d6d0f commit 1d62772

3 files changed

Lines changed: 210 additions & 1 deletion

File tree

dataikuapi/dss/dataset.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ def __init__(self, client, project_key, dataset_name):
5959
self.project_key = project_key
6060
self.dataset_name = dataset_name
6161

62+
@property
63+
def id(self):
64+
return self.dataset_name
65+
6266
@property
6367
def name(self):
6468
return self.dataset_name

dataikuapi/dss/flow.py

Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
from .utils import AnyLoc
22
from .dataset import DSSDataset
3+
from .managedfolder import DSSManagedFolder
4+
from .savedmodel import DSSSavedModel
35
from .recipe import DSSRecipe, DSSRecipeDefinitionAndPayload
46
from .future import DSSFuture
57
import logging, json
@@ -13,6 +15,49 @@ def get_graph(self):
1315
data = self.client._perform_json("GET", "/projects/%s/flow/graph/" % (self.project.project_key))
1416
return DSSProjectFlowGraph(self, data)
1517

18+
def get_zone(self, id):
19+
"""
20+
Gets a single Flow zone by id
21+
:rtype: :class:`DSSFlowZone`
22+
"""
23+
data = self.client._perform_json("GET", "/projects/%s/flow/zones/%s" % (self.project.project_key, id))
24+
return DSSFlowZone(self, data)
25+
26+
def get_default_zone(self):
27+
"""
28+
Returns the default zone of the Flow
29+
:rtype: :class:`DSSFlowZone`
30+
"""
31+
return self.get_zone("default")
32+
33+
def list_zones(self):
34+
"""
35+
Lists all zones in the Flow
36+
:rtype: list of :class:`DSSFlowZone`
37+
"""
38+
data = self.client._perform_json("GET", "/projects/%s/flow/zones" % (self.project.project_key))
39+
return [DSSFlowZone(self, z) for z in data]
40+
41+
def get_zone_of_object(self, obj):
42+
"""
43+
Finds the zone to which this object belongs.
44+
45+
If the object is not found in any specific zone, it belongs to the default zone, and the default
46+
zone is returned
47+
48+
:param object obj: A :class:`dataikuapi.dss.dataset.DSSDataset`, :class:`dataikuapi.dss.managedfolder.DSSManagedFolder`,
49+
or :class:`dataikuapi.dss.savedmodel.DSSSavedModel` to search
50+
51+
:rtype: :class:`DSSFlowZone`
52+
"""
53+
sr = self._to_smart_ref(obj)
54+
55+
for zone in self.list_zones():
56+
for item in zone._raw["items"]:
57+
if json.dumps(sr) == json.dumps(item):
58+
return zone
59+
return self.get_default_zone()
60+
1661
def replace_input_computable(self, current_ref, new_ref, type="DATASET"):
1762
"""
1863
This method replaces all references to a "computable" (Dataset, Managed Folder or Saved Model)
@@ -86,6 +131,163 @@ def propagate_schema(self, dataset_name, rebuild=False, recipe_update_options={}
86131
return DSSFuture(self.client,update_future.get('jobId', None), update_future)
87132

88133

134+
def _to_smart_ref(self, obj):
135+
if isinstance(obj, DSSDataset):
136+
ot = "DATASET"
137+
elif isinstance(obj, DSSManagedFolder):
138+
ot = "MANAGED_FOLDER"
139+
elif isinstance(obj, DSSSavedModel):
140+
ot = "SAVED_MODEL"
141+
elif isinstance(obj, DSSRecipe):
142+
ot = "RECIPE"
143+
else:
144+
raise ValueError("Cannot transform to DSS object ref: %s" % obj)
145+
146+
if obj.project_key == self.project.project_key:
147+
return {
148+
"objectId" : obj.id,
149+
"objectType": ot
150+
}
151+
else:
152+
return {
153+
"projectKey" : obj.project_key,
154+
"objectId" : obj.id,
155+
"objectType": ot
156+
}
157+
158+
class DSSFlowZone(object):
159+
"""
160+
A zone in the Flow. Do not create this object manually, use :meth:`DSSProjectFlow.get_zone`
161+
or :meth:`DSSProjectFlow.list_zones`
162+
"""
163+
def __init__(self, flow, data):
164+
self.flow = flow
165+
self.client = flow.client
166+
self._raw = data
167+
168+
@property
169+
def id(self):
170+
return self._raw["id"]
171+
172+
@property
173+
def name(self):
174+
return self._raw["name"]
175+
176+
def __repr__(self):
177+
return "<dataikuapi.dss.flow.DSSFlowZone (id=%s, name=%s)>" % (self.id, self.name)
178+
179+
def get_settings(self):
180+
"""Gets the settings of this zone in order to modify them
181+
182+
:rtype: :class:`DSSFlowZoneSettings`
183+
"""
184+
return DSSFlowZoneSettings(self)
185+
186+
def _to_native_obj(self, zone_item):
187+
if not "projectKey" in zone_item or zone_item["projectKey"] == self.flow.project.project_key:
188+
p = self.flow.project
189+
else:
190+
p = self.client.get_project(zone_item["projectKey"])
191+
192+
if zone_item["objectType"] == "DATASET":
193+
return p.get_dataset(zone_item["objectId"])
194+
elif zone_item["objectType"] == "MANAGED_FOLDER":
195+
return p.get_managed_folder(zone_item["objectId"])
196+
elif zone_item["objectType"] == "SAVED_MODEL":
197+
return p.get_saved_model(zone_item["objectId"])
198+
elif zone_item["objectType"] == "RECIPE":
199+
return p.get_recipe(zone_item["objectId"])
200+
else:
201+
raise ValueError("Cannot transform to DSS object: %s" % zone_item)
202+
203+
def add_item(self, obj):
204+
"""
205+
Adds an item to this zone.
206+
207+
The item will automatically be moved from its existing zone. Additional items may be moved to this zone
208+
as a result of the operation (notably the recipe generating `obj`).
209+
210+
:param object obj: A :class:`dataikuapi.dss.dataset.DSSDataset`, :class:`dataikuapi.dss.managedfolder.DSSManagedFolder`,
211+
or :class:`dataikuapi.dss.savedmodel.DSSSavedModel` to add to the zone
212+
"""
213+
self.client._perform_empty("POST", "/projects/%s/flow/zones/%s/items" % (self.flow.project.project_key, self.id),
214+
body=self.flow._to_smart_ref(obj))
215+
216+
#. TBD: if we make "add to default" work propertly, then we don't need thjis
217+
#def remove_item(self, obj):
218+
# """
219+
# Removes an item to this zone.#
220+
#
221+
# :param object obj: A :class:`dataikuapi.dss.dataset.DSSDataset`, :class:`dataikuapi.dss.managedfolder.DSSManagedFolder`,
222+
# or :class:`dataikuapi.dss.savedmodel.DSSSavedModel` to add to the zone
223+
# """
224+
# sr = self._to_smart_ref(obj)
225+
#
226+
# self.client._perform_empty("DELETE", "/projects/%s/flow/zones/%s/items/%s/%s" % (self.flow.project.project_key,
227+
# self.id, sr["objectType"], sr["objectId"]))
228+
229+
@property
230+
def items(self):
231+
"""
232+
The list of items explicitly belonging to this zone.
233+
234+
This list is read-only, to modify it, use :meth:`add_item` and :meth:`remove_item`.
235+
236+
Note that the "default" zone never has any items, as it contains all items that are not
237+
explicitly in a zone. To get the full list of items in a zone, including in the "default" zone, use
238+
the :meth:`get_graph` method.
239+
240+
@rtype list of zone items, either :class:`dataikuapi.dss.dataset.DSSDataset`,
241+
:class:`dataikuapi.dss.managedfolder.DSSManagedFolder`,
242+
or :class:`dataikuapi.dss.savedmodel.DSSSavedModel` or :class:`dataiuapi.dss.recipe.DSSRecipe`
243+
"""
244+
return [self._to_native_obj(i) for i in self._raw["items"]]
245+
246+
@property
247+
def shared(self):
248+
"""
249+
The list of items that have been explicitly pre-shared to this zone.
250+
251+
This list is read-only, to modify it, use :meth:`add_shared` and :meth:`remove_shared`
252+
253+
@rtype list of shared zone items, either :class:`dataikuapi.dss.dataset.DSSDataset`,
254+
:class:`dataikuapi.dss.managedfolder.DSSManagedFolder`,
255+
or :class:`dataikuapi.dss.savedmodel.DSSSavedModel` or :class:`dataiuapi.dss.recipe.DSSRecipe`
256+
"""
257+
return [self._to_native_obj(i) for i in self._raw["shared"]]
258+
259+
def get_graph(self):
260+
data = self.client._perform_json("GET", "/projects/%s/flow/zones/%s/graph" % (self.flow.project.project_key, self.id))
261+
return DSSProjectFlowGraph(self.flow, data)
262+
263+
class DSSFlowZoneSettings(object):
264+
"""The settings of a flow zone. Do not create this directly, use :meth:`DSSFlowZone.get_settings`"""
265+
def __init__(self, zone):
266+
self._zone = zone
267+
self._raw = zone._raw
268+
269+
def get_raw(self):
270+
"""
271+
Gets the raw settings of the zone.
272+
273+
You cannot modify the `items` and `shared` elements through this class. Instead, use :meth:`DSSFlowZone.add_item` and
274+
others
275+
"""
276+
return self._raw
277+
278+
@property
279+
def name(self):
280+
return self._raw["name"]
281+
282+
@name.setter
283+
def name(self, new_name):
284+
self._raw["name"] = new_name
285+
286+
def save(self):
287+
"""Saves the settings of the zone"""
288+
self._zone.client._perform_empty("PUT", "/projects/%s/flow/zones/%s" % (self._zone.flow.project.project_key, self._zone.id),
289+
body=self._raw)
290+
89291
class DSSProjectFlowGraph(object):
90292

91293
def __init__(self, flow, data):

dataikuapi/dss/savedmodel.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,11 @@ def __init__(self, client, project_key, sm_id):
1414
self.client = client
1515
self.project_key = project_key
1616
self.sm_id = sm_id
17+
18+
@property
19+
def id(self):
20+
return self.sm_id
1721

18-
1922
########################################################
2023
# Versions
2124
########################################################

0 commit comments

Comments
 (0)