55# SPDX-License-Identifier: Apache-2.0
66
77from .service import Service
8-
8+ from .. utils . decorators import experimental
99
1010class ModelManagement (Service ):
1111 """The Model Management API provides basic resources for monitoring
@@ -20,7 +20,8 @@ class ModelManagement(Service):
2020 'performance tasks' )
2121
2222 # TODO: set ds2MultiType
23- def publish_model (self ,
23+ @classmethod
24+ def publish_model (cls ,
2425 model ,
2526 destination ,
2627 name = None ,
@@ -80,15 +81,16 @@ def publish_model(self,
8081 # Publishes a model that has already been registered in the model
8182 # repository.
8283 # Unlike model_publish service, does not require Code to be specified.
83- r = self .post ('/publish' ,
84- json = request ,
85- params = dict (force = force ,
84+ r = cls .post ('/publish' ,
85+ json = request ,
86+ params = dict (force = force ,
8687 reloadModelTable = reload_model_table ),
87- headers = {'Content-Type' :
88+ headers = {'Content-Type' :
8889 'application/vnd.sas.models.publishing.request.asynchronous+json' })
8990 return r
9091
91- def create_performance_definition (self ,
92+ @classmethod
93+ def create_performance_definition (cls ,
9294 model ,
9395 library_name ,
9496 table_prefix ,
@@ -156,7 +158,7 @@ def create_performance_definition(self,
156158 """
157159 from .model_repository import ModelRepository
158160
159- if '_' in table_prefix :
161+ if not scoring_required and '_' in table_prefix :
160162 raise ValueError (
161163 "Parameter 'table_prefix' cannot contain underscores."
162164 " Received a value of '%s'." ) % table_prefix
@@ -210,11 +212,12 @@ def create_performance_definition(self,
210212 project .get ('variables' , []) if
211213 v .get ('role' ) == 'output' ]
212214
213- return self .post ('/performanceTasks' , json = request ,
214- headers = {
215+ return cls .post ('/performanceTasks' , json = request ,
216+ headers = {
215217 'Content-Type' : 'application/vnd.sas.models.performance.task+json' })
216218
217- def execute_performance_definition (self , definition ):
219+ @classmethod
220+ def execute_performance_definition (cls , definition ):
218221 """Launches a job to run a performance definition.
219222
220223 Parameters
@@ -228,7 +231,118 @@ def execute_performance_definition(self, definition):
228231 The executing job
229232
230233 """
231- definition = self .get_performance_definition (definition )
234+ definition = cls .get_performance_definition (definition )
235+
236+ return cls .post ('/performanceTasks/%s' % definition .id )
237+
238+ @classmethod
239+ @experimental
240+ def list_model_workflow_definition (cls ):
241+ """List all enabled Workflow Processes to execute on Model Project.
242+
243+ Returns
244+ -------
245+ RestObj
246+ The list of workflows
247+
248+ """
249+ from .workflow import Workflow
250+ wf = Workflow ()
251+
252+ return wf .list_enabled_definitions ()
253+
254+ @classmethod
255+ @experimental
256+ def list_model_workflow_prompt (cls , workflowName ):
257+ """List prompt Workflow Processes Definitions.
258+
259+ Parameters
260+ ----------
261+ workflowName : str
262+ Name or ID of an enabled workflow to retrieve inputs
263+
264+ Returns
265+ -------
266+ list
267+ The list of prompts for specific workflow
268+
269+ """
270+ from .workflow import Workflow
271+ wf = Workflow ()
272+
273+ return wf .list_workflow_prompt (workflowName )
274+
275+ @classmethod
276+ @experimental
277+ def list_model_workflow_executed (cls , projectName ):
278+ """List prompt Workflow Processes Definitions.
279+
280+ Parameters
281+ ----------
282+ projectName : str
283+ Name of the Project list executed workflow
284+
285+ Returns
286+ -------
287+ RestObj
288+ List of workflows associated to project
289+
290+ """
291+ from .model_repository import ModelRepository
292+ mr = ModelRepository ()
293+
294+ project = mr .get_project (projectName )
295+
296+ return cls .get ('/workflowProcesses?filter=eq(associations.solutionObjectId,%22' + project ['id' ] + '%22)' )
297+
298+ @classmethod
299+ @experimental
300+ def execute_model_workflow_definition (cls , project_name , workflow_name , input = None ):
301+ """Runs specific Workflow Processes Definitions.
302+
303+ Parameters
304+ ----------
305+ project_name : str
306+ Name of the Project that will execute workflow
307+ workflow_name : str
308+ Name or ID of an enabled workflow to execute
309+ input : dict, optional
310+ Input values for the workflow for initial workflow prompt
311+
312+ Returns
313+ -------
314+ RestObj
315+ The executing workflow
316+
317+ """
318+ from .model_repository import ModelRepository
319+ from .workflow import Workflow
320+
321+ mr = ModelRepository ()
322+ wf = Workflow ()
323+
324+ project = mr .get_project (project_name )
325+
326+ workflow = wf .run_workflow_definition (workflow_name , input = input )
327+
328+ # Associations running workflow to model project, note workflow has to be running
329+ # THINK ABOUT: do we do a check on status of the workflow to determine if it is still running before associating?
330+
331+ input = {"processName" : workflow ['name' ],
332+ "processId" : workflow ['id' ],
333+ "objectType" : "MM_Project" ,
334+ "solutionObjectName" : project_name ,
335+ "solutionObjectId" : project ['id' ],
336+ "solutionObjectUri" : "/modelRepository/projects/" + project ['id' ],
337+ "solutionObjectMediaType" : "application/vnd.sas.models.project+json" }
338+
339+ #Note, you can get a HTTP Error 404: {"errorCode":74052,"message":"The workflow process for id <> cannot be found.
340+ # Associations can only be made to running processes.","details":["correlator:
341+ # e62c5562-2b11-45db-bcb7-933200cb0f0a","traceId: 3118c0fb1eb9702d","path:
342+ # /modelManagement/workflowAssociations"],"links":[],"version":2,"httpStatusCode":404}
343+ # Which is fine and expected like the Visual Experience.
344+ return cls .post ('/workflowAssociations' ,
345+ json = input ,
346+ headers = {'Content-Type' : 'application/vnd.sas.workflow.object.association+json' })
232347
233- return self .post ('/performanceTasks/%s' % definition .id )
234348
0 commit comments