1- from .dataset import DSSDataset
2- from .recipe import DSSRecipe
3- from .managedfolder import DSSManagedFolder
4- from .savedmodel import DSSSavedModel
5- from .job import DSSJob
6- from .scenario import DSSScenario
7- from .apiservice import DSSAPIService
8- import sys
1+ from dataikuapi .utils import DataikuException
2+
93
104class DSSPluginSettings (object ):
115 """
@@ -30,6 +24,7 @@ def save(self):
3024 """Saves the settings to DSS"""
3125 self .client ._perform_empty ("POST" , "/plugins/%s/settings" % (self .plugin_id ), body = self .settings )
3226
27+
3328class DSSPlugin (object ):
3429 """
3530 A plugin on the DSS instance
@@ -116,6 +111,41 @@ def update_from_git(self, repository_url, checkout = "master", subpath=None):
116111 })
117112 return self .client .get_future (ret ["jobId" ])
118113
114+ ########################################################
115+ # Plugin uninstall/delete
116+ ########################################################
117+
118+ def list_usages (self , project_key = None ):
119+ """
120+ Get the list of usages of the plugin.
121+
122+ :param str project_key: optional key of project where to look for usages. Default is None and looking in all projects.
123+ :return: a :class:`DSSPluginUsages`
124+ """
125+ return DSSPluginUsages (
126+ self .client ._perform_json ("GET" , "/plugins/{pluginId}/actions/listUsages" .format (pluginId = self .plugin_id ),
127+ params = {"projectKey" : project_key })
128+ )
129+
130+ def delete (self , force = False ):
131+ """
132+ Delete a plugin.
133+
134+ If not forced (default), pre-deletion checks will be run (as by :func:`prepare_delete` and the deletion will be
135+ performed if and only if no usage of the plugin is detected and no error occurred during usages analysis.
136+
137+ :param bool force: if True, plugin will be deleted even if usages are found or errors occurred during usages
138+ analysis. Default is False.
139+ :return: a :class:`dataikuapi.dssfuture.DSSFuture`
140+ """
141+
142+ params = {
143+ "force" : force
144+ }
145+ ret = self .client ._perform_json ("POST" , "/plugins/{pluginId}/actions/delete" .format (pluginId = self .plugin_id ),
146+ body = params )
147+ return self .client .get_future (ret .get ("jobId" , None ))
148+
119149 ########################################################
120150 # Managing the dev plugin's contents
121151 ########################################################
@@ -147,4 +177,88 @@ def put_file(self, path, f):
147177 data = f .read () # eat it all, because making it work with a path variable and a MultifilePart in swing looks complicated
148178 return self .client ._perform_empty ("POST" , "/plugins/%s/contents/%s" % (self .plugin_id , path ), raw_body = data )
149179
150-
180+
181+ class DSSPluginUsage (object ):
182+ """
183+ Information on a usage of an element of a plugin.
184+
185+ Has the following properties:
186+ - element_kind: webapps, python-formats,...
187+ - element_type: type name of the element
188+ - object_id: id of the object using the plugin element. Can be None.
189+ - object_type: type of the object using the plugin element. Can be None.
190+ - project_key: project key of the object using the plugin element. Can be None.
191+ """
192+ def __init__ (self , data ):
193+ """
194+ Instantiate a DSSPluginUsage from the dict of its properties.
195+ :param dict data: dict of properties
196+ """
197+ self .element_kind = data ["elementKind" ]
198+ self .element_type = data ["elementType" ]
199+ self .object_id = data .get ("objectId" , None )
200+ self .object_type = data .get ("objectType" , None )
201+ self .project_key = data .get ("projectKey" , None )
202+
203+
204+ class DSSMissingType (object ):
205+ """
206+ Information on a type not found while analyzing usages of a plugin.
207+
208+ Has the following properties:
209+ - missing type: the missing type
210+ - object_id: id of the object depending on the missing type. Can be None.
211+ - object_type: type of the object depending on the missing type. Can be None.
212+ - project_key: project key of the object depending on the missing type. Can be None.
213+ """
214+ def __init__ (self , data ):
215+ """
216+ Instantiate a DSSMissingType from the dict of its properties
217+ :param dict data: dictionary of properties
218+ """
219+ self .missing_type = data ["missingType" ]
220+ self .object_id = data .get ("objectId" , None )
221+ self .object_type = data .get ("objectType" , None )
222+ self .project_key = data .get ("projectKey" , None )
223+
224+
225+ class DSSPluginUsages (object ):
226+ """
227+ Information on the usages of a plugin.
228+
229+ Has the following properties:
230+ - usages (list of :class:`DSSPluginUsage`)
231+ - missing_types (a list of :class:`DSSMissingType`).
232+
233+ Some custom types may not be found during usage analysis, typically when a plugin was removed
234+ but is still used. This prevents some detailed analysis and may hide some uses.
235+ This information is provided in missing_types.
236+ """
237+ def __init__ (self , data ):
238+ """
239+ Initialize a DSSPluginUsages from a dict of its properties
240+
241+ :param dict data: the usages as json dict
242+ """
243+ self ._data = data
244+ self .usages = []
245+ self .missing_types = []
246+ for json_usage in data .get ("usages" , []):
247+ self .usages .append (DSSPluginUsage (json_usage ))
248+ for json_missing_type in data .get ("missingTypes" ):
249+ self .missing_types .append (DSSMissingType (json_missing_type ))
250+
251+ def get_raw (self ):
252+ """
253+ Get plugin usages as a dictionary.
254+ :rtype: dict
255+ """
256+ return self ._data
257+
258+ def maybe_used (self ):
259+ """
260+ Returns true if the plugin maybe in use, as usages of the plugin were found, or errors
261+ encountered during analysis.
262+ :return:
263+ """
264+ return not (not self .usages and not self .missing_types )
0 commit comments