Skip to content

Commit b348b49

Browse files
author
Cloud User
committed
Added workflow.py and workflow methods for model_management
1 parent b291ca0 commit b348b49

File tree

2 files changed

+198
-1
lines changed

2 files changed

+198
-1
lines changed

src/sasctl/_services/model_management.py

Lines changed: 101 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
from .service import Service
88

9-
109
class ModelManagement(Service):
1110
"""The Model Management API provides basic resources for monitoring
1211
performance, comparing models, and running workflow processes.
@@ -232,3 +231,104 @@ def execute_performance_definition(self, definition):
232231

233232
return self.post('/performanceTasks/%s' % definition.id)
234233

234+
def list_model_workflow_definition(self):
235+
"""List all enabled Workflow Processes to execute on Model Project.
236+
237+
Returns
238+
-------
239+
RestObj
240+
The list of workflows
241+
242+
"""
243+
from .workflow import Workflow
244+
wf = Workflow()
245+
246+
return wf.list_workflow_enableddefinitions()
247+
248+
def list_model_workflow_prompt(self, workflowName):
249+
"""List prompt Workflow Processes Definitions.
250+
251+
Parameters
252+
----------
253+
workflowName : str
254+
Name or ID of an enabled workflow to retrieve inputs
255+
256+
Returns
257+
-------
258+
list
259+
The list of prompts for specific workflow
260+
261+
"""
262+
from .workflow import Workflow
263+
wf = Workflow()
264+
265+
return wf.list_workflow_prompt(workflowName)
266+
267+
268+
def list_model_workflow_executed(self, projectName):
269+
"""List prompt Workflow Processes Definitions.
270+
271+
Parameters
272+
----------
273+
projectName : str
274+
Name of the Project list executed workflow
275+
276+
277+
Returns
278+
-------
279+
RestObj
280+
List of workflows associated to project
281+
282+
"""
283+
from .model_repository import ModelRepository
284+
mr = ModelRepository()
285+
286+
project = mr.get_project(projectName)
287+
288+
return self.get('/workflowProcesses?filter=eq(associations.solutionObjectId,%22'+project['id']+'%22)')
289+
290+
291+
def execute_model_workflow_definition(self, projectName, workflowName, input=None):
292+
"""Runs specific Workflow Processes Definitions.
293+
294+
Parameters
295+
----------
296+
projectName : str
297+
Name of the Project that will execute workflow
298+
workflowName : str
299+
Name or ID of an enabled workflow to execute
300+
input : dict, optional
301+
Input values for the workflow for initial workflow prompt
302+
303+
Returns
304+
-------
305+
RestObj
306+
The executing workflow
307+
308+
"""
309+
from .model_repository import ModelRepository
310+
from .workflow import Workflow
311+
mr = ModelRepository()
312+
wf = Workflow()
313+
314+
project = mr.get_project(projectName)
315+
316+
workflow = wf.run_workflow_definition(workflowName, input=input)
317+
318+
#Associations running workflow to model project, note workflow has to be running
319+
# THINK ABOUT: do we do a check on status of the workflow to determine if it is still running before associating?
320+
321+
input={"processName":workflow['name'],"processId":workflow['id'],"objectType":"MM_Project",
322+
"solutionObjectName":projectName,"solutionObjectId":project['id'],
323+
"solutionObjectUri":"/modelRepository/projects/"+project['id'],
324+
"solutionObjectMediaType":"application/vnd.sas.models.project+json"}
325+
326+
#Note, you can get a HTTP Error 404: {"errorCode":74052,"message":"The workflow process for id <> cannot be found.
327+
# Associations can only be made to running processes.","details":["correlator:
328+
# e62c5562-2b11-45db-bcb7-933200cb0f0a","traceId: 3118c0fb1eb9702d","path:
329+
# /modelManagement/workflowAssociations"],"links":[],"version":2,"httpStatusCode":404}
330+
# Which is fine and expected like the Visual Experience.
331+
return self.post('/workflowAssociations', json=input,
332+
headers={'Content-Type': 'application/vnd.sas.workflow.object.association+json'})
333+
334+

src/sasctl/_services/workflow.py

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
#!/usr/bin/env python
2+
# encoding: utf-8
3+
#
4+
# Copyright © 2019, SAS Institute Inc., Cary, NC, USA. All Rights Reserved.
5+
# SPDX-License-Identifier: Apache-2.0
6+
7+
from .service import Service
8+
9+
class Workflow(Service):
10+
"""The Workflow API provides basic resources for list, prompt details,
11+
and running workflow processes.
12+
"""
13+
_SERVICE_ROOT= '/workflow'
14+
15+
16+
def list_workflow_enableddefinitions(self):
17+
"""List all enabled Workflow Processes Definitions.
18+
19+
Returns
20+
-------
21+
RestObj
22+
The list of workflows
23+
24+
"""
25+
26+
#Additional header to fix 400 ERROR Bad Request
27+
headers={"Accept-Language": "en-US"}
28+
return self.get('/enabledDefinitions', headers=headers)
29+
30+
def list_workflow_prompt(self, name):
31+
"""List prompt Workflow Processes Definitions.
32+
33+
Parameters
34+
----------
35+
name : str
36+
Name or ID of an enabled workflow to retrieve inputs
37+
38+
Returns
39+
-------
40+
list
41+
The list of prompts for specific workflow
42+
43+
"""
44+
45+
ret = self.__find_specific_workflow(name)
46+
if ret is None:
47+
raise ValueError("No Workflow enabled for %s name or id." % name)
48+
49+
if 'prompts' in ret:
50+
return ret['prompts']
51+
else:
52+
# No prompt inputs on workflow
53+
return None
54+
55+
def run_workflow_definition(self, name, input=None):
56+
"""Runs specific Workflow Processes Definitions.
57+
58+
Parameters
59+
----------
60+
name : str
61+
Name or ID of an enabled workflow to execute
62+
input : dict, optional
63+
Input values for the workflow for initial workflow prompt
64+
65+
Returns
66+
-------
67+
RestObj
68+
The executing workflow
69+
70+
"""
71+
72+
workflow = self.__find_specific_workflow(name)
73+
if workflow is None:
74+
raise ValueError("No Workflow enabled for %s name or id." % name)
75+
76+
if input is None:
77+
return self.post('/processes?definitionId=' + workflow['id'],
78+
headers={'Content-Type': 'application/vnd.sas.workflow.variables+json'})
79+
if isinstance(input, dict):
80+
return self.post('/processes?definitionId=' + workflow['id'], json=input,
81+
headers={'Content-Type': 'application/vnd.sas.workflow.variables+json'})
82+
83+
def __find_specific_workflow(self, name):
84+
# Internal helper method
85+
# Finds a workflow with the name (can be a name or id)
86+
# Returns a dict objects of the workflow
87+
listendef = self.list_workflow_enableddefinitions()
88+
for tmp in listendef:
89+
if tmp['name'] == name:
90+
return tmp
91+
elif tmp['id'] == name:
92+
return tmp
93+
94+
# Did not find any enabled workflow with name/id
95+
return None
96+
97+

0 commit comments

Comments
 (0)