Skip to content

Commit 306043e

Browse files
author
Cloud User
committed
Fix SAS models project variables so performance definitions can be created quickly, added outputs to sas datastep code
1 parent 62d7558 commit 306043e

File tree

2 files changed

+68
-6
lines changed

2 files changed

+68
-6
lines changed

src/sasctl/tasks.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -207,10 +207,26 @@ def get_version(x):
207207
# If model is a CASTable then assume it holds an ASTORE model.
208208
# Import these via a ZIP file.
209209
if 'swat.cas.table.CASTable' in str(type(model)):
210-
zipfile = utils.create_package(model)
210+
zipfile = utils.create_package(model, input=input)
211211

212212
if create_project:
213-
project = mr.create_project(project, repo_obj)
213+
outvar=[]
214+
invar=[]
215+
import zipfile as zp
216+
import copy
217+
zipfilecopy = copy.deepcopy(zipfile)
218+
tmpzip=zp.ZipFile(zipfilecopy)
219+
if "outputVar.json" in tmpzip.namelist():
220+
outvar=json.loads(tmpzip.read("outputVar.json"))
221+
for tmp in outvar:
222+
tmp.update({'role':'output'})
223+
if "inputVar.json" in tmpzip.namelist():
224+
invar=json.loads(tmpzip.read("inputVar.json"))
225+
for tmp in invar:
226+
if tmp['role'] != 'input':
227+
tmp['role']='input'
228+
vars=invar + outvar
229+
project = mr.create_project(project, repo_obj, variables=vars)
214230

215231
model = mr.import_model_from_zip(name, project, zipfile,
216232
version=version)

src/sasctl/utils/astore.py

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,21 @@
2020
swat = None
2121

2222

23-
def create_package(table):
23+
def create_package(table, input=None):
2424
"""Create an importable model package from a CAS table.
2525
2626
Parameters
2727
----------
2828
table : swat.CASTable
2929
The CAS table containing an ASTORE or score code.
30+
input : DataFrame, type, list of type, or dict of str: type, optional
31+
The expected type for each input value of the target function.
32+
Can be omitted if target function includes type hints. If a DataFrame
33+
is provided, the columns will be inspected to determine type information.
34+
If a single type is provided, all columns will be assumed to be that type,
35+
otherwise a list of column types or a dictionary of column_name: type
36+
may be provided.
37+
3038
3139
Returns
3240
-------
@@ -45,18 +53,26 @@ def create_package(table):
4553
assert isinstance(table, swat.CASTable)
4654

4755
if 'DataStepSrc' in table.columns:
48-
return create_package_from_datastep(table)
56+
#Input only passed to datastep
57+
return create_package_from_datastep(table, input=input)
4958
else:
5059
return create_package_from_astore(table)
5160

5261

53-
def create_package_from_datastep(table):
62+
def create_package_from_datastep(table, input=None):
5463
"""Create an importable model package from a score code table.
5564
5665
Parameters
5766
----------
5867
table : swat.CASTable
5968
The CAS table containing the score code.
69+
input : DataFrame, type, list of type, or dict of str: type, optional
70+
The expected type for each input value of the target function.
71+
Can be omitted if target function includes type hints. If a DataFrame
72+
is provided, the columns will be inspected to determine type information.
73+
If a single type is provided, all columns will be assumed to be that type,
74+
otherwise a list of column types or a dictionary of column_name: type
75+
may be provided.
6076
6177
Returns
6278
-------
@@ -73,11 +89,41 @@ def create_package_from_datastep(table):
7389

7490
dscode = table.to_frame().loc[0, 'DataStepSrc']
7591

92+
#TODO: Extract inputs into file
93+
94+
#Find outputs from ds code
95+
output_vars=[]
96+
for sasline in dscode.split('\n'):
97+
if sasline.strip().startswith('label'):
98+
output_var=dict()
99+
for tmp in sasline.split('='):
100+
if 'label' in tmp:
101+
ovarname=tmp.split('label')[1].strip()
102+
output_var.update({"name":ovarname})
103+
#Determine type of variable is decimal or string
104+
if "length " + ovarname in dscode:
105+
sastype=dscode.split("length " + ovarname)[1].split(';')[0].strip()
106+
if "$" in sastype:
107+
output_var.update({"type":"string"})
108+
output_var.update({"length":sastype.split("$")[1]})
109+
else:
110+
output_var.update({"type":"decimal"})
111+
output_var.update({"length":sastype})
112+
else:
113+
#If no length for varaible, default is decimal, 8
114+
output_var.update({"type":"decimal"})
115+
output_var.update({"length":8})
116+
else:
117+
output_var.update({"description":tmp.split(';')[0].strip().strip("'")})
118+
output_vars.append(output_var)
119+
76120
file_metadata = [{'role': 'score', 'name': 'dmcas_scorecode.sas'}]
77121

78122
zip_file = _build_zip_from_files({
79123
'fileMetadata.json': file_metadata,
80-
'dmcas_scorecode.sas': dscode
124+
'dmcas_scorecode.sas': dscode,
125+
'ModelProperties.json': {"scoreCodeType":"dataStep"},
126+
'outputVar.json': output_vars
81127
})
82128

83129
return zip_file

0 commit comments

Comments
 (0)