BookmarkSubscribeRSS Feed

Getting Python Talking with The SAS Viya REST API: Registering a Client - [PART 1]

Started ‎06-05-2019 by
Modified ‎10-10-2019 by
Views 6,796

Are you a Python developer trying to get started with SAS Viya? Or maybe you have come across this guide in order to better understand what to do with all the different tokens required to interface with VIYA ? In this two part series we are going to walk through the very first steps in your VIYA API journey with Python. The focus of this post is going to be on the process of registering a client, getting and generating various tokens and explaining what it all actually means.

 

Registering a Client

Background:  The process of Registering a client is the first step in getting a Python developer access to the API. This step has to be performed by someone who has access to the head Viya node in Linux. This has to be done by someone who is a member of the SAS Administrators group, however if you have this level of access then you should be able to perform these steps without any issues.

 

Pre-requisites:

  • Administrator (elevated/sudo) access to the VIYA Environment system
  • Python compiler installed on the server
  • Entry level understanding of Linux
  • Basic understanding of python: functions and variables
  • The only required library needed for this code is the requests library

    import requests

     

Check that python is installed by running the following command:

 

python --version

 

python.png

If the command is recognized, then you are all set. 

 

Step 1: Retrieve the Consul Token

A consult token is sort of like a “password” that lives on the head Viya file system. We need to retrieve in order to prove to the system that we do in fact have the right to Register a Client. The consul token is located in the /opt/sas/viya/config/etc/SASSecurityCertificateFramework/tokens/consul/default/ directory and is stored in a file called client.token (later referred to as a consul token). 

Note: The consul token is one of the most important and highly guarded assets for a SAS VIYA system. For this reason, it can only be accessed by someone with a elevated access on the machine. 

 

 

def getConsulToken():
    with open('/opt/sas/viya/config/etc/SASSecurityCertificateFramework/tokens/consul/default/client.token', 'r') as file:
        data = file.read()
        print("The consul Token is: [" + str(data)+"]")
        return str(data)

consulToken = getConsulToken()

The expected output is:

token.png

 

 

Step 2: Get Authentication Token

Now that we have a consul token from the previous step. We need to supply an Application Name of our choice. For example, if the project your are working on is for Human Resources, you may want to name the application: HRApp. This information is passed in to the function/code below. After it runs, it will return yet another token called Oauth token. With this token in hand, the system has set aside the name of our application and is ready for the actual registration steps.

 

Note: The Application Name is created during this step and will be later used by the Python developer as well.

 

hostname = “example.com”
def registrationOauthTokenReuqest(appName, consulToken): print("Attempting to get a registration Oauth token")
url = "http://" +str(hostname)+ "/SASLogon/oauth/clients/consul?callback=false&serviceId="+ str(appName) headers = {"X-Consul-Token":str(consulToken)}
r = requests.post(url, headers=headers, timeout=30)
if r.status_code == 200: return r.json()['access_token']

appName = "HRApp" #your Application Name
access_token = registrationOauthTokenReuqest(appName, consulToken)

The expected output is:

oauth.JPG

 

Step 3: Registering the Client

This is the final step in the registration process where we have supply a couple of bits of information that we already have (Application Name and Oauth token), along with a password of your choice (referred to as ‘secret’).

Note: By default, the validity is set to 12 hours (or 43199 seconds). This is the amount of time a python developer or program can be logged to this app until the login expires and needs to be re-signed in.

 

def registerNewClient(appName, secret, authToken, validity=43199):
    print("Attempting to register")

    url = "https://" + str(hostname) + "/SASLogon/oauth/clients"
   
    headers = {"Content-Type":"application/json",
               "Authorization": "Bearer " + str(authToken)}

    data = {"client_id":str(appName),
            "client_secret":str(secret),
            "scope": "openid",
            "authorized_grant_types":"password",
            "access_token_validity":validity
            }

    r = requests.post(url,headers=headers, json=data, timeout=30, verify=False)
    print(r)

    if r.status_code == 201:
      print("Register success")
      print(r.json())

secret = "passwordOfYourChoice" #supply a password
registerNewClient(appName, secret, access_token, validity=43199)

The expected output is:

 

Registration.JPG

 

The registration is complete. The Administrator will need to provide the Application Name and Secret to the Developer to access the API.

 

How to make this example work for you

This example was created in a Viya 3.4. All code in this article is intended to be submitted in Python 3.6 within the Viya 3.4 environment with elevated access in order to complete these steps. 

The attachments for this post are:

  • viya_api_register.py 

Run the file on the head Viya Server by sending the following command:

 

python viya_api_register.py

 

Next Steps:

Part 2 of Getting Python Talking with The SAS Viya REST API

 

 

REFERENCES 

Comments

Any idea the reason for below issue;

 

 

Python 3.6.3 (default, Apr 10 2019, 14:37:36)

[GCC 4.8.5 20150623 (Red Hat 4.8.5-16)] on linux

Type "help", "copyright", "credits" or "license" for more information.

>>> import requests

>>> def getConsulToken():

...     with open('/opt/sas/viya/config/etc/SASSecurityCertificateFramework/tokens/consul/default/client.token', 'r') as file:

...         data = file.read()

...         print("The consul Token is: [" + str(data)+"]")

...         return str(data)consulToken = getConsulToken()

  File "<stdin>", line 5

    return str(data)consulToken = getConsulToken()

                              ^

SyntaxError: invalid syntax

>>>

Hi @venkattolu 

I suggest using the code from the attachment to the post, it appears that the newlines didnt paste correctly into the post.

That last line should really be:

                return str(data)
consulToken = getConsulToken()

 

With the return being indented correctly for the function definition above. 

In essence we would have just created/defined a function, and then called it on the very last line. 

Hi

Question:

- Is there a service that needs to be active

- Is this allowed only on host machine (SAS Logon Manager)

When ever i run the above code on a remote machine (My Own PC) with URL set, the following functions sends the HTML version of the Login screen.

 

Function: def registrationOauthTokenReuqest(appName, consulToken):
print("Attempting to get a registration Oauth token")
url = "http://" +str(sasserver)+ "/SASLogon/oauth/clients/consul?callback=false&serviceId="+ str(appName)
headers = {"X-Consul-Token":str(consulToken)}
r = requests.post(url, headers=headers, timeout=30)
print(r.text)
print("####################")
print(r)
if r.status_code == 200:
print(r.json())
print("-------ACCESS TOKEN: " + str(r.json()['access_token']))
#admRec.write("The access token is: " + str(r.json()['access_token']) + "\n")
return r.json()['access_token']
else:
print("Could not get registration oauth token")


Message: 
<Response [200]>
Traceback (most recent call last):
File "request_client.py", line 30, in <module>
access_token = registrationOauthTokenReuqest(appName, consulToken)
File "request_client.py", line 22, in registrationOauthTokenReuqest
print(r.json())
File "/var/log/hadoop/anaconda3/lib/python3.6/site-packages/requests/models.py", line 900, in json
return complexjson.loads(self.text, **kwargs)
File "/var/log/hadoop/anaconda3/lib/python3.6/json/__init__.py", line 354, in loads
return _default_decoder.decode(s)
File "/var/log/hadoop/anaconda3/lib/python3.6/json/decoder.py", line 339, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/var/log/hadoop/anaconda3/lib/python3.6/json/decoder.py", line 357, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 12 column 1 (char 11)


 

 

kh4

HI @vatslavorlov ,

 

As a SAS Administrator is there a way to list out already registered clients(Application Names)?

 

Thanks

 

Version history
Last update:
‎10-10-2019 10:08 AM
Updated by:
Contributors

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

Register now!

Free course: Data Literacy Essentials

Data Literacy is for all, even absolute beginners. Jump on board with this free e-learning  and boost your career prospects.

Get Started

Article Tags