11from .utils import AnyLoc
22from .dataset import DSSDataset
3+ from .managedfolder import DSSManagedFolder
4+ from .savedmodel import DSSSavedModel
35from .recipe import DSSRecipe , DSSRecipeDefinitionAndPayload
46from .future import DSSFuture
57import logging , json
@@ -13,6 +15,62 @@ 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 create_zone (self , name , color = "#2ab1ac" ):
19+ """
20+ Creates a new flow zone
21+
22+ :returns the newly created zone
23+ :rtype: :class:`DSSFlowZone`
24+ """
25+ data = self .client ._perform_json ("POST" , "/projects/%s/flow/zones" % (self .project .project_key ), body = {
26+ "name" : name ,
27+ "color" :color
28+ })
29+ return DSSFlowZone (self , data )
30+
31+ def get_zone (self , id ):
32+ """
33+ Gets a single Flow zone by id
34+ :rtype: :class:`DSSFlowZone`
35+ """
36+ data = self .client ._perform_json ("GET" , "/projects/%s/flow/zones/%s" % (self .project .project_key , id ))
37+ return DSSFlowZone (self , data )
38+
39+ def get_default_zone (self ):
40+ """
41+ Returns the default zone of the Flow
42+ :rtype: :class:`DSSFlowZone`
43+ """
44+ return self .get_zone ("default" )
45+
46+ def list_zones (self ):
47+ """
48+ Lists all zones in the Flow
49+ :rtype: list of :class:`DSSFlowZone`
50+ """
51+ data = self .client ._perform_json ("GET" , "/projects/%s/flow/zones" % (self .project .project_key ))
52+ return [DSSFlowZone (self , z ) for z in data ]
53+
54+ def get_zone_of_object (self , obj ):
55+ """
56+ Finds the zone to which this object belongs.
57+
58+ If the object is not found in any specific zone, it belongs to the default zone, and the default
59+ zone is returned
60+
61+ :param object obj: A :class:`dataikuapi.dss.dataset.DSSDataset`, :class:`dataikuapi.dss.managedfolder.DSSManagedFolder`,
62+ or :class:`dataikuapi.dss.savedmodel.DSSSavedModel` to search
63+
64+ :rtype: :class:`DSSFlowZone`
65+ """
66+ sr = self ._to_smart_ref (obj )
67+
68+ for zone in self .list_zones ():
69+ for item in zone ._raw ["items" ]:
70+ if json .dumps (sr ) == json .dumps (item ):
71+ return zone
72+ return self .get_default_zone ()
73+
1674 def replace_input_computable (self , current_ref , new_ref , type = "DATASET" ):
1775 """
1876 This method replaces all references to a "computable" (Dataset, Managed Folder or Saved Model)
@@ -86,6 +144,164 @@ def propagate_schema(self, dataset_name, rebuild=False, recipe_update_options={}
86144 return DSSFuture (self .client ,update_future .get ('jobId' , None ), update_future )
87145
88146
147+ def _to_smart_ref (self , obj ):
148+ if isinstance (obj , DSSDataset ):
149+ ot = "DATASET"
150+ elif isinstance (obj , DSSManagedFolder ):
151+ ot = "MANAGED_FOLDER"
152+ elif isinstance (obj , DSSSavedModel ):
153+ ot = "SAVED_MODEL"
154+ elif isinstance (obj , DSSRecipe ):
155+ ot = "RECIPE"
156+ else :
157+ raise ValueError ("Cannot transform to DSS object ref: %s" % obj )
158+
159+ if obj .project_key == self .project .project_key :
160+ return {
161+ "objectId" : obj .id ,
162+ "objectType" : ot
163+ }
164+ else :
165+ return {
166+ "projectKey" : obj .project_key ,
167+ "objectId" : obj .id ,
168+ "objectType" : ot
169+ }
170+
171+ class DSSFlowZone (object ):
172+ """
173+ A zone in the Flow. Do not create this object manually, use :meth:`DSSProjectFlow.get_zone`
174+ or :meth:`DSSProjectFlow.list_zones`
175+ """
176+ def __init__ (self , flow , data ):
177+ self .flow = flow
178+ self .client = flow .client
179+ self ._raw = data
180+
181+ @property
182+ def id (self ):
183+ return self ._raw ["id" ]
184+
185+ @property
186+ def name (self ):
187+ return self ._raw ["name" ]
188+
189+ def __repr__ (self ):
190+ return "<dataikuapi.dss.flow.DSSFlowZone (id=%s, name=%s)>" % (self .id , self .name )
191+
192+ def get_settings (self ):
193+ """Gets the settings of this zone in order to modify them
194+
195+ :rtype: :class:`DSSFlowZoneSettings`
196+ """
197+ return DSSFlowZoneSettings (self )
198+
199+ def _to_native_obj (self , zone_item ):
200+ if not "projectKey" in zone_item or zone_item ["projectKey" ] == self .flow .project .project_key :
201+ p = self .flow .project
202+ else :
203+ p = self .client .get_project (zone_item ["projectKey" ])
204+
205+ if zone_item ["objectType" ] == "DATASET" :
206+ return p .get_dataset (zone_item ["objectId" ])
207+ elif zone_item ["objectType" ] == "MANAGED_FOLDER" :
208+ return p .get_managed_folder (zone_item ["objectId" ])
209+ elif zone_item ["objectType" ] == "SAVED_MODEL" :
210+ return p .get_saved_model (zone_item ["objectId" ])
211+ elif zone_item ["objectType" ] == "RECIPE" :
212+ return p .get_recipe (zone_item ["objectId" ])
213+ else :
214+ raise ValueError ("Cannot transform to DSS object: %s" % zone_item )
215+
216+ def add_item (self , obj ):
217+ """
218+ Adds an item to this zone.
219+
220+ The item will automatically be moved from its existing zone. Additional items may be moved to this zone
221+ as a result of the operation (notably the recipe generating `obj`).
222+
223+ :param object obj: A :class:`dataikuapi.dss.dataset.DSSDataset`, :class:`dataikuapi.dss.managedfolder.DSSManagedFolder`,
224+ or :class:`dataikuapi.dss.savedmodel.DSSSavedModel` to add to the zone
225+ """
226+ self .client ._perform_empty ("POST" , "/projects/%s/flow/zones/%s/items" % (self .flow .project .project_key , self .id ),
227+ body = self .flow ._to_smart_ref (obj ))
228+
229+ #. TBD: if we make "add to default" work propertly, then we don't need thjis
230+ #def remove_item(self, obj):
231+ # """
232+ # Removes an item to this zone.#
233+ #
234+ # :param object obj: A :class:`dataikuapi.dss.dataset.DSSDataset`, :class:`dataikuapi.dss.managedfolder.DSSManagedFolder`,
235+ # or :class:`dataikuapi.dss.savedmodel.DSSSavedModel` to add to the zone
236+ # """
237+ # sr = self._to_smart_ref(obj)
238+ #
239+ # self.client._perform_empty("DELETE", "/projects/%s/flow/zones/%s/items/%s/%s" % (self.flow.project.project_key,
240+ # self.id, sr["objectType"], sr["objectId"]))
241+
242+ @property
243+ def items (self ):
244+ """
245+ The list of items explicitly belonging to this zone.
246+
247+ This list is read-only, to modify it, use :meth:`add_item` and :meth:`remove_item`.
248+
249+ Note that the "default" zone never has any items, as it contains all items that are not
250+ explicitly in a zone. To get the full list of items in a zone, including in the "default" zone, use
251+ the :meth:`get_graph` method.
252+
253+ @rtype list of 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 ["items" ]]
258+
259+ @property
260+ def shared (self ):
261+ """
262+ The list of items that have been explicitly pre-shared to this zone.
263+
264+ This list is read-only, to modify it, use :meth:`add_shared` and :meth:`remove_shared`
265+
266+ @rtype list of shared zone items, either :class:`dataikuapi.dss.dataset.DSSDataset`,
267+ :class:`dataikuapi.dss.managedfolder.DSSManagedFolder`,
268+ or :class:`dataikuapi.dss.savedmodel.DSSSavedModel` or :class:`dataiuapi.dss.recipe.DSSRecipe`
269+ """
270+ return [self ._to_native_obj (i ) for i in self ._raw ["shared" ]]
271+
272+ def get_graph (self ):
273+ data = self .client ._perform_json ("GET" , "/projects/%s/flow/zones/%s/graph" % (self .flow .project .project_key , self .id ))
274+ return DSSProjectFlowGraph (self .flow , data )
275+
276+
277+ class DSSFlowZoneSettings (object ):
278+ """The settings of a flow zone. Do not create this directly, use :meth:`DSSFlowZone.get_settings`"""
279+ def __init__ (self , zone ):
280+ self ._zone = zone
281+ self ._raw = zone ._raw
282+
283+ def get_raw (self ):
284+ """
285+ Gets the raw settings of the zone.
286+
287+ You cannot modify the `items` and `shared` elements through this class. Instead, use :meth:`DSSFlowZone.add_item` and
288+ others
289+ """
290+ return self ._raw
291+
292+ @property
293+ def name (self ):
294+ return self ._raw ["name" ]
295+
296+ @name .setter
297+ def name (self , new_name ):
298+ self ._raw ["name" ] = new_name
299+
300+ def save (self ):
301+ """Saves the settings of the zone"""
302+ self ._zone .client ._perform_empty ("PUT" , "/projects/%s/flow/zones/%s" % (self ._zone .flow .project .project_key , self ._zone .id ),
303+ body = self ._raw )
304+
89305class DSSProjectFlowGraph (object ):
90306
91307 def __init__ (self , flow , data ):
0 commit comments