Learn how to import, register an analytical model in SAS Viya, publish and deploy automatically to Azure, where it will be ready for scoring requests, in less than eight minutes. Read on for the details.
Stack Overflow wrote:
Data scientists excel at creating models that represent and predict real-world data, but effectively deploying machine learning models is more of an art than science. Deployment requires skills more commonly found in software engineering and DevOps. Venturebeat reports that 87% of data science projects never make it to production.
With SAS Viya and the Azure cloud platform you can tip the balance in your favor. Models that do not get deployed can become the exception, not the rule.
In just under eight minutes, you can convert a dormant ZIP file into a registered model in SAS Model Manager, a container image, and a functional REST API that is prepared for scoring on Azure.
Create a Python program called SCRModelRegister.py, that uses sasctl to register a model in SAS Model Manager from the ZIP file in your Git repository.
# Import necessary packages
import sys
import os
import requests
import shutil
from sasctl import Session
from sasctl.services import model_repository as mr, model_management as mm
import urllib3
import argparse
# Create an ArgumentParser object to handle command-line arguments
parser = argparse.ArgumentParser()
parser.add_argument('--host', type=str, required=True)
parser.add_argument('--user', type=str, required=True)
parser.add_argument('--password', type=str, required=True)
parser.add_argument('--protocol', type=str, required=True)
parser.add_argument('--repository_name', type=str, required=True)
parser.add_argument('--project_name', type=str, required=True)
parser.add_argument('--model_name', type=str, required=True)
parser.add_argument('--model_folder', type=str, required=True)
args = parser.parse_args()
# Print the command-line arguments
print('SAS Viya URL: ', args.host)
print('SAS User Name: ', args.user)
#print('SAS User Password: ', args.password)
print('Protocol: ', args.protocol)
print('SAS Model Repository Name: ', args.repository_name)
print('SAS Model Project Name: ', args.project_name)
print('SAS Model Name: ', args.model_name)
print('SAS Model Folder: ', args.model_folder)
# Set the path to the SSL certificates
pem_path='/home/jumpuser/.certs/my_trustedcerts.pem'
# Create a session using the specified arguments
s = Session(args.host, args.user, args.password, args.protocol, verify_ssl=pem_path)
# List object properties
print("Object doc: s")
print(dir(s))
print("Object doc: s._request_token_with_oauth")
print(dir(s._request_token_with_oauth))
# Get an access token using OAuth
at=s._request_token_with_oauth(args.user, args.password).access_token
# Retrieve a repository and project from SAS Model Manager
repository = mr.get_repository(args.repository_name)
print(f"Repository retrieved: {repository.name} with {repository.id}")
project = mr.get_project(args.project_name)
print(f"Project retrieved: {project.name} with {project.id}")
# Prepare to post the model to the specified URL
url = f"{args.host}/modelRepository/models"
print("Will POST the model", args.model_name, " to this url: ", url)
headers = {'Authorization': f'Bearer {s._request_token_with_oauth(args.user, args.password).access_token}'}
payload={
'name': args.model_name,
'type': 'GENERIC',
'projectId': project.id
}
print("This model will be posted: ")
print(args.model_folder + "/" + args.model_name + ".zip")
files={'files' : open(args.model_folder + "/" + args.model_name + ".zip",'rb')}
# Post the model to the specified URL
register_model = requests.post(
url,
data = payload,
headers = headers,
files = files,
verify=pem_path
)
# Print the content of the response
print(register_model.content)
# Import necessary packages
import sys
import os
import requests
import shutil
from sasctl import Session
from sasctl.services import model_repository as mr, model_management as mm
import urllib3
import argparse
# Create an ArgumentParser object to handle command-line arguments
parser = argparse.ArgumentParser()
parser.add_argument('--host', type=str, required=True)
parser.add_argument('--user', type=str, required=True)
parser.add_argument('--password', type=str, required=True)
parser.add_argument('--protocol', type=str, required=True)
parser.add_argument('--repository_name', type=str, required=False)
parser.add_argument('--project_name', type=str, required=False)
parser.add_argument('--model_name', type=str, required=True)
parser.add_argument('--model_folder', type=str, required=False)
parser.add_argument('--dest_name', type=str, required=True)
parser.add_argument('--model_publish_name', type=str, required=True)
parser.add_argument('--model_publish_notes', type=str, required=True)
args = parser.parse_args()
# Print the command-line arguments
print('SAS Viya URL: ', args.host)
print('SAS User Name: ', args.user)
#print('SAS User Password: ', args.password)
print('Protocol: ', args.protocol)
print('SAS Model Repository Name: ', args.repository_name)
print('SAS Model Project Name: ', args.project_name)
print('SAS Model Name: ', args.model_name)
print('SAS Model Folder: ', args.model_folder)
print('Azure Publishing Destination Name: ', args.dest_name)
print('SAS Model Publish Name: ', args.model_publish_name)
print('SAS Model Publish Notes: ', args.model_publish_notes)
# Set the path to the SSL certificates
pem_path='/home/jumpuser/.certs/my_trustedcerts.pem'
# Create a session using the specified arguments
s = Session(args.host, args.user, args.password, args.protocol, verify_ssl=pem_path)
# Get an access token using OAuth
at=s._request_token_with_oauth(args.user, args.password).access_token
# Get the model from SAS Model Manager
model = mr.get_model(args.model_name)
print(model)
# Prepare to publish the model to the specified URL
headers = {
"Content-Type": "application/vnd.sas.models.publishing.request.asynchronous+json",
"Authorization": f"Bearer {s._request_token_with_oauth(args.user, args.password).access_token}"
}
# to publish model under a different name can use "modelName": args.model_publish_name
# to publish model under the same name can use "modelName": args.model_name
payload = {
"destinationName": args.dest_name,
"modelContents": [
{
"modelName": args.model_publish_name,
"publishLevel": "model",
"sourceUri": f"/modelRepository/models/{model.id}"
}
],
"name": args.model_publish_name,
"notes": args.model_publish_notes
}
# Post/publish the model to the specified URL
model_publish = requests.post(
url=f'{args.host}/modelManagement/publish?force=true',
headers=headers,
data= json.dumps(payload),
verify=pem_path
)
# Print the content of the response
print(model_publish.content)
Select any image to see a larger version.
Mobile users: To view the images, select the "Full" version at the bottom of the page.
# Python script importing a model from a .zip in SAS Viya Model Manager
# A second Python script publishes the model from SAS Viya Model Manager to Azure
# the SAS Model Manager repository and project must be created before
# the Azure publishing destination must be created before
# the pipeline passes parameters to the python scripts.
name: 06_051_Model_Automation
parameters:
- name: MODEL_NAME
displayName: Model file name without the .zip at the end
type: string
default: QS_Reg1
trigger:
- main
pool:
name: $(pool)
stages:
- stage: models
displayName: Manage Models in SAS Model Manager
jobs:
- job: importModel
displayName: Import Model in SAS Model Manager
steps:
- checkout: self
persistCredentials: true
- task: AzureKeyVault@2
inputs:
azureSubscription: '$(azureSubscriptionSC)'
KeyVaultName: '$(keyvault)'
SecretsFilter: '*'
RunAsPreJob: true
- script: |
echo Check python
python3 --version
echo Python is installed
echo Install pip3
sudo apt install python3-pip -y
displayName: 'Install Pip 3.x'
- script: |
echo 'List directory where Git Repo was cloned: ' && pwd
ls -la
echo Get the folder where the Git repo was cloned
export GITFOLDER=$(pwd)
echo Git Pull
git pull origin main
ls -la
echo Install Requirements
pip3 install -r $GITFOLDER/requirements.txt
displayName: 'Install Python Requirements'
- task: Bash@3
inputs:
targetType: 'inline'
script: |
echo 'List the folder where Git Repo was cloned: ' && pwd
ls -la
echo Get the folder where the Git repo was cloned
export GITFOLDER=$(pwd)
echo List the Python programs folder
ls -la $GITFOLDER/programs
echo List the models folder
ls -la $GITFOLDER/programs
echo Arguments to pass to the python script
export INGRESS_URL=https://my_viya_url
echo Viya URL: ${INGRESS_URL}
SAS_USER=sas_user_here
#SASPASS Will be retrieved from the Azure Key Vault $(keyvault) as a variable $(SASPASS)
PROTOCOL=https
REPO_NAME=Public
PROJECT_NAME=QS_HMEQ
echo Path to certificates - ADAPT PATH if NEEDED
REQUESTS_CA_BUNDLE=~/.certs/my_trustedcerts.pem
echo Execute Python Program with Parameters
python3 $GITFOLDER/programs/SCRModelRegister.py --host $INGRESS_URL --user $SAS_USER --password $(SASPASS) --protocol $PROTOCOL --repository_name $REPO_NAME --project_name $PROJECT_NAME --model_name ${{ parameters.MODEL_NAME }} --model_folder $GITFOLDER/content > ~/SCRModelRegister.log
echo List Execution Log
cat ~/SCRModelRegister.log
displayName: Import Model in SAS Model Manager
- job: publishModel
displayName: Publish Model to Azure
dependsOn: importModel
steps:
- checkout: self
persistCredentials: true
- task: AzureKeyVault@2
inputs:
azureSubscription: '$(azureSubscriptionSC)'
KeyVaultName: '$(keyvault)'
SecretsFilter: '*'
RunAsPreJob: true
- task: Bash@3
inputs:
targetType: 'inline'
script: |
echo 'List the folder where Git Repo was cloned: ' && pwd
ls -la
echo Get the folder where the Git repo was cloned
export GITFOLDER=$(pwd)
echo List the Python programs folder
ls -la $GITFOLDER/programs
echo List the models folder
ls -la $GITFOLDER/programs
echo Arguments to pass to the python script
export INGRESS_URL=https://my_viya_url
echo Viya URL: ${INGRESS_URL}
SAS_USER=sas_user_here
#SASPASS Will be retrieved from the Azure Key Vault $(keyvault) as a variable $(SASPASS)
PROTOCOL=https
REPO_NAME=Public
PROJECT_NAME=QS_HMEQ
DEST_NAME=AzureCLI
echo Path to certificates - ADAPT PATH if NEEDED
REQUESTS_CA_BUNDLE=~/.certs/my_trustedcerts.pem
echo Execute Python Program with Parameters
python3 $GITFOLDER/programs/SCRModelPublish.py --host $INGRESS_URL --user $SAS_USER --password $(SASPASS) --protocol $PROTOCOL --model_name ${{ parameters.MODEL_NAME }} --dest_name $DEST_NAME --model_publish_name "sasmodel" --model_publish_notes "Published using REST API" > ~/SCRModelPublish.log
echo List Execution Log
cat ~/SCRModelPublish.log
displayName: Publish Model from SAS Model Manager to Azure
- job: listModels
displayName: List Models in SAS Model Manager
dependsOn: publishModel
steps:
- checkout: self
persistCredentials: true
- task: AzureKeyVault@2
inputs:
azureSubscription: '$(azureSubscriptionSC)'
KeyVaultName: '$(keyvault)'
SecretsFilter: '*'
RunAsPreJob: true
- script: |
echo 'List the folder where the Git Repo was cloned: ' && pwd
ls -la
echo Get the folder where the Git repo was cloned in a variable
export GITFOLDER=$(pwd)
echo List the cloned Git Repo programs folder
ls -la $GITFOLDER/programs
echo Create SAS-Viya CLI Profile
echo Initialize needed variables
pwd && ls -la
export SAS_CLI_PROFILE=gelenv
echo $SAS_CLI_PROFILE
export current_namespace=my
export CURL_CA_BUNDLE=~/.certs/${current_namespace}_trustedcerts.pem
echo $CURL_CA_BUNDLE
export SSL_CERT_FILE=~/.certs/${current_namespace}_trustedcerts.pem
echo ${SSL_CERT_FILE}
export REQUESTS_CA_BUNDLE=${SSL_CERT_FILE}
echo ${REQUESTS_CA_BUNDLE}
export INGRESS_URL=https://my_viya_url
echo Viya URL: ${INGRESS_URL}
clidir=/opt/sas/viya/home/bin
echo SAS-Viya CLI directory is: $clidir
echo Create SAS-Viya CLI Profile
$clidir/sas-viya --profile ${SAS_CLI_PROFILE} profile set-endpoint ${INGRESS_URL}
$clidir/sas-viya --profile ${SAS_CLI_PROFILE} profile toggle-color on
$clidir/sas-viya --profile ${SAS_CLI_PROFILE} profile set-output fulljson
echo Show profile
$clidir/sas-viya --profile ${SAS_CLI_PROFILE} profile show
echo Login in
SAS_USER=sas_user_here
$clidir/sas-viya --profile ${SAS_CLI_PROFILE} auth login -user $SAS_USER -password $(SASPASS)
echo *************** END COMMON TRUNK *******************
echo Model Management Module
echo Switching SAS Output to text
export SAS_OUTPUT=text
echo SAS Model Manager
echo Get a List of Repositories
$clidir/sas-viya --profile ${SAS_CLI_PROFILE} --output text models repository list
echo Get a List of Projects
$clidir/sas-viya --profile ${SAS_CLI_PROFILE} --output text models project list
echo List models
$clidir/sas-viya --profile ${SAS_CLI_PROFILE} --output text models list
echo Get a List of Publishing Destinations
$clidir/sas-viya --profile ${SAS_CLI_PROFILE} --output text models destination list
echo Get a List of Published Objects
$clidir/sas-viya --profile ${SAS_CLI_PROFILE} --output text models published list
displayName: SAS Model Manager Lists
/
at the end.
Thanks to my colleague @YiJianChing for helping out with sasctl.
Thank you for your time reading this post. If you liked the post, give it a thumbs up! Please comment and tell us what you think about Python and SAS Viya REST APIs. If you wish to get more information, please write me an email.
Find more articles from SAS Global Enablement and Learning here.
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 16. Read more here about why you should contribute and what is in it for you!
Data Literacy is for all, even absolute beginners. Jump on board with this free e-learning and boost your career prospects.