BookmarkSubscribeRSS Feed
askojuvonen1
SAS Employee

I hear quite often nowadays this question: how do I run my SAS (Viya) programs from outside using REST APIs?  

 

There is an excellent Github repository which addresses this question, with several practical code examples: https://github.com/sassoftware/rest-api-use-cases .

 

By following these examples, I tested SAS job execution from Python client. My example SAS program produces some summary statistics and a line graph from SASHELP.AIR dataset, which is filtered by two macro variables.

 

 

/* Create dataset */
proc sql; create table air_subset as select * from sashelp.air where date between "&startdate"d and "&enddate"d; quit; ods graphics / reset width=6.4in height=4.8in imagemap; /* Summary statistics */
proc means data=WORK.AIR_SUBSET chartype mean std min max median n vardef=df qmethod=os; var AIR; run; /* Histogram plot */
proc univariate data=WORK.AIR_SUBSET vardef=df noprint; var AIR; histogram AIR; run; proc sort data=WORK.AIR_SUBSET out=_SeriesPlotTaskData; by DATE; run; /* Line graph*/
proc sgplot data=_SeriesPlotTaskData; series x=DATE y=AIR /; xaxis grid; yaxis grid; run; ods graphics / reset; proc datasets library=WORK noprint; delete _SeriesPlotTaskData; run;

I saved the sas-program as plot_air.sas and created a job definition of it. I placed the job definition in Public-folder.

 

askojuvonen1_0-1670516509106.png

 

 

Our SAS part of the experiment is now ready!

 

Let’s do the REST call in Python next. 

 

First thing to do is the authentication. For my testing purposes, I authenticate with user id and password. There are more secure ways to do the authentication: you should follow the security policies of your organization.

 

Note that steps 1 and 2 are for registrating the client, and they are not needed to run after initial registration.

 

import requests as request
import time

# To get the client_token, you need to run this command in Viya server: 
# kubectl -n sse get secret sas-consul-client -o jsonpath="{.data.CONSUL_TOKEN}" | echo "$(base64 -d)"

sasserver = "https://myviyaserver.sas.com"
client_token = "<client token from kubectl command above>"
username =  “myusername”
password = “mypassword”
client_id = "myclient"
client_secret = "mysecret"
# Step 1 : Get the client access token url = sasserver+"/SASLogon/oauth/clients/consul?callback=false&serviceId=" + client_id payload = {} headers = { "X-Consul-Token": client_token } response = request.request("POST", url, headers=headers, data = payload, verify=False).json() client_access_token = response["access_token"]
# Step 2 : Register the client url = sasserver+"/SASLogon/oauth/clients" payload = {"client_id": client_id, "client_secret": client_secret, "scope": ["*"], "resource_ids": "none", "authorities": ["uaa.none"], "authorized_grant_types": ["password"], "access_token_validity": 36000} headers = { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + client_access_token } response = request.request("POST", url, headers = headers, json = payload, verify=False).json() # Step 3 : Get the access token url = sasserver + "/SASLogon/oauth/token" data = { 'grant_type': 'password', 'username': username, 'password': password } headers = {'Accept': 'application/json'} response = request.post(url, headers=headers, data=data, auth=(client_id, client_secret), verify=False).json() access_token = response["access_token"]

 

Step 4 makes the REST API call to the desired job (/Public/plot_air). Note that the macro variables (startdate, enddate) which filter the AIR-dataset  in plot_air.sas are set as parameters in URL.  

 

# Step 4 : Call the SAS job plot_air with parameters startdate and enddate
job_url = sasserver+"/SASJobExecution/?_program=/Public/plot_air&startdate=1JAN1950&enddate=31DEC1959"
url = job_url + '&_action=json&_resultfile=*&_omittextlog=false'

headers = {
    'Authorization': 'bearer ' + access_token,
    'Content-Type': 'application/vnd.sas.job.execution.job.request',
    'Accept': 'application/vnd.sas.job.execution.job'
}

r = request.post(url, headers=headers, verify=False).json()

 

In Step 5, the result URLs are read from the HTTP response. log_uri contains the URL into SAS log, and output_uri  into SAS output.

 

# Step 5 : get the SAS log and SAS output URLs
log_uri = sasserver + r['items'][1]['href']
output_uri = sasserver + r['items'][2]['href']
print(log_uri)
print(output_uri)

 

In the last step, the HTML result is written into local file.

 

# Step 6 : write the SAS output html-file into local folder

output_str = request.get(output_uri, headers=headers, verify=False).text
filename = "c:\\temp\\Output_"+time.strftime("%Y%m%d-%H%M%S")+".html"
with open(filename, "w") as output_html:
    output_html.write(output_str)

 

And this is how the result HTML looks!

 

askojuvonen1_0-1670518011444.png

 

 

 

 

 

sas-innovate-2026-white.png



April 27 – 30 | Gaylord Texan | Grapevine, Texas

Registration is open

Walk in ready to learn. Walk out ready to deliver. This is the data and AI conference you can't afford to miss.
Register now and lock in 2025 pricing—just $495!

Register now

Discussion stats
  • 0 replies
  • 2034 views
  • 4 likes
  • 1 in conversation