def test_score_mas(self, iris_dataset, request): from sasctl.services import microanalytic_score as mas module_name = request.config.cache.get('MAS_MODULE_NAME', None) assert module_name is not None # Retrieve the module from MAS module = mas.get_module(module_name) assert module.name == module_name # Create Python methods for the model steps module = mas.define_steps(module) # Call .predict() x = iris_dataset.iloc[0, :] assert hasattr(module, 'predict') result = module.predict(x) assert isinstance(result, six.string_types) assert result in ('setosa', 'virginica', 'versicolor') # Call .predict_proba() assert hasattr(module, 'predict_proba') probs = module.predict_proba(x) assert len(probs) == 3 assert all(isinstance(p, float) for p in probs) assert round(sum(probs), 5) == 1.0
def test_score_sklearn(self): from sasctl.services import microanalytic_score as mas m = mas.get_module(SCIKIT_MODEL_NAME.replace(' ', '')) m = mas.define_steps(m) r = m.predict(sepalwidth=1, sepallength=2, petallength=3, petalwidth=4) assert r == 'virginica'
def test_score_sklearn(self): from sasctl.services import microanalytic_score as mas m = mas.get_module(SCIKIT_MODEL_NAME.replace(' ', '')) m = mas.define_steps(m) r = m.score(sepalwidth=1, sepallength=2, petallength=3, petalwidth=4) assert isinstance(r, tuple) pytest.xfail('PyMAS integration not yet working.') assert r['rc'] is None
def test_call_python_module_steps_pandas(self): pd = pytest.importorskip('pandas') r = mas.define_steps(self.MODULE_NAME) df = pd.DataFrame(dict(var1=[1], var2=['test'])) assert (6, 'TEST') == r.myfunction(df.iloc[0, :]) df = pd.DataFrame(dict(var1=[1.5], var2=[3])) assert r.myfunction2(df.iloc[0, :]) == 4.5
def test_score_mas(self, boston_dataset, request): from sasctl.services import microanalytic_score as mas module_name = request.config.cache.get('MAS_MODULE_NAME', None) assert module_name is not None # Retrieve the module from MAS module = mas.get_module(module_name) assert module.name == module_name # Create Python methods for the model steps module = mas.define_steps(module) assert hasattr(module, 'score') result = module.score(boston_dataset.iloc[0, :]) assert round(result, 4) == 30.0038
def test_score_mas(self, boston_dataset, request): from sasctl.services import microanalytic_score as mas module_name = request.config.cache.get('MAS_MODULE_NAME', None) assert module_name is not None # Retrieve the module from MAS module = mas.get_module(module_name) assert module.name == module_name # Create Python methods for the model steps module = mas.define_steps(module) assert hasattr(module, 'predict') result = module.predict(boston_dataset.iloc[0, :]) # Don't think order of rows is guaranteed. assert isinstance(result, float) assert result > 1
def test_define_steps(): # Mock module to be returned module = RestObj(name='unittestmodule', stepIds=['step1', 'step2']) # Mock module step with no inputs step1 = RestObj(id='post') # Mock module step with multiple inputs step2 = RestObj({ "id": "score", "inputs": [{ "name": "age", "type": "decimal", "dim": 0, "size": 0 }, { "name": "b", "type": "decimal", "dim": 0, "size": 0 }, { "name": "chas", "type": "decimal", "dim": 0, "size": 0 }, { "name": "crim", "type": "decimal", "dim": 0, "size": 0 }, { "name": "dis", "type": "decimal", "dim": 0, "size": 0 }, { "name": "indus", "type": "decimal", "dim": 0, "size": 0 }, { "name": "lstat", "type": "decimal", "dim": 0, "size": 0 }, { "name": "nox", "type": "decimal", "dim": 0, "size": 0 }, { "name": "ptratio", "type": "decimal", "dim": 0, "size": 0 }, { "name": "rad", "type": "decimal", "dim": 0, "size": 0 }, { "name": "rm", "type": "decimal", "dim": 0, "size": 0 }, { "name": "tax", "type": "decimal", "dim": 0, "size": 0 }, { "name": "zn", "type": "decimal", "dim": 0, "size": 0 }], "outputs": [{ "name": "em_prediction", "type": "decimal", "dim": 0, "size": 0 }, { "name": "p_price", "type": "decimal", "dim": 0, "size": 0 }, { "name": "_warn_", "type": "string", "dim": 0, "size": 4 }] }) with mock.patch( 'sasctl._services.microanalytic_score.MicroAnalyticScore.get_module' ) as get_module: with mock.patch( 'sasctl._services.microanalytic_score.MicroAnalyticScore' '.get_module_step') as get_step: get_module.return_value = module get_step.side_effect = [step1, step2] result = mas.define_steps(None) for step in get_step.side_effect: assert hasattr(result, step.id)
def publish_model(model, destination, code=None, max_retries=60, replace=False, **kwargs): """Publish a model to a configured publishing destination. Parameters ---------- model : str or dict The name or id of the model, or a dictionary representation of the model. destination : str code : optional max_retries : int, optional replace : bool, optional Whether to overwrite the model if it already exists in the `destination` kwargs : optional additional arguments will be passed to the underlying publish functions. Returns ------- RestObj The published model Notes ----- If no code is specified, the model is assumed to be already registered in the model repository and Model Manager's publishing functionality will be used. Otherwise, the model publishing API will be used. See Also -------- :meth:`model_management.publish_model <.ModelManagement.publish_model>` :meth:`model_publish.publish_model <.ModelPublish.publish_model>` .. versionchanged:: 1.1.0 Added `replace` option. """ def submit_request(): # Submit a publishing request if code is None: dest_obj = mp.get_destination(destination) if dest_obj and dest_obj.destinationType == "cas": publish_req = mm.publish_model(model, destination, force=replace, reload_model_table=True) else: publish_req = mm.publish_model(model, destination, force=replace) else: publish_req = mp.publish_model(model, destination, code=code, **kwargs) # A successfully submitted request doesn't mean a successfully # published model. Response for publish request includes link to # check publish log job = mr._monitor_job(publish_req, max_retries=max_retries) return job # Submit and wait for status job = submit_request() # If model was successfully published and it isn't a MAS module, we're done if job.state.lower() == 'completed' \ and job.destination.destinationType != 'microAnalyticService': return request_link(job, 'self') # If MAS publish failed and replace=True, attempt to delete the module # and republish if job.state.lower() == 'failed' and replace and \ job.destination.destinationType == 'microAnalyticService': from .services import microanalytic_score as mas mas.delete_module(job.publishName) # Resubmit the request job = submit_request() # Raise exception if still failing if job.state.lower() == 'failed': log = request_link(job, 'publishingLog') raise RuntimeError("Failed to publish model '%s': %s" % (model, log.log)) # Raise exception if unknown status received elif job.state.lower() != 'completed': raise RuntimeError("Model publishing job in an unknown state: '%s'" % job.state.lower()) log = request_link(job, 'publishingLog') msg = log.get('log').lstrip('SUCCESS===') # As of Viya 3.4 MAS converts module names to lower case. # Since we can't rely on the request module name being preserved, try to # parse the URL out of the response so we can retrieve the created module. module_url = _parse_module_url(msg) if module_url is None: raise Exception('Unable to retrieve module URL from publish log.') module = get(module_url) if 'application/vnd.sas.microanalytic.module' in module._headers[ 'content-type']: # Bind Python methods to the module instance that will execute the # corresponding MAS module step. from sasctl.services import microanalytic_score as mas return mas.define_steps(module) return module
user = '******' password = '******' #astore_table = 'gb_astore' #astore_caslib = 'public' ################################### ####### Getting astore table ###### s = Session(host, user, password, verify_ssl=False) module = mas.get_module(modelname) module = mas.define_steps(module) steps = mas.list_module_steps(module) steps[0]['id'] steps[0]['links'] print(help(module.predict)) res = module.predict(5.0, 2.0, 3.5, 1.0) res2 = module.predict_proba(5.0, 2.0, 3.5, 1.0) print(res, res2) """ DATA SAMPLE {'Sepal_Length': {60: 5.0},
def test_call_python_module_steps_numpy(self): np = pytest.importorskip('numpy') r = mas.define_steps(self.MODULE_NAME) array = np.array([1.5, 3]) assert r.myfunction2(array) == 4.5
def test_call_python_module_steps(self): r = mas.define_steps(self.MODULE_NAME) assert (6, 'TEST') == r.myfunction(1, 'test')
def test_call_python_module_steps(): from sasctl.services.microanalytic_score import define_steps r = define_steps('sasctl_testmethod') assert (6, 'TEST') == r.myfunction(1, 'test')
def test_define_steps_invalid_name(): """Verify that invalid characters are stripped.""" # Mock module to be returned # From bug reported by Paata module = RestObj({ 'createdBy': 'paata', 'creationTimeStamp': '2020-03-02T15:37:57.811Z', 'id': 'petshop_model_xgb_new', 'language': 'ds2', 'links': [{ 'href': '/microanalyticScore/modules', 'itemType': 'application/vnd.sas.microanalytic.module', 'method': 'GET', 'rel': 'up', 'type': 'application/vnd.sas.collection', 'uri': '/microanalyticScore/modules' }, { 'href': '/microanalyticScore/modules/petshop_model_xgb_new', 'method': 'GET', 'rel': 'self', 'type': 'application/vnd.sas.microanalytic.module', 'uri': '/microanalyticScore/modules/petshop_model_xgb_new' }, { 'href': '/microanalyticScore/modules/petshop_model_xgb_new/source', 'method': 'GET', 'rel': 'source', 'type': 'application/vnd.sas.microanalytic.module.source', 'uri': '/microanalyticScore/modules/petshop_model_xgb_new/source' }, { 'href': '/microanalyticScore/modules/petshop_model_xgb_new/steps', 'itemType': 'application/vnd.sas.microanalytic.module.step', 'method': 'GET', 'rel': 'steps', 'type': 'application/vnd.sas.collection', 'uri': '/microanalyticScore/modules/petshop_model_xgb_new/steps' }, { 'href': '/microanalyticScore/modules/petshop_model_xgb_new/submodules', 'itemType': 'application/vnd.sas.microanalytic.submodule', 'method': 'GET', 'rel': 'submodules', 'type': 'application/vnd.sas.collection', 'uri': '/microanalyticScore/modules/petshop_model_xgb_new/submodules' }, { 'href': '/microanalyticScore/modules/petshop_model_xgb_new', 'method': 'PUT', 'rel': 'update', 'responseType': 'application/vnd.sas.microanalytic.module', 'type': 'application/vnd.sas.microanalytic.module', 'uri': '/microanalyticScore/modules/petshop_model_xgb_new' }, { 'href': '/microanalyticScore/modules/petshop_model_xgb_new', 'method': 'DELETE', 'rel': 'delete', 'uri': '/microanalyticScore/modules/petshop_model_xgb_new' }], 'modifiedBy': 'paata', 'modifiedTimeStamp': '2020-03-02T15:57:10.008Z', 'name': '"petshop_model_XGB_new"', 'properties': [{ 'name': 'sourceURI', 'value': 'http://modelmanager/modelRepository/models/72facedf-8e36-418e-8145-1398686b997a' }], 'revision': 0, 'scope': 'public', 'stepIds': ['score'], 'version': 2, 'warnings': [] }) # Mock module step with multiple inputs step2 = RestObj({ "id": "score", "inputs": [{ "name": "age", "type": "decimal", "dim": 0, "size": 0 }, { "name": "b", "type": "decimal", "dim": 0, "size": 0 }, { "name": "chas", "type": "decimal", "dim": 0, "size": 0 }, { "name": "crim", "type": "decimal", "dim": 0, "size": 0 }, { "name": "dis", "type": "decimal", "dim": 0, "size": 0 }, { "name": "indus", "type": "decimal", "dim": 0, "size": 0 }, { "name": "lstat", "type": "decimal", "dim": 0, "size": 0 }, { "name": "nox", "type": "decimal", "dim": 0, "size": 0 }, { "name": "ptratio", "type": "decimal", "dim": 0, "size": 0 }, { "name": "rad", "type": "decimal", "dim": 0, "size": 0 }, { "name": "rm", "type": "decimal", "dim": 0, "size": 0 }, { "name": "tax", "type": "decimal", "dim": 0, "size": 0 }, { "name": "zn", "type": "decimal", "dim": 0, "size": 0 }], "outputs": [{ "name": "em_prediction", "type": "decimal", "dim": 0, "size": 0 }, { "name": "p_price", "type": "decimal", "dim": 0, "size": 0 }, { "name": "_warn_", "type": "string", "dim": 0, "size": 4 }] }) with mock.patch( 'sasctl._services.microanalytic_score.MicroAnalyticScore.get_module' ) as get_module: with mock.patch( 'sasctl._services.microanalytic_score.MicroAnalyticScore' '.get_module_step') as get_step: get_module.return_value = module get_step.side_effect = [step2] result = mas.define_steps(None) for step in get_step.side_effect: assert hasattr(result, step.id)