BookmarkSubscribeRSS Feed

From cURL to PROC HTTP on SAS Viya

Started 3 weeks ago by
Modified 2 weeks ago by
Views 436

There are many SAS Communities and other SAS resources on how to use PROC HTTP to connect to external systems and communicate via API calls. See the bottom of this article for a list of some of these resources. Today, in this article, I want to focus on how to create REST API calls from the API documentation, connect to SAS Viya, and make API calls from SAS Studio.

 

Then, in the second article we will offer a more technical perspective with SAS code samples that show how to set up an end-to-end use case.

 

The developer portal

The first place to start is is the API documentation itself. This is found on the SAS developer portal, developer.sas.com. The SAS Viya APIs are split up by categories. In today's example we'll use APIs from several categories and offer examples for various HTTP methods. The use case is setting up a job definition and executing the job.

 

The first step is to create a folder where we can place the job definition. From the developer portal home page, the Folders API is under the Platform Administration category. Just to note, we'll also use the Compute and Jobs API later on. Finally, you have the option browse all APIs.

 

APICategories.png

 

Once in the Platform Administration category, select the Folders API.

 

PlatformAdminAPIs.png

 

The Folders API page lists all API endpoints. Since we need to find a folder to create an new location (folder) to house the job definition, we'll use the Get a list of folders endpoint. 

FoldersAPI.png

 

The endpoint documentation has a sample API request call.

GetFolderList.png

 

Notice the example call is using cURL. There are over a dozen language options such as Python requests, Go, JavaScript, R, etc; however, PROC HTTP is not one of them. 

 

So, let's take the cURL command and convert it to SAS code.

 

Converting cURL to PROC HTTP

Now let's explore how to take the sample from the API documentation and convert it into a PROC HTTP call.

 

GET Method

For this use case, we need to create a folder in an existing folder, so let's start with identifying that folder. Here is the API call to get the Public folder id:

curl --request GET 
--url 'https://sasserver.demo.sas.com/folders/folders?filter=eq(name,'Public')' \
--header 'Authorization: Bearer <access-token-goes-here>' \
--header 'Accept: application/json, application/vnd.sas.collection+json'

 

And here is the equivalent call using PROC HTTP:

/* 1 */ filename resp temp;
/* 2 */ proc http 
            method = 'GET'
            url = "https://sasserver.demo.sas.com/folders/folders/?filter=eq(name,'Public')"
/* 3 */     oauth_bearer = sas_services 
/* 4 */     out = resp;           
            headers 'Accept' = 'application/json, application/vnd.sas.collection+json';
        run;

Now, let's explore some notes on how to make the conversion.

  1. In the PROC HTTP example, we start with using the SAS FILENAME statement to define a location to store the API call response output.
  2. The PROC HTTP code begins.
  3. Since we are connecting directly to SAS Viya from SAS Studio, we use sas_services to authenticate. No token is required.
  4. Put the API call response output in the resp variable.

POST Method

The next step in our scenario is creating a directory in the parent (Public) directory from the example GET above. We would again go to the developer portal, follow a similar path in the documentation, and access the Create a new folder API endpoint. Below is an example API call using cURL:

curl --request POST 
--url 'https://sasserver.demo.sas.com/folders/folders?parentFolderUri=/folders/folders/F98c7f933-ec70-4736-b56c-bf29489ff03e' \
--header 'Accept: application/vnd.sas.content.folder+json' \
--header 'Authorization: Bearer <access-token-goes-here>' \
--header 'Content-Type: application/json' \
--data '{
  "name": "API Job Exec",
  "description": "My API tests folder.",
  "type": "folder"
}'

 

And here is the equivalent call using PROC HTTP:

         filename resp temp;
         proc http
             method = 'POST'
/* 1 */      in = '{                                     
             "name": "jobExecution_prochttp",
             "description": "Job Execution for proc http",
             "type": "folder"
             }' 
             url = "https://sasserver.demo.sas.com/folders/folders?parentFolderUri=/folders/folders/F98c7f933-ec70-4736-b56c-bf29489ff03e"
/* 2 */      ct = 'application/json'              
             oauth_bearer = sas_services
             out = resp;
             headers 'Accept' = 'application/vnd.sas.content.folder+json';
run;
 
Again, let's explore some notes on how to make the conversion. I have not repeated some of the comments again, as they are the same as the previous PROC HTTP code.

 

  1. ct is a special built-in option that takes the value of the Content Type header.
  2. Use the in = option for the --data equivalent option in cURL. This is the body of the POST API call.

More Examples

Let's finish out the use case with two more examples: 

  • create the job
  • execute the job

Create the job

The following cURL command creates a job definition that renders a simple table and writes it to the CAS server in the folder we created earlier:

curl --request POST
--url 'https://sasserver.demo.sas.com/jobDefinitions/definitions?parentFolderUri=/folders/folders/F44j5l654-gh47-5846-k36s-lf66624ah96r' \
--header 'Accept: application/json, application/vnd.sas.job.definition+json' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <access-token-goes-here>' \
--data '{
  "version":2,
  "name":"Table Create",
  "description":"Create a simple data set",
  "type":"Compute",
  "parameters":[
        {
        "version": 1,
        "name": "_contextName",
        "defaultValue": "SAS Job Execution compute context",
        "type": "CHARACTER",
        "label": "Context Name",
        "required": false
    }
  ],
  "code":"cas mySess; caslib _all_ assign; data casuser.test(promote=yes); input a b c d; datalines;\n1 2 3 4\n5 6 7 8\n;"
}'

 

And here is the equivalent call using PROC HTTP:

proc http
    method='POST'
    in='{
          "version": 2,
          "name": "Table Create",
          "description": "Create a simple data set",
          "type": "Compute",
          "parameters": [
            {
                  "version": 1,
                  "name": "_contextName",
                  "defaultValue": "SAS Job Execution compute context",
                  "type": "CHARACTER",
                  "label": "Context Name",
                  "required": false
            }
          ],
           "code": "cas mySess; caslib _all_ assign; data casuser.test(promote=yes); input a b c d; datalines;\n1 2 3 4\n5 6 7 8\n;"
    }'
     ct = 'application/json'
     url = "https://sasserver.demo.sas.com/jobDefinitions/definitions?parentFolderUri=/folders/folders/F44j5l654-gh47-5846-k36s-lf66624ah96r"
     oauth_bearer = sas_services
     out = resp;
     headers 'Accept' = 'application/json, application/vnd.sas.job.definition+json';
run;

 

Execute the Job

Finally, we'll run the job, creating the simple table. Below is the cURL command:

curl --request POST
--url 'https://sasserver.demo.sas.com/jobExecution/jobs' \
--header 'Accept: application/json, application/vnd.sas.job.execution.job+json, application/vnd.sas.error+json' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <access-token-goes-here>' \
--data '{
  "name": "Simple proc print",
  "description": "Execution of the job we previously created",
  "jobDefinitionUri": "/jobDefinitions/definitions/{{job_id}}"
}'

 

And here is the equivalent call using PROC HTTP:

filename resp temp;
proc http
    method = 'POST'
    in = {
        {
         "name": "Simple proc print",
         "description": "Execution of the job we previously created",
         "jobDefinitionUri": "/jobDefinitions/definitions/{{job_id}}"
         }
          }
     ct = 'application/json'
     url = "https://sasserver.demo.sas.com/jobExecution/jobs"
     oauth_bearer = sas_services
     out = resp;
     headers 'Accept' = 'application/json, application/vnd.sas.job.execution.job+json, application/vnd.sas.error+json';
run;

 

Wrapping Up

PROC HTTP allows you to include SAS Viya API calls and integrate it into your SAS code. We can take cURL commands and easily convert them to a SAS call. Stay tuned for the second article where we'll take this use case and create an end-to-end use case using SAS code.

 

PROC HTTP Resources

 

Version history
Last update:
2 weeks ago
Updated by:
Contributors

sas-innovate-white.png

Our biggest data and AI event of the year.

Don’t miss the livestream kicking off May 7. It’s free. It’s easy. And it’s the best seat in the house.

Join us virtually with our complimentary SAS Innovate Digital Pass. Watch live or on-demand in multiple languages, with translations available to help you get the most out of every session.

 

Register now!

SAS AI and Machine Learning Courses

The rapid growth of AI technologies is driving an AI skills gap and demand for AI talent. Ready to grow your AI literacy? SAS offers free ways to get started for beginners, business leaders, and analytics professionals of all skill levels. Your future self will thank you.

Get started

Article Tags