Publié le :

Lister et localiser des rapports SAS VA via l'API REST

Ce code est également disponible en : Deutsch English Español
En attente de validation
Attention : Ce code nécessite des droits administrateur.
Le script commence par appeler le service 'reports' via PROC HTTP pour obtenir une liste de rapports filtrée (ici, par nom). La réponse JSON est lue avec une LIBNAME JSON. Ensuite, pour chaque rapport trouvé, une macro (%save_VA_Report_Path) est exécutée. Cette macro utilise un autre appel API ('folders/ancestors') pour trouver le chemin du dossier parent du rapport. Le chemin est reconstruit et stocké dans le dataset final. Enfin, le script affiche la liste des rapports avec leur chemin, identifiant, et métadonnées de création/modification.
Analyse des données

Type : EXTERNE


Les données sont générées dynamiquement par des appels à l'API REST de SAS Viya. Le premier appel récupère les métadonnées des rapports, et les appels suivants récupèrent la structure des dossiers pour chaque rapport.

1 Bloc de code
PROC HTTP Data
Explication :
Ce bloc exécute une requête GET sur l'API des rapports de SAS Viya pour récupérer une collection de rapports filtrés par leur nom ('Report 2'). La réponse, au format JSON, est stockée dans le fileref temporaire 'rptFile'.
Copié !
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 Bloc de code
DATA STEP Data
Explication :
Assigne une bibliothèque 'rptFile' pour lire le JSON reçu. Ensuite, une étape DATA lit les items de la collection de rapports pour créer la table 'ds_rpts', en conservant et renommant les variables pertinentes comme l'ID, le nom et les timestamps.
Copié !
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 Bloc de code
MACRO
Explication :
Définit une macro qui prend un URI de rapport en entrée. La macro effectue un appel PROC HTTP pour trouver les dossiers ancêtres du rapport, utilise PROC SQL pour reconstruire le chemin complet, puis met à jour le dataset 'ds_rpts' avec ce chemin pour le rapport correspondant. Note: La mise à jour du dataset ds_rpts est inefficace car elle recrée la table à chaque appel.
Copié !
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 Bloc de code
DATA STEP Data
Explication :
Cette étape DATA _NULL_ parcourt la table 'ds_rpts' et utilise 'CALL EXECUTE' pour appeler dynamiquement la macro '%save_VA_Report_Path' pour chaque rapport (chaque 'id') trouvé, afin de peupler le chemin du rapport.
Copié !
1DATA _null_;
2 SET ds_rpts;
3 call execute('%save_VA_Report_Path('||id||')');
4RUN;
5 Bloc de code
PROC PRINT
Explication :
Imprime le contenu final du dataset 'ds_rpts' pour afficher le chemin, le nom, l'ID, le créateur et les timestamps de chaque rapport.
Copié !
1 
2PROC PRINT
3DATA=ds_rpts;
4var rptPath name rptID createdBy CreatedAt LastModified;
5RUN;
6 
Ce matériel est fourni "tel quel" par We Are Cas. Il n'y a aucune garantie, expresse ou implicite, quant à la qualité marchande ou à l'adéquation à un usage particulier concernant le matériel ou le code contenu dans les présentes. We Are Cas n'est pas responsable des erreurs dans ce matériel tel qu'il existe maintenant ou existera, et We Are Cas ne fournit pas de support technique pour celui-ci.
Banner
Le Conseil de l'Expert
Expert
Michael
Responsable de l'infrastructure Viya.
« L'inventaire des rapports SAS Visual Analytics à l'aide des API REST est une approche bien plus robuste que l'utilisation des méthodes héritées. Ce script illustre une mécanique essentielle de SAS Viya : la distinction entre l'objet métier (le rapport) et sa localisation logique dans l'arborescence. En couplant le service /reports et le service /folders, vous parvenez à reconstruire dynamiquement le "fil d'Ariane" (breadcrumbs) de vos contenus.

Recommandations et points de vigilance
L'efficacité du service ancestors : L'utilisation de l'URL /folders/ancestors?childUri=... est la méthode d'expert par excellence. Elle permet, en une seule requête, de récupérer toute la hiérarchie parente d'un objet. Trier les résultats par ordinal_ancestors desc dans l'étape PROC SQL est crucial pour reconstruire le chemin du dossier racine vers le dossier final de manière logique.

Optimisation des appels API : Le script utilise CALL EXECUTE pour déclencher une macro par rapport trouvé. Si votre filtre initial retourne des centaines de rapports, le nombre d'appels PROC HTTP pourrait impacter les performances. Dans ce cas, il est préférable de privilégier des approches de traitement par lots ou de mettre en cache les chemins des dossiers fréquemment consultés.

Gestion de l'authentification : L'utilisation de oauth_bearer=sas_services simplifie grandement le code en réutilisant le jeton d'authentification de la session active. Assurez-vous toutefois que l'utilisateur exécutant le script possède les permissions de lecture non seulement sur les rapports, mais aussi sur l'ensemble des dossiers parents pour éviter des chemins incomplets. »