Published on :

List and locate SAS VA reports via REST API

This code is also available in: Deutsch Español Français
Awaiting validation
Attention : This code requires administrator privileges.
The script begins by calling the 'reports' service via PROC HTTP to obtain a filtered list of reports (here, by name). The JSON response is read with a LIBNAME JSON. Then, for each report found, a macro (%save_VA_Report_Path) is executed. This macro uses another API call ('folders/ancestors') to find the parent folder path of the report. The path is reconstructed and stored in the final dataset. Finally, the script displays the list of reports with their path, ID, and creation/modification metadata.
Data Analysis

Type : EXTERNAL


Data is dynamically generated by calls to the SAS Viya REST API. The first call retrieves report metadata, and subsequent calls retrieve the folder structure for each report.

1 Code Block
PROC HTTP Data
Explanation :
This block executes a GET request to the SAS Viya reports API to retrieve a collection of reports filtered by their name ('Report 2'). The JSON response is stored in the temporary fileref 'rptFile'.
Copied!
1%let BASE_URI=%sysfunc(getoption(SERVICESBASEURL));
2%let fullpath=/SAS Content/;
3 
4FILENAME rptFile TEMP ENCODING='UTF-8';
5PROC HTTP METHOD = "GET" oauth_bearer=sas_services OUT = rptFile
6/* get a list of reports, say created by sbjciw, or report name is 'Report 2' */
7/* URL = "&BASE_URI/reports/reports?filter=eq(createdBy,'sbjciw')" */
8 URL = "&BASE_URI/reports/reports?filter=eq(name,'Report 2')";
9 HEADERS "Accept" = "application/vnd.sas.collection+json"
10 "Accept-Item" = "application/vnd.sas.summary+json";
11 
12RUN;
2 Code Block
DATA STEP Data
Explanation :
Assigns a 'rptFile' library to read the received JSON. Then, a DATA step reads the items from the report collection to create the 'ds_rpts' table, keeping and renaming relevant variables like ID, name, and timestamps.
Copied!
1LIBNAME rptFile json;
2 
3DATA ds_rpts (keep=rptID id name createdBy creationTimeStamp modifiedTimeStamp
4 rename=(modifiedTimeStamp=LastModified creationTimeStamp=CreatedAt));
5 LENGTH rptID $ 60 rptPath $ 100;
6 SET rptFile.items;
7 rptID = '/reports/reports/'||id;
8RUN;
3 Code Block
MACRO
Explanation :
Defines a macro that takes a report URI as input. The macro performs a PROC HTTP call to find the ancestor folders of the report, uses PROC SQL to reconstruct the full path, then updates the 'ds_rpts' dataset with this path for the corresponding report. Note: Updating the 'ds_rpts' dataset is inefficient as it recreates the table with each call.
Copied!
1%MACRO save_VA_Report_Path(reportURI);
2 FILENAME fldFile TEMP ENCODING='UTF-8';
3 %let locURI = &reportURI;
4
5 PROC HTTP METHOD = "GET" oauth_bearer=sas_services OUT = fldFile
6 /* get the folders in which the reportURI is in */
7 URL = "&BASE_URI/folders/ancestors?childUri=/reports/reports/&reportURI";
8 HEADERS "Accept" = "application/vnd.sas.content.folder.ancestor+json";
9 RUN;
10 LIBNAME fldFile json;
11
12/* generate the path from the returned folders above */
13 PROC SQL noprint;
14 select name into :fldname separated BY '/'
15 from fldFile.ancestors
16 order BY ordinal_ancestors desc;
17 QUIT;
18 
19 DATA tmpsave;
20 LENGTH cc $ 36;
21 SET ds_rpts;
22 cc = "&locURI";
23 IF trim(id) = trim(cc) THEN
24 rptPath=resolve('&fullpath.&fldname.');
25 drop cc;
26 RUN;
27
28 DATA ds_rpts;
29 SET tmpsave;
30 RUN;
31 
32%MEND save_VA_Report_Path;
4 Code Block
DATA STEP Data
Explanation :
This DATA _NULL_ step iterates through the 'ds_rpts' table and uses 'CALL EXECUTE' to dynamically call the '%save_VA_Report_Path' macro for each report (each 'id') found, in order to populate the report's path.
Copied!
1DATA _null_;
2 SET ds_rpts;
3 call execute('%save_VA_Report_Path('||id||')');
4RUN;
5 Code Block
PROC PRINT
Explanation :
Prints the final content of the 'ds_rpts' dataset to display the path, name, ID, creator, and timestamps for each report.
Copied!
1 
2PROC PRINT
3DATA=ds_rpts;
4var rptPath name rptID createdBy CreatedAt LastModified;
5RUN;
6 
This material is provided "as is" by We Are Cas. There are no warranties, expressed or implied, as to merchantability or fitness for a particular purpose regarding the materials or code contained herein. We Are Cas is not responsible for errors in this material as it now exists or will exist, nor does We Are Cas provide technical support for it.