├── AutomatedMachineLearning └── mlPipelineAutomation.md ├── CASActions ├── README.md └── append-table │ ├── README.md │ ├── append-tables.md │ ├── costumesByYear.xlsx │ └── postman-collection │ ├── README.md │ └── append-table.postman_collection.json ├── CONTRIBUTING.md ├── Compute ├── README.md ├── casManagement.md ├── compute.md ├── jobDefinitions.md └── jobExecution.md ├── ContributorAgreement.txt ├── CoreServices ├── README.md ├── annotations.md ├── authorization.md ├── files.md ├── folders.md ├── listData.md ├── resources │ ├── .gitkeep │ └── resources.md └── sasLogon.md ├── DataManagement ├── README.md ├── catalog │ ├── overview.md │ ├── postman │ │ └── catalog │ │ │ ├── create-and-run-discovery-agent │ │ │ ├── README.md │ │ │ └── create-and-run-discovery-agent.postman_collection.json │ │ │ ├── create-and-search-on-tags │ │ │ ├── README.md │ │ │ └── create-and-search-on-tags.postman_collection.json │ │ │ ├── create-and-use-asset │ │ │ ├── README.md │ │ │ └── create-and-use-asset.postman_collection.json │ │ │ ├── download-upload-to-cas-profiled-metrics-data │ │ │ ├── README.md │ │ │ └── download-upload-to-cas-profiled-metrics-data.postman_collection.json │ │ │ ├── overview.md │ │ │ ├── sasserver.postman_environment.json │ │ │ └── use-search-to-lookup-resources │ │ │ ├── README.md │ │ │ └── use-search-to-lookup-resources.postman_collection.json │ └── python │ │ └── catalog │ │ ├── create-and-run-discovery-agent │ │ ├── README.md │ │ └── create-and-run-discovery-agent.ipynb │ │ ├── create-and-search-on-tags │ │ ├── README.md │ │ └── create-and-search-on-tags.ipynb │ │ ├── create-and-use-asset │ │ ├── README.md │ │ └── create-and-use-asset.ipynb │ │ ├── download-upload-to-cas-profiled-metrics-data │ │ ├── README.md │ │ └── download-upload-to-cas-profiled-metrics-data_requests_notebook.ipynb │ │ ├── overview.md │ │ └── use-search-to-lookup-resources │ │ ├── README.md │ │ └── use-search-to-lookup-resources.ipynb ├── dataQuality.md ├── dataSources.md ├── dataTables.md ├── glossary │ ├── import.csv │ ├── postman │ │ └── glossary │ │ │ ├── drafts-use-cases │ │ │ ├── README.md │ │ │ └── drafts-use-cases.postman_collection.json │ │ │ ├── import-terms-use-cases │ │ │ ├── README.md │ │ │ └── import-terms-use-case.postman_collection.json │ │ │ ├── term-type-use-cases │ │ │ ├── README.md │ │ │ └── term-types-use-case.postman_collection.json │ │ │ └── terms-use-cases │ │ │ ├── README.md │ │ │ └── terms-use-case.postman_collection.json │ └── python │ │ └── glossary │ │ ├── drafts-use-cases │ │ ├── README.md │ │ └── drafts_use_cases.ipynb │ │ ├── import-terms-use-cases │ │ ├── README.md │ │ └── import_terms_use_cases.ipynb │ │ ├── term-type-use-cases │ │ ├── README.md │ │ └── term_type_use_cases.ipynb │ │ └── terms-use-cases │ │ ├── README.md │ │ └── terms_use_cases.ipynb ├── images │ ├── .gitkeep │ ├── RowSets_RowSetPaginationHorizontal1.png │ ├── RowSets_RowSetPaginationHorizontal2.png │ ├── RowSets_RowSetPaginationHorizontal3.png │ └── RowSets_RowSetPaginationHorizontal4.png └── rowSets.md ├── DecisionManagement ├── README.md ├── businessRules.md ├── dataMining.md ├── decisions.md ├── images │ ├── MASExampleCode.jpg │ ├── sequence-analysis.png │ ├── sequence-score-with-mapped-code.png │ └── sequence-score-with-score-definition.png ├── microAnalyticScore.md ├── modelManagement.md ├── modelPublish.md ├── modelRepository.md ├── referenceData.md ├── scoreDefinitions.md ├── scoreExecutions.md ├── subjectContacts.md ├── treatmentDefinitions.md └── viya35 │ ├── businessRules_viya35.md │ ├── decisions_viya35.md │ ├── modelManagement_viya35.md │ ├── modelPublish_viya35.md │ ├── modelRepository_viya35.md │ └── treatmentDefinitions_viya35.md ├── LICENSE ├── README.md ├── TextAnalytics ├── README.md ├── categorization.md ├── concepts.md ├── sentimentAnalysis.md ├── textParsing.md └── topics.md ├── User_and_Aggregated_Samples └── SAS │ ├── README.md │ └── create-va-svg-img │ ├── README.md │ ├── create-va-svg-img.sas │ └── create_VA_svg_image.png ├── VisualInvestigator ├── README.md ├── viSearchAndDiscovery.md └── viWorkflow.md └── Visualization ├── README.md ├── error-codes.md ├── reportImages.md └── reportTransforms.md /CASActions/README.md: -------------------------------------------------------------------------------- 1 | # CAS Action REST APIs on SAS Viya 2 | 3 | Each directory in this section contains examples of CAS Action REST API requests. 4 | -------------------------------------------------------------------------------- /CASActions/append-table/README.md: -------------------------------------------------------------------------------- 1 | # Append a table using Cloud Analytics Services (CAS) REST APIs on SAS Viya 2 | 3 | The commands in the append-table.md file come from the SAS Users blog post [Append tables in SAS® Viya® with REST APIs – a treat, no tricks](https://blogs.sas.com/content/sgf/2019/10/28/append-tables-in-sas-viya-with-rest-apis). The series of REST API calls creates a session with the SAS Viya server, loads a table, and then appends the table with additional data. 4 | 5 | I used the cURL command to send the requests and I include any needed headers and body text. Further, prior to running the commands you will need to obtain an access token. For more information on authenticating to SAS Viya see the post [Authentication to SAS Viya: a couple of approaches](https://blogs.sas.com/content/sgf/2019/01/25/authentication-to-sas-viya/). I created the ACCESSTOKEN variable to store the value of the acess token. Finally, you will need to replace *https://sasserver* with your SAS Viya server and *\* with the session id created in the first step. 6 | 7 | You can find a Postman collection of the same REST calls in the [append-tables file](../append-tables) in this repository. 8 | 9 | More information about SAS REST APIs and open source integration can be found on [developer.sas.com](https://developer.sas.com/home.html). -------------------------------------------------------------------------------- /CASActions/append-table/append-tables.md: -------------------------------------------------------------------------------- 1 | # Commands to append a table using CAS REST APIs 2 | 3 | ### createSession 4 | ``` 5 | curl -X POST https://sasserver:8777/cas/sessions \ 6 | -H 'Authorization: Bearer $ACCESSTOKEN' \ 7 | -H 'Content-Type: application/vnd.sas.cas.session+json' 8 | ``` 9 | 10 | ### createGlobalCaslib 11 | ``` 12 | curl -X POST https://sasserver:8777/cas/sessions//actions/table.addCaslib \ 13 | -H 'Authorization: Bearer $ACCESSTOKEN' \ 14 | -H 'Content-Type: application/json' \ 15 | -d {"name":"HALLOWEEN","path":"/home/sasdemo/halloween","description":"HALLOWEEN","subDirectories":"false","permission":"PUBLICWRITE","session":"false","dataSource":{"srcType":"path"},"createDirectory":"true","hidden":"false","transient":"false"} 16 | ``` 17 | 18 | ### copyDataSetIntoCaslib 19 | This is a manual step of copying the data file to the Caslib path. There are various ways to copy/upload the data. 20 | 21 | ### createTempCaslib 22 | ``` 23 | curl -X POST https://sasserver:8777/cas/sessions/<session=id>/actions/table.addCaslib \ 24 | -H 'Authorization: Bearer $ACCESSTOKEN' \ 25 | -H 'Content-Type: application/json' \ 26 | -d {"name":"TEMP","path":"/home/sasdemo/temp","description":"TEMP","subDirectories":"false","permission":"PUBLICWRITE","session":"false","dataSource":{"srcType":"path"},"createDirectory":"true","hidden":"false","transient":"false"} 27 | ``` 28 | 29 | ### loadDataToMemory 30 | ``` 31 | curl -X POST https://sasserver:8777/cas/sessions//actions/table.loadTable 32 | -H 'Authorization: Bearer $ACCESSTOKEN' \ 33 | -H 'Content-Type: application/json' \ 34 | -d {"path":"costumesByYear.xlsx","caslib":"HALLOWEEN","importOptions":{"fileType":"EXCEL"},"casOut":{"caslib":"TEMP","name":"costumesByYear","promote":"true"}} 35 | ``` 36 | 37 | ### createTempTableWithAppendData 38 | ``` 39 | curl -X PUT https://sasserver:8777/cas/sessions//actions/upload 40 | -H 'Authorization: Bearer $ACCESSTOKEN' \ 41 | -H 'Content-Type: text/plain' \ 42 | -H 'JSON-Parameters: {"casOut":{"caslib":"TEMP","name":"data2019","promote":"true"},"importOptions":{"fileType":"CSV"}}' \ 43 | --data-binary $'Year,Costume\n2019,The Golden Girls\n2019,Pennywise' 44 | ``` 45 | 46 | ### runDataStepToAppendData 47 | ``` 48 | curl -X POST https://sasserver:8777/cas/sessions//actions/runCode \ 49 | -H 'Authorization: Bearer $ACCESSTOKEN' \ 50 | -H 'Content-Type: application/json' \ 51 | -d {"code": "data temp.costumesbyyear(append=force) ; set temp.data2019;run;"} 52 | ``` 53 | 54 | ### saveAppendedTableBackToCaslib 55 | ``` 56 | curl -X POST https://sasserver:8777/cas/sessions//actions/table.save \ 57 | -H 'Authorization: Bearer $ACCESSTOKEN' \ 58 | -H 'Content-Type: application/json' \ 59 | -d {"table":{"name":"costumesbyyear","caslib":"TEMP","singlePass":"false"},"name":"costumesbyyear","replace":"true","compress":"false","caslib":"HALLOWEEN","exportOptions":{"fileType":"BASESAS"}} 60 | ``` 61 | 62 | ### deleteTempCaslib 63 | ``` 64 | curl -X POST https://sasserver:8777/cas/sessions//table.dropCaslib \ 65 | -H 'Authorization: Bearer $ACCESSTOKEN' \ 66 | -H 'Content-Type: application/json' \ 67 | -d {"caslib":"TEMP"} 68 | ``` 69 | 70 | ### deleteCASSession 71 | ``` 72 | curl -X POST https://sasserver:8777/cas/sessions/ \ 73 | -H 'Authorization: Bearer $ACCESSTOKEN' 74 | ``` -------------------------------------------------------------------------------- /CASActions/append-table/costumesByYear.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sassoftware/devsascom-rest-api-samples/8371b14b9e354a79d8993d8eb9c87f4110708209/CASActions/append-table/costumesByYear.xlsx -------------------------------------------------------------------------------- /CASActions/append-table/postman-collection/README.md: -------------------------------------------------------------------------------- 1 | # Append-Table Postman collection 2 | 3 | The postman collection in append-table.postman_collection.json contains the steps to load, append, and save a data table in SAS Viya using Cloud Analytics Services (CAS) REST APIs. 4 | 5 | The collection uses OAuth2 to connect to SAS Viya. The collections uses pre and post request scripts to get an access token. Several variables are used as well. You should have the following variables created in your Postman environment: 6 | 7 | | Token | Description | 8 | | -------- | -------------- | 9 | | token_url | endpoint for the authentiction server | 10 | | encoded_id_secret | base64 encoded clientid:clientsecret | 11 | | OAUTH_USERNAME | username used for authentication | 12 | | OAUTH_PASSWORD | password used for authentication | 13 | | sasserver | SAS Viya server | 14 | 15 | Other variables will be created during the execution of the collection. It is not required that these exist prior to beginning. -------------------------------------------------------------------------------- /CASActions/append-table/postman-collection/append-table.postman_collection.json: -------------------------------------------------------------------------------- 1 | { 2 | "info": { 3 | "_postman_id": "304c8f29-dd5f-4517-a04a-265edb3aafb6", 4 | "name": "Halloween", 5 | "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" 6 | }, 7 | "item": [ 8 | { 9 | "name": "createCASSession", 10 | "event": [ 11 | { 12 | "listen": "prerequest", 13 | "script": { 14 | "id": "90f71b6e-c59b-48e2-bc62-04b2a75d30db", 15 | "exec": [ 16 | "pm.sendRequest({\r", 17 | " url: pm.environment.get(\"token_url\")+\"/SASLogon/oauth/token\",\r", 18 | " method: 'POST',\r", 19 | " header: {\r", 20 | " 'Authorization': 'Basic '+ pm.environment.get(\"encoded_id_secret\"),\r", 21 | " 'Accept': 'application/json',\r", 22 | " 'Content-Type': 'application/x-www-form-urlencoded',\r", 23 | " },\r", 24 | " body: {\r", 25 | " mode: 'urlencoded',\r", 26 | " urlencoded: [\r", 27 | " {key: \"grant_type\", value: \"password\", disabled: false},\r", 28 | " {key: \"username\", value: pm.environment.get(\"OAUTH_USERNAME\"), disabled: false},\r", 29 | " {key: \"password\", value: pm.environment.get(\"OAUTH_PASSWORD\"), disabled: false}\r", 30 | " ]\r", 31 | " }\r", 32 | " }, function (err, res) {\r", 33 | " pm.environment.set(\"authToken\", res.json().access_token);\r", 34 | "});" 35 | ], 36 | "type": "text/javascript" 37 | } 38 | }, 39 | { 40 | "listen": "test", 41 | "script": { 42 | "id": "3897c19d-d9fd-47ad-b17e-20b110ed3424", 43 | "exec": [ 44 | "var jsonData = JSON.parse(responseBody);", 45 | "pm.environment.set(\"sessionid\", jsonData.id);" 46 | ], 47 | "type": "text/javascript" 48 | } 49 | } 50 | ], 51 | "request": { 52 | "auth": { 53 | "type": "oauth2", 54 | "oauth2": [ 55 | { 56 | "key": "accessToken", 57 | "value": "{{authToken}}", 58 | "type": "string" 59 | }, 60 | { 61 | "key": "addTokenTo", 62 | "value": "header", 63 | "type": "string" 64 | } 65 | ] 66 | }, 67 | "method": "POST", 68 | "header": [ 69 | { 70 | "key": "Content-Type", 71 | "value": "application/vnd.sas.cas.session+json", 72 | "type": "text" 73 | } 74 | ], 75 | "url": { 76 | "raw": "{{sasserver}}/casManagement/servers/cas-shared-default/sessions", 77 | "host": [ 78 | "{{sasserver}}" 79 | ], 80 | "path": [ 81 | "casManagement", 82 | "servers", 83 | "cas-shared-default", 84 | "sessions" 85 | ] 86 | } 87 | }, 88 | "response": [] 89 | }, 90 | { 91 | "name": "createCaslib", 92 | "request": { 93 | "auth": { 94 | "type": "oauth2", 95 | "oauth2": [ 96 | { 97 | "key": "accessToken", 98 | "value": "{{authToken}}", 99 | "type": "string" 100 | }, 101 | { 102 | "key": "addTokenTo", 103 | "value": "header", 104 | "type": "string" 105 | } 106 | ] 107 | }, 108 | "method": "POST", 109 | "header": [ 110 | { 111 | "key": "Content-Type", 112 | "value": "application/json", 113 | "type": "text" 114 | } 115 | ], 116 | "body": { 117 | "mode": "raw", 118 | "raw": "{\"name\":\"HALLOWEEN\",\"path\":\"/home/sasdemo/halloween\",\"description\":\"HALLOWEEN\",\"subDirectories\":\"false\",\"permission\":\"PUBLICWRITE\",\"session\":\"false\",\"dataSource\":{\"srcType\":\"path\"},\"createDirectory\":\"true\",\"hidden\":\"false\",\"transient\":\"false\"}" 119 | }, 120 | "url": { 121 | "raw": "{{sasserver}}:8777/cas/sessions/{{sessionid}}/actions/table.addCaslib", 122 | "host": [ 123 | "{{sasserver}}" 124 | ], 125 | "port": "8777", 126 | "path": [ 127 | "cas", 128 | "sessions", 129 | "{{sessionid}}", 130 | "actions", 131 | "table.addCaslib" 132 | ] 133 | } 134 | }, 135 | "response": [] 136 | }, 137 | { 138 | "name": "createTempCaslib", 139 | "request": { 140 | "auth": { 141 | "type": "oauth2", 142 | "oauth2": [ 143 | { 144 | "key": "accessToken", 145 | "value": "{{authToken}}", 146 | "type": "string" 147 | }, 148 | { 149 | "key": "addTokenTo", 150 | "value": "header", 151 | "type": "string" 152 | } 153 | ] 154 | }, 155 | "method": "POST", 156 | "header": [ 157 | { 158 | "key": "Content-Type", 159 | "value": "application/json", 160 | "type": "text" 161 | } 162 | ], 163 | "body": { 164 | "mode": "raw", 165 | "raw": "{\"name\":\"TEMP\",\"path\":\"/home/sasdemo/temp\",\"description\":\"TEMP\",\"subDirectories\":\"false\",\"permission\":\"PUBLICWRITE\",\"session\":\"false\",\"dataSource\":{\"srcType\":\"path\"},\"createDirectory\":\"true\",\"hidden\":\"false\",\"transient\":\"false\"}" 166 | }, 167 | "url": { 168 | "raw": "{{sasserver}}:8777/cas/sessions/{{sessionid}}/actions/table.addCaslib", 169 | "host": [ 170 | "{{sasserver}}" 171 | ], 172 | "port": "8777", 173 | "path": [ 174 | "cas", 175 | "sessions", 176 | "{{sessionid}}", 177 | "actions", 178 | "table.addCaslib" 179 | ] 180 | } 181 | }, 182 | "response": [] 183 | }, 184 | { 185 | "name": "loadCostumeTableToMem", 186 | "request": { 187 | "auth": { 188 | "type": "oauth2", 189 | "oauth2": [ 190 | { 191 | "key": "accessToken", 192 | "value": "{{authToken}}", 193 | "type": "string" 194 | }, 195 | { 196 | "key": "addTokenTo", 197 | "value": "header", 198 | "type": "string" 199 | } 200 | ] 201 | }, 202 | "method": "POST", 203 | "header": [ 204 | { 205 | "key": "Content-Type", 206 | "value": "application/json", 207 | "type": "text" 208 | } 209 | ], 210 | "body": { 211 | "mode": "raw", 212 | "raw": "{\"path\":\"costumesByYear.xlsx\",\"caslib\":\"HALLOWEEN\",\"importOptions\":{\"fileType\":\"EXCEL\"},\"casOut\":{\"caslib\":\"TEMP\",\"name\":\"costumesByYear\",\"promote\":\"true\"}}" 213 | }, 214 | "url": { 215 | "raw": "{{sasserver}}:8777/cas/sessions/{{sessionid}}/actions/table.loadTable", 216 | "host": [ 217 | "{{sasserver}}" 218 | ], 219 | "port": "8777", 220 | "path": [ 221 | "cas", 222 | "sessions", 223 | "{{sessionid}}", 224 | "actions", 225 | "table.loadTable" 226 | ] 227 | } 228 | }, 229 | "response": [] 230 | }, 231 | { 232 | "name": "createData2019Table", 233 | "request": { 234 | "auth": { 235 | "type": "oauth2", 236 | "oauth2": [ 237 | { 238 | "key": "accessToken", 239 | "value": "{{authToken}}", 240 | "type": "string" 241 | }, 242 | { 243 | "key": "addTokenTo", 244 | "value": "header", 245 | "type": "string" 246 | } 247 | ] 248 | }, 249 | "method": "PUT", 250 | "header": [ 251 | { 252 | "key": "Content-Type", 253 | "value": "text/plain", 254 | "type": "text" 255 | }, 256 | { 257 | "key": "JSON-Parameters", 258 | "value": "{\"casOut\":{\"caslib\":\"TEMP\",\"name\":\"data2019\",\"promote\":\"true\"},\"importOptions\":{\"fileType\":\"CSV\"}}", 259 | "type": "text" 260 | } 261 | ], 262 | "body": { 263 | "mode": "raw", 264 | "raw": "Year,Costume\n2019,The Golden Girls\n2019,Pennywise" 265 | }, 266 | "url": { 267 | "raw": "{{sasserver}}:8777/cas/sessions/{{sessionid}}/actions/upload", 268 | "host": [ 269 | "{{sasserver}}" 270 | ], 271 | "port": "8777", 272 | "path": [ 273 | "cas", 274 | "sessions", 275 | "{{sessionid}}", 276 | "actions", 277 | "upload" 278 | ] 279 | } 280 | }, 281 | "response": [] 282 | }, 283 | { 284 | "name": "appendNewDataToCostume", 285 | "request": { 286 | "auth": { 287 | "type": "oauth2", 288 | "oauth2": [ 289 | { 290 | "key": "accessToken", 291 | "value": "{{authToken}}", 292 | "type": "string" 293 | }, 294 | { 295 | "key": "addTokenTo", 296 | "value": "header", 297 | "type": "string" 298 | } 299 | ] 300 | }, 301 | "method": "POST", 302 | "header": [ 303 | { 304 | "key": "Content-Type", 305 | "value": "application/json", 306 | "type": "text" 307 | } 308 | ], 309 | "body": { 310 | "mode": "raw", 311 | "raw": "{\"code\": \"data temp.costumesbyyear(append=force) ; set temp.data2019;run;\"}" 312 | }, 313 | "url": { 314 | "raw": "{{sasserver}}:8777/cas/sessions/{{sessionid}}/actions/runCode", 315 | "host": [ 316 | "{{sasserver}}" 317 | ], 318 | "port": "8777", 319 | "path": [ 320 | "cas", 321 | "sessions", 322 | "{{sessionid}}", 323 | "actions", 324 | "runCode" 325 | ] 326 | } 327 | }, 328 | "response": [] 329 | }, 330 | { 331 | "name": "saveCostumeTable", 332 | "request": { 333 | "auth": { 334 | "type": "oauth2", 335 | "oauth2": [ 336 | { 337 | "key": "accessToken", 338 | "value": "{{authToken}}", 339 | "type": "string" 340 | }, 341 | { 342 | "key": "addTokenTo", 343 | "value": "header", 344 | "type": "string" 345 | } 346 | ] 347 | }, 348 | "method": "POST", 349 | "header": [ 350 | { 351 | "key": "Content-Type", 352 | "value": "application/json", 353 | "type": "text" 354 | } 355 | ], 356 | "body": { 357 | "mode": "raw", 358 | "raw": "{\"table\":{\"name\":\"costumesbyyear\",\"caslib\":\"TEMP\",\"singlePass\":\"false\"},\"name\":\"costumesbyyear\",\"replace\":\"true\",\"compress\":\"false\",\"caslib\":\"HALLOWEEN\",\"exportOptions\":{\"fileType\":\"BASESAS\"}}" 359 | }, 360 | "url": { 361 | "raw": "{{sasserver}}:8777/cas/sessions/{{sessionid}}/actions/table.save", 362 | "host": [ 363 | "{{sasserver}}" 364 | ], 365 | "port": "8777", 366 | "path": [ 367 | "cas", 368 | "sessions", 369 | "{{sessionid}}", 370 | "actions", 371 | "table.save" 372 | ] 373 | } 374 | }, 375 | "response": [] 376 | }, 377 | { 378 | "name": "dropTempCaslib", 379 | "request": { 380 | "auth": { 381 | "type": "oauth2", 382 | "oauth2": [ 383 | { 384 | "key": "accessToken", 385 | "value": "{{authToken}}", 386 | "type": "string" 387 | }, 388 | { 389 | "key": "addTokenTo", 390 | "value": "header", 391 | "type": "string" 392 | } 393 | ] 394 | }, 395 | "method": "POST", 396 | "header": [ 397 | { 398 | "key": "Content-Type", 399 | "value": "application/json", 400 | "type": "text" 401 | } 402 | ], 403 | "body": { 404 | "mode": "raw", 405 | "raw": "{\"caslib\":\"TEMP\"}" 406 | }, 407 | "url": { 408 | "raw": "{{sasserver}}:8777/cas/sessions/{{sessionid}}/actions/table.dropCaslib", 409 | "host": [ 410 | "{{sasserver}}" 411 | ], 412 | "port": "8777", 413 | "path": [ 414 | "cas", 415 | "sessions", 416 | "{{sessionid}}", 417 | "actions", 418 | "table.dropCaslib" 419 | ] 420 | } 421 | }, 422 | "response": [] 423 | }, 424 | { 425 | "name": "deleteCASSession", 426 | "request": { 427 | "auth": { 428 | "type": "oauth2", 429 | "oauth2": [ 430 | { 431 | "key": "accessToken", 432 | "value": "{{authToken}}", 433 | "type": "string" 434 | }, 435 | { 436 | "key": "addTokenTo", 437 | "value": "header", 438 | "type": "string" 439 | } 440 | ] 441 | }, 442 | "method": "DELETE", 443 | "header": [], 444 | "url": { 445 | "raw": "{{sasserver}}:8777/cas/sessions/{{sessionid}}", 446 | "host": [ 447 | "{{sasserver}}" 448 | ], 449 | "port": "8777", 450 | "path": [ 451 | "cas", 452 | "sessions", 453 | "{{sessionid}}" 454 | ] 455 | } 456 | }, 457 | "response": [] 458 | } 459 | ], 460 | "auth": { 461 | "type": "oauth2", 462 | "oauth2": [ 463 | { 464 | "key": "accessToken", 465 | "value": "{{authToken}}", 466 | "type": "string" 467 | }, 468 | { 469 | "key": "addTokenTo", 470 | "value": "header", 471 | "type": "string" 472 | } 473 | ] 474 | }, 475 | "protocolProfileBehavior": {} 476 | } -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # **Your examples are welcome and encouraged!** 2 | 3 | ## How to Contribute 4 | 5 | In addition to our SAS-provided samples we have provided a directory [User_and_Aggregated_Samples](User_and_Aggregated_Samples) where you can add your samples as well so that other members of our community can learn fom them too! We ask only that: 6 | 7 | 1. You have verified that the sample can work for anyone and is not specific to a particular environment. 8 | 9 | 2. You open an issue to discuss any questions you have or ideas for contribution. 10 | 11 | 3. You create a directory under [User_and_Aggregated_Samples](User_and_Aggregated_Samples), with a descriptive name, and include a README.md file for usage instructions. 12 | 13 | 4. You follow the below Contributor Agreement. 14 | 15 | ## Contributor License Agreement 16 | 17 | Contributions to this project must be accompanied by a signed 18 | [Contributor Agreement](ContributorAgreement.txt). 19 | You (or your employer) retain the copyright to your contribution, 20 | this simply gives us permission to use and redistribute your contributions as 21 | part of the project. 22 | 23 | ## Code reviews 24 | 25 | All submissions, including submissions by project members, require review. We 26 | use GitHub pull requests for this purpose. Consult 27 | [GitHub Help](https://help.github.com/articles/about-pull-requests/) for more 28 | information on using pull requests. -------------------------------------------------------------------------------- /Compute/README.md: -------------------------------------------------------------------------------- 1 | # SAS REST API Examples 2 | 3 | ## Compute and Jobs 4 | 5 | This repository contains SAS contributed examples that show the capabilities of the CAS Management REST APIs. You can use these examples for learning or for validating your environment. 6 | 7 | You are encouraged to contribute your own examples in the [User Contributions repository](../User_and_Aggregated_Samples). 8 | 9 | ## Examples 10 | 11 | * [CAS Management](casManagement.md) 12 | * [Compute](compute.md) 13 | * [Job Definitions](jobDefinitions.md) 14 | * [Job Execution](jobExecution.md) 15 | 16 | -------------------------------------------------------------------------------- /Compute/jobDefinitions.md: -------------------------------------------------------------------------------- 1 | # Job Definitions API 2 | The Job Definitions API manages jobs using the create, read, update, and delete operations. A Job Definition is a batch execution that contains a list of input parameters, a job type, and a "code" attribute. A job definition can run in multiple execution environments, 3 | based on the type of the job. Possible types might include "cas", "compute", or "rest". The "code" for a job definition 4 | depends on the job definition type. For example, for a job of type "compute", the code is SAS code; and 5 | for a job of type "rest", the code is an UnRAVL script. 6 | 7 | ## API Request Examples 8 | 9 | * [Discover top level links for jobDefinitions](#top-level-link) 10 | * [Get a List of job definitions](#GetJobDefinitions) 11 | * [Create a job definition](#CreateJobDefinition) 12 | * [Update a job definition](#UpdateJobDefinition) 13 | * [Delete a job definition](#DeleteJobDefinition) 14 | 15 | #### Get API Links for Root Resource 16 | Example: Using a HATEOS approach, find the link that returns the 17 | list of job definitions that is defined in the system. 18 | 19 | ``` 20 | GET /jobDefinitions/ 21 | Accept: application/vnd.sas.api+json 22 | ``` 23 | 24 | `Response:` 25 | 26 | ```json 27 | { 28 | "version": 1, 29 | "links": [ 30 | { 31 | "method": "GET", 32 | "rel": "job-definitions", 33 | "href": "/jobDefinitions/definitions", 34 | "uri": "/jobDefinitions/definitions", 35 | "type": "application/vnd.sas.collection" 36 | } 37 | ] 38 | } 39 | ``` 40 | 41 | #### Get a List of Job Definitions 42 | Example: Using the link obtained from the previous example, the administrative type program 43 | gets the list of job definitions that is defined in the system to display in a UI. 44 | 45 | ``` 46 | GET /jobDefinitions/definitions 47 | Accept: application/vnd.sas.collection+json 48 | ``` 49 | 50 | #### Create a Job Definition 51 | Example: A user that is using the administrative program needs to create a job definition to run on a SAS Compute server. The response contains the ID of the newly created job. This ID is used for updates or Delete operations on this job. 52 | 53 | ``` 54 | POST /jobDefinitions/definitions 55 | Content-Type: application/vnd.sas.job.definition+json 56 | Accept: application/vnd.sas.job.definition+json 57 | ``` 58 | 59 | `Body:` 60 | 61 | ```json 62 | { 63 | "version":2, 64 | "name":"Simple proc print", 65 | "description":"Show the contents of sashelp.class using PROC PRINT", 66 | "type":"Compute", 67 | "parameters":[ 68 | { 69 | "version": 1, 70 | "name": "_contextName", 71 | "defaultValue": "SAS Job Execution compute context", 72 | "type": "CHARACTER", 73 | "label": "Context Name", 74 | "required": false 75 | } 76 | ], 77 | "code":"ods html style=HTMLBlue;\nproc print data=sashelp.class; run; quit;\nods html close;" 78 | } 79 | ``` 80 | 81 | `Response:` 82 | 83 | ```json 84 | { 85 | "creationTimeStamp": "2018-03-16T13:39:58.210Z", 86 | "modifiedTimeStamp": "2018-03-16T13:39:58.211Z", 87 | "createdBy": "omitest", 88 | "modifiedBy": "omitest", 89 | "version": 2, 90 | "id": "35d7b64c-bd29-4a28-9d16-94d897224487", 91 | "name": "Simple proc print", 92 | "description": "Show the contents of sashelp.class using PROC PRINT", 93 | "type": "Compute", 94 | "parameters": [ 95 | { 96 | "version": 1, 97 | "name": "_contextName", 98 | "defaultValue": "SAS Job Execution compute context", 99 | "type": "CHARACTER", 100 | "label": "Context Name", 101 | "required": false 102 | } 103 | ], 104 | "code": "ods html style=HTMLBlue;\nproc print data=sashelp.class; run; quit;\nods html close;", 105 | "links": [ 106 | { 107 | "method": "GET", 108 | "rel": "self", 109 | "href": "/jobDefinitions/definitions/35d7b64c-bd29-4a28-9d16-94d897224487", 110 | "uri": "/jobDefinitions/definitions/35d7b64c-bd29-4a28-9d16-94d897224487", 111 | "type": "application/vnd.sas.job.definition" 112 | }, 113 | { 114 | "method": "PUT", 115 | "rel": "update", 116 | "href": "/jobDefinitions/definitions/35d7b64c-bd29-4a28-9d16-94d897224487", 117 | "uri": "/jobDefinitions/definitions/35d7b64c-bd29-4a28-9d16-94d897224487", 118 | "type": "application/vnd.sas.job.definition", 119 | "responseType": "application/vnd.sas.job.definition" 120 | }, 121 | { 122 | "method": "DELETE", 123 | "rel": "delete", 124 | "href": "/jobDefinitions/definitions/35d7b64c-bd29-4a28-9d16-94d897224487", 125 | "uri": "/jobDefinitions/definitions/35d7b64c-bd29-4a28-9d16-94d897224487" 126 | } 127 | ], 128 | "properties": [] 129 | } 130 | ``` 131 | 132 | #### Update a Job Definition 133 | Example: The user needs to modify the SAS code in the job just created to enable filtering by AGE and add a second parameter in the Job definition for AGE. Since the API supports conditional PUT based on ETags, an If-Match header with the ETag must be present in the PUT request to modify the job. 134 | 135 | ``` 136 | PUT /jobDefinitions/definitions/35d7b64c-bd29-4a28-9d16-94d897224487 137 | Content-Type: application/vnd.sas.job.definition+json 138 | Accept: application/vnd.sas.job.definition+json 139 | If-Match: "jetzq6wz" 140 | ``` 141 | 142 | `Body:` 143 | 144 | ```json 145 | "version":2, 146 | "id": "35d7b64c-bd29-4a28-9d16-94d897224487", 147 | "name":"Proc print with AGE filter", 148 | "description": "Show the contents of sashelp.class using PROC PRINT and filtering by AGE.", 149 | "type":"Compute", 150 | "parameters":[ 151 | { 152 | "version": 1, 153 | "name": "_contextName", 154 | "defaultValue": "SAS Job Execution compute context", 155 | "type": "CHARACTER", 156 | "label": "Context Name", 157 | "required": false 158 | }, 159 | { 160 | "version": 1, 161 | "name": "AGE", 162 | "defaultValue": "10", 163 | "type": "NUMERIC", 164 | "label": "Lowest age for report", 165 | "required": false 166 | } 167 | ], 168 | "code":"ods html style=HTMLBlue;\nproc print data=sashelp.class; where age > &AGE; run; quit;\nods html close;" 169 | } 170 | ``` 171 | 172 | `Response:` 173 | 174 | ```json 175 | { 176 | "creationTimeStamp": "2018-03-16T13:39:58.210Z", 177 | "modifiedTimeStamp": "2018-03-16T13:47:45.397Z", 178 | "createdBy": "omitest", 179 | "modifiedBy": "omitest", 180 | "version": 2, 181 | "id": "35d7b64c-bd29-4a28-9d16-94d897224487", 182 | "name": "Proc print with AGE filter", 183 | "description": "Show the contents of sashelp.class using PROC PRINT and filtering by AGE.", 184 | "type": "Compute", 185 | "parameters": [ 186 | { 187 | "version": 1, 188 | "name": "_contextName", 189 | "defaultValue": "SAS Job Execution compute context", 190 | "type": "CHARACTER", 191 | "label": "Context Name", 192 | "required": false 193 | }, 194 | { 195 | "version": 1, 196 | "name": "AGE", 197 | "defaultValue": "10", 198 | "type": "NUMERIC", 199 | "label": "Lowest age for report", 200 | "required": false 201 | } 202 | ], 203 | "code": "ods html style=HTMLBlue;\nproc print data=sashelp.class; where age > &AGE; run; quit;\nods html close;", 204 | "links": [ 205 | { 206 | "method": "GET", 207 | "rel": "self", 208 | "href": "/jobDefinitions/definitions/35d7b64c-bd29-4a28-9d16-94d897224487", 209 | "uri": "/jobDefinitions/definitions/35d7b64c-bd29-4a28-9d16-94d897224487", 210 | "type": "application/vnd.sas.job.definition" 211 | }, 212 | { 213 | "method": "PUT", 214 | "rel": "update", 215 | "href": "/jobDefinitions/definitions/35d7b64c-bd29-4a28-9d16-94d897224487", 216 | "uri": "/jobDefinitions/definitions/35d7b64c-bd29-4a28-9d16-94d897224487", 217 | "type": "application/vnd.sas.job.definition", 218 | "responseType": "application/vnd.sas.job.definition" 219 | }, 220 | { 221 | "method": "DELETE", 222 | "rel": "delete", 223 | "href": "/jobDefinitions/definitions/35d7b64c-bd29-4a28-9d16-94d897224487", 224 | "uri": "/jobDefinitions/definitions/35d7b64c-bd29-4a28-9d16-94d897224487" 225 | } 226 | ], 227 | "properties": [] 228 | } 229 | ``` 230 | 231 | #### Delete a Job Definition 232 | Example: The user no longer needs the job and decides to delete it. 233 | 234 | ``` 235 | DELETE /jobDefinitions/definitions/35d7b64c-bd29-4a28-9d16-94d897224487 236 | ``` 237 | 238 | version 2, last updated 26 Nov, 2019 -------------------------------------------------------------------------------- /ContributorAgreement.txt: -------------------------------------------------------------------------------- 1 | Contributor Agreement 2 | 3 | Version 1.1 4 | 5 | Contributions to this software are accepted only when they are 6 | properly accompanied by a Contributor Agreement. The Contributor 7 | Agreement for this software is the Developer's Certificate of Origin 8 | 1.1 (DCO) as provided with and required for accepting contributions 9 | to the Linux kernel. 10 | 11 | In each contribution proposed to be included in this software, the 12 | developer must include a "sign-off" that denotes consent to the 13 | terms of the Developer's Certificate of Origin. The sign-off is 14 | a line of text in the description that accompanies the change, 15 | certifying that you have the right to provide the contribution 16 | to be included. For changes provided in source code control (for 17 | example, via a Git pull request) the sign-off must be included in 18 | the commit message in source code control. For changes provided 19 | in email or issue tracking, the sign-off must be included in the 20 | email or the issue, and the sign-off will be incorporated into the 21 | permanent commit message if the contribution is accepted into the 22 | official source code. 23 | 24 | If you can certify the below: 25 | 26 | Developer's Certificate of Origin 1.1 27 | 28 | By making a contribution to this project, I certify that: 29 | 30 | (a) The contribution was created in whole or in part by me and I 31 | have the right to submit it under the open source license 32 | indicated in the file; or 33 | 34 | (b) The contribution is based upon previous work that, to the best 35 | of my knowledge, is covered under an appropriate open source 36 | license and I have the right under that license to submit that 37 | work with modifications, whether created in whole or in part 38 | by me, under the same open source license (unless I am 39 | permitted to submit under a different license), as indicated 40 | in the file; or 41 | 42 | (c) The contribution was provided directly to me by some other 43 | person who certified (a), (b) or (c) and I have not modified 44 | it. 45 | 46 | (d) I understand and agree that this project and the contribution 47 | are public and that a record of the contribution (including all 48 | personal information I submit with it, including my sign-off) is 49 | maintained indefinitely and may be redistributed consistent with 50 | this project or the open source license(s) involved. 51 | 52 | then you just add a line saying 53 | 54 | Signed-off-by: Random J Developer 55 | 56 | using your real name (sorry, no pseudonyms or anonymous contributions.) -------------------------------------------------------------------------------- /CoreServices/README.md: -------------------------------------------------------------------------------- 1 | # SAS REST API Examples 2 | 3 | ## Core Services (Platform Administration) 4 | 5 | This repository contains SAS contributed examples that show the capabilities of the Core Services REST APIs. You can use these examples for learning or for validating your environment. 6 | 7 | You are encouraged to contribute your own examples in the [User Contributions repository](../User_and_Aggregated_Samples). 8 | 9 | ## Examples 10 | 11 | * [Annotations](annotations.md) 12 | * [Authorization](authorization.md) 13 | * [Files](files.md) 14 | * [Folders](folders.md) 15 | * [List Data](listData.md) 16 | * [Projects](projects.md) 17 | * [SAS Logon](sasLogon.md) 18 | -------------------------------------------------------------------------------- /CoreServices/resources/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sassoftware/devsascom-rest-api-samples/8371b14b9e354a79d8993d8eb9c87f4110708209/CoreServices/resources/.gitkeep -------------------------------------------------------------------------------- /CoreServices/resources/resources.md: -------------------------------------------------------------------------------- 1 | #### Resource Relationships 2 | 3 | 4 | | Type | Attribute | Description | 5 | |--------------|--------|---------------------------------------------------------------------------------| 6 | | String |`id` | The identifier for the file. This is set internally and cannot be changed. | 7 | | | `contentType` | The content type of the source file. This is set and managed internally. | 8 | | |`createdBy` | The owner of the file. This is set internally and cannot be changed. | 9 | | | `encoding` | The character encoding of the content. This is set and managed internally. | 10 | | |`modifiedBy` | The user who last modified the file. This is set and managed internally. | 11 | | | `name` | The name of the file. This is initialized internally and can be changed after initialization. | 12 | | |`parentUri` | The reference URI of the parent, owner, or associated object. This is managed by the end user. | 13 | | | `contentDisposition` | The content disposition to use while downloading the file. This is managed by the end user.| 14 | | |`description` | A brief description of the files. This is managed by the end user. | 15 | | | `documentType` | The document type of the file. This is managed by the end user.| 16 | | |`expirationTimeStamp` | The date and time at which the file expires or is deleted. This is managed by the end user. | 17 | |Date | `creationTimeStamp` | The date of file creation. This is set internally and cannot be changed.| 18 | | |`modifiedTimeStamp` | The date that the file was last modified. This is set and managed internally. | 19 | |List | ` links` | A collection of links that represent the supported operations for the current resource. The following links are supported:
  • `self : GET` - A link to retrieve the metadata of the file.
  • `patch : PATCH` - A link to update the metadata of the file.
  • `delete : DELETE` - A link to delete the current file resource.
  • `content : GET` - A link to download the actual content of the file.
  • `updateContent : PUT` - A link to update the actual content of the file.
  • | 20 | |Long | `size` | The size of the actual content. This is set and managed internally.| 21 | |Map | ` properties` | A mapping of key/value pairs that can be used to provide more information about the file. This is managed by the end user.| 22 | 23 | #### Root 24 | 25 | Path: `/` 26 | 27 | The root of the API. This resource contains links to the top-level resources in the API. 28 | ##### Links 29 | The `GET /` response includes the following links: 30 | 31 | | Relation | Method | Description | 32 | |--------------|--------|---------------------------------------------------------------------------------| 33 | | checkState | HEAD | Checks the state of the service.
    URI: `/files/files`
    Response type: [`application/json`] | 34 | | create | POST | Uploads a file. Note that Type `*/*` indicates that the content-type is dynamic. The end user must provide the actual content-type to file service, not `*/*`.
    URI: `/files/files`
    Request type: `*/*`
    Response type: `application/vnd.sas.file` | 35 | | files | GET | Returns a collection of files.
    URI: `/files/files`
    Response type: `application/vnd.sas.collection` | 36 | | bulkFiles | POST | Returns a collection of files for multiple parentUri entries using `application/vnd.sas.selection` in the request body.
    URI: `/files/files`
    Request type: `application/vnd.sas.selection`
    Response type: `application/vnd.sas.collection` | 37 | 38 | #### File 39 | 40 | Path: `/files/{fileId}` 41 | 42 | This endpoint returns the file resource or metadata of the file. 43 | 44 | ##### Links 45 | Links from the file resource include the following: 46 | 47 | | Relation | Method | Description | 48 | |--------------|--------|---------------------------------------------------------------------------------| 49 | | self | GET | Returns the meta representation of the file resource.
    URI: `/files/files/{fileId}`
    Response type: [`application/vnd.sas.file`] | 50 | | alternate | GET |Returns the summary representation of the file resource.
    URI: `/files/files/{fileId}`
    Response type: [`application/vnd.sas.summary`] | 51 | | content | GET | Downloads the actual content of the file. The type is the contentType from vnd.sas.file.
    URI: `/files/files/{fileId}/content`
    Response type: [`*/*`] | 52 | | update | PUT | Updates the meta information of the file resource.
    URI: `/files/files/{fileId}`
    Request type: `application/vnd.sas.file`
    Response type: `application/vnd.sas.file`| 53 | | patch | PATCH | Updates the meta information of the file resource.
    URI: `/files/files/{fileId}`
    Request type: `application/vnd.sas.file`
    Response type: `application/vnd.sas.file`| 54 | | updateContent | PUT | Updates the actual content of the file. Note that Type `*/*` indicates that content-type is dynamic. The end-user must pass on actual content-type to file service, not `*/*`.
    URI: `/files/files/{fileId}/content`
    Request type: `*/*`
    Response type: `application/vnd.sas.file` | 55 | | delete | DELETE | Removes the file resource.
    URI: `/files/files/{fileId}`| 56 | | create | POST | Uploads a file. Note that Type `*/*` indicates that content-type is dynamic. The end user must pass on actual content-type to file service, not `*/*`.
    URI: `/files/files`
    Request type: `*/*`
    Response type: `application/vnd.sas.file` | 57 | | copyFile | POST | If the user has Read access to the file, copies the file.
    URI: `/files/files/{fileId}/copy`
    Response type: `application/vnd.sas.file` | 58 | 59 | 60 | #### File Collection 61 | 62 | Path: `/files` 63 | 64 | This endpoint returns the collection of file resource. 65 | 66 | ##### Links 67 | 68 | Links from the collection include the following: 69 | 70 | | Relation | Method | Description | 71 | |--------------|--------|---------------------------------------------------------------------------------| 72 | | self | GET | Returns the current page from the collection. | 73 | | prev | GET | Returns the previous page of the collection. This link is omitted if the current view is on the first page. | 74 | | next | GET | Returns the next page of the collection. This link is omitted if the current view is on the last page of the collection. | 75 | | first | GET | Returns the first page of the collection. This link is omitted if the current view is on the first page. | 76 | 77 | 78 | -------------------------------------------------------------------------------- /CoreServices/sasLogon.md: -------------------------------------------------------------------------------- 1 | # SAS Logon API 2 | Most SAS Viya APIs require authentication for all operations, and many require authorization. For SAS Viya APIs, authentication and authorization 3 | require a valid access token. The SAS Logon API provides the standard OAuth protocol endpoints through which clients obtain access tokens to make 4 | subsequent API calls. Access tokens are obtained when a client requests and authenticates to the SAS Logon API with a valid form of authorization, 5 | which is expressed in the form of an authorization grant. 6 | 7 | Developers must first have their SAS administrator register a client identifier. The SAS administrator then provides API developers 8 | with the client identifier and client secret to use in API calls. Developers must use the client identifier and secret in all API calls. 9 | 10 | ## API Request Examples 11 | 12 | 13 | * [Obtain an access token using client credentials](#ObtainAccessTokenUsingClientCredentials) 14 | * [Obtain an access token using resource owner password credentials](#ObtainAccessTokenUsingResourceOwnerPasswordCredentials) 15 | * [List clients](#ListClients) 16 | * [Retrieve client](#RetrieveClient) 17 | * [Create client](#CreateClient) 18 | * [Update client](#UpdateClient) 19 | * [Change secret](#ChangeSecret) 20 | * [Delete client](#DeleteClient) 21 | * [Obtain token to create client](#ObtainTokenCreateClient) 22 | 23 | 24 | #### Obtain an Access Token Using Client Credentials 25 | Here is an example of a client application obtaining an access token using its client credentials. 26 | 27 | ``` 28 | POST /SASLogon/oauth/token 29 | Content-Type: application/x-www-form-urlencoded 30 | Authorization: Basic YXBwOnNlY3JldA== 31 | Accept: application/json 32 | ``` 33 | 34 | `Body:` 35 | 36 | ```text 37 | grant_type=client_credentials 38 | ``` 39 | 40 | `Response:` 41 | 42 | ```json 43 | { 44 | "access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6ImxlZ2FjeS10b2tlbi1rZXkiLCJ0eXAiOiJKV1QifQ.eyJqdGkiOiIzMjJmZGIyOTAyYzg0YTUxYTY2N2I5MGI5OWZhMWYwNiIsInN1YiI6ImFwcCIsImF1dGhvcml0aWVzIjpbInVhYS5ub25lIl0sInNjb3BlIjpbInVhYS5ub25lIl0sImNsaWVudF9pZCI6ImFwcCIsImNpZCI6ImFwcCIsImF6cCI6ImFwcCIsImdyYW50X3R5cGUiOiJjbGllbnRfY3JlZGVudGlhbHMiLCJyZXZfc2lnIjoiNjY4ZjYzYjkiLCJpYXQiOjE1MjIxNjY2MTEsImV4cCI6MTUyMjIwOTgxMSwiaXNzIjoiaHR0cHM6Ly9leGFtcGxlLnNhcy5jb20vU0FTTG9nb24vb2F1dGgvdG9rZW4iLCJ6aWQiOiJ1YWEiLCJhdWQiOlsiYXBwIl19.VPuBsB2Yod-OKtt87nhjPFlkkhG3eN48CvFkbxvWli5hDYMihTmTBVTSuAAdqaZoesNwSICYWmjBbS0FJkIp5kNKxuxb8sEtwUa8zVS5FZy0D9Ocir1mS5Fgz7ox0u6YQDXKe_mC6tij8YaYzRxJiS-fcVe6vCaRjXHbIRqVQ3U", 45 | "token_type": "bearer", 46 | "expires_in": 43199, 47 | "scope": "uaa.none", 48 | "jti": "322fdb2902c84a51a667b90b99fa1f06" 49 | } 50 | ``` 51 | 52 | 53 | #### Obtain an Access Token Using Resource Owner Password Credentials 54 | Here is an example of a client application obtaining an access token for an end user by providing the user's password credentials. 55 | 56 | ``` 57 | POST /SASLogon/oauth/token 58 | Content-Type: application/x-www-form-urlencoded 59 | Authorization: Basic YXBwOnNlY3JldA== 60 | Accept: application/json 61 | ``` 62 | 63 | `Body:` 64 | 65 | ```text 66 | grant_type=password&username=bob&password=bobspassword 67 | ``` 68 | 69 | `Response:` 70 | 71 | ```json 72 | { 73 | "access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6ImxlZ2FjeS10b2tlbi1rZXkiLCJ0eXAiOiJKV1QifQ.eyJqdGkiOiIzNTM4ZTQxNTEyNDY0NmU3YTJiZjA1NDBlNTM3MjNlNSIsInN1YiI6IjAzMzNiODlkLTc5MjUtNDllZS04N2Y3LTQ4YzY1Mzg2N2RlZCIsInNjb3BlIjpbIm9wZW5pZCIsImdyb3VwMSIsImdyb3VwMiIsImdyb3VwMyJdLCJjbGllbnRfaWQiOiJhcHAiLCJjaWQiOiJhcHAiLCJhenAiOiJhcHAiLCJncmFudF90eXBlIjoicGFzc3dvcmQiLCJ1c2VyX2lkIjoiMDMzM2I4OWQtNzkyNS00OWVlLTg3ZjctNDhjNjUzODY3ZGVkIiwib3JpZ2luIjoidWFhIiwidXNlcl9uYW1lIjoiYm9iIiwiZW1haWwiOiJub25lIiwiYXV0aF90aW1lIjoxNTIyMTY3MTY3LCJyZXZfc2lnIjoiOWEzYzI0ZWQiLCJpYXQiOjE1MjIxNjcxNjcsImV4cCI6MTUyMjIxMDM2NywiaXNzIjoiaHR0cHM6Ly9leGFtcGxlLnNhcy5jb20vU0FTTG9nb24vb2F1dGgvdG9rZW4iLCJ6aWQiOiJ1YWEiLCJhdWQiOlsiYXBwIiwib3BlbmlkIl19.EOpYXf5acyiTn1wY5Tjr9vdu5Ez_UyPnYriMPlR9DkDTPtxxphdCiQweMEx8bjevWmFhDV-m4MDFm9F551F36cyhkpaXq39Xu6My_iDdc-xdAMvm04PHhz6p2NDSjCrmg9L5remIK-WQDyN3klkKNQvuN2V8jklVoXVMj_bBgpg", 74 | "token_type": "bearer", 75 | "expires_in": 43199, 76 | "scope": "openid group1 group2 group3", 77 | "jti": "322fdb2902c84a51a667b90b99fa1f06" 78 | } 79 | ``` 80 | 81 | 82 | #### List Clients 83 | Here is an example of performing a GET request to list clients. 84 | ``` 85 | GET /SASLogon/oauth/clients?filter=client_id+eq+%22XCUNhS%22&sortBy=client_id&sortOrder=descending&startIndex=1&count=10 86 | Authorization: Bearer 4c24145d284840feb9e1d4e247dfee56 87 | Accept: application/json 88 | ``` 89 | 90 | `Response:` 91 | 92 | ```json 93 | { 94 | "resources" : [ { 95 | "scope" : [ "clients.read", "clients.write" ], 96 | "client_id" : "XCUNhS", 97 | "resource_ids" : [ "none" ], 98 | "authorized_grant_types" : [ "client_credentials" ], 99 | "redirect_uri" : [ "http://ant.path.wildcard/**/passback/*", "http://test1.com" ], 100 | "autoapprove" : [ "true" ], 101 | "authorities" : [ "clients.read", "clients.write" ], 102 | "token_salt" : "tCZeCV", 103 | "allowedproviders" : [ "uaa", "ldap", "my-saml-provider" ], 104 | "name" : "My Client Name", 105 | "lastModified" : 1548439765963 106 | } ], 107 | "startIndex" : 1, 108 | "itemsPerPage" : 1, 109 | "totalResults" : 1, 110 | "schemas" : [ "http://cloudfoundry.org/schema/scim/oauth-clients-1.0" ] 111 | } 112 | ``` 113 | 114 | 115 | #### Retrieve Client 116 | Here is an example of performing a GET request to retrieve clients. 117 | 118 | ``` 119 | GET /SASLogon/oauth/clients/dm13Sn 120 | Authorization: Bearer 4c24145d284840feb9e1d4e247dfee56 121 | Accept: application/json 122 | ``` 123 | 124 | `Response:` 125 | 126 | ```json 127 | { 128 | "scope" : [ "clients.read", "clients.write" ], 129 | "client_id" : "dm13Sn", 130 | "resource_ids" : [ "none" ], 131 | "authorized_grant_types" : [ "client_credentials" ], 132 | "redirect_uri" : [ "http://ant.path.wildcard/**/passback/*", "http://test1.com" ], 133 | "autoapprove" : [ "true" ], 134 | "authorities" : [ "clients.read", "clients.write" ], 135 | "token_salt" : "KWIYYl", 136 | "allowedproviders" : [ "uaa", "ldap", "my-saml-provider" ], 137 | "name" : "My Client Name", 138 | "lastModified" : 1548439766817, 139 | "required_user_groups" : [ ] 140 | } 141 | ``` 142 | 143 | 144 | #### Create Client 145 | Here is an example of performing a POST request to create a client. 146 | 147 | ``` 148 | POST /SASLogon/oauth/clients 149 | Content-Type: application/json 150 | Authorization: Bearer 6eb2f4f9eeee48d4ac40c4c86509e3d7 151 | Accept: application/json 152 | ``` 153 | 154 | `Body:` 155 | 156 | ```json 157 | { 158 | "scope" : [ "clients.read", "clients.write" ], 159 | "client_id" : "FYBc34", 160 | "client_secret" : "secret", 161 | "resource_ids" : [ ], 162 | "authorized_grant_types" : [ "client_credentials" ], 163 | "redirect_uri" : [ "http://test1.com", "http://ant.path.wildcard/**/passback/*" ], 164 | "authorities" : [ "clients.read", "clients.write" ], 165 | "token_salt" : "mOxTVD", 166 | "autoapprove" : true, 167 | "allowedproviders" : [ "uaa", "ldap", "my-saml-provider" ], 168 | "name" : "My Client Name" 169 | } 170 | ``` 171 | 172 | `Response:` 173 | 174 | ```json 175 | { 176 | "scope" : [ "clients.read", "clients.write" ], 177 | "client_id" : "FYBc34", 178 | "resource_ids" : [ "none" ], 179 | "authorized_grant_types" : [ "client_credentials" ], 180 | "redirect_uri" : [ "http://ant.path.wildcard/**/passback/*", "http://test1.com" ], 181 | "autoapprove" : [ "true" ], 182 | "authorities" : [ "clients.read", "clients.write" ], 183 | "token_salt" : "mOxTVD", 184 | "allowedproviders" : [ "uaa", "ldap", "my-saml-provider" ], 185 | "name" : "My Client Name", 186 | "lastModified" : 1548439765169, 187 | "required_user_groups" : [ ] 188 | } 189 | ``` 190 | 191 | 192 | #### Update Client 193 | Here is an example of performing a PUT request to list clients. 194 | 195 | ``` 196 | PUT /SASLogon/oauth/clients/P5yPMY 197 | Content-Type: application/json 198 | Authorization: Bearer 6eb2f4f9eeee48d4ac40c4c86509e3d7 199 | Accept: application/json 200 | ``` 201 | 202 | `Body:` 203 | 204 | ```json 205 | { 206 | "scope" : [ "clients.new", "clients.autoapprove" ], 207 | "client_id" : "P5yPMY", 208 | "authorized_grant_types" : [ "client_credentials" ], 209 | "redirect_uri" : [ "http://redirect.url" ], 210 | "autoapprove" : [ "clients.autoapprove" ] 211 | } 212 | ``` 213 | 214 | `Response:` 215 | 216 | ```json 217 | { 218 | "scope" : [ "clients.new", "clients.autoapprove" ], 219 | "client_id" : "P5yPMY", 220 | "resource_ids" : [ "none" ], 221 | "authorized_grant_types" : [ "client_credentials" ], 222 | "redirect_uri" : [ "http://redirect.url" ], 223 | "autoapprove" : [ "clients.autoapprove" ], 224 | "authorities" : [ "clients.read", "clients.write" ], 225 | "token_salt" : "9UnUQG", 226 | "allowedproviders" : [ "uaa", "ldap", "my-saml-provider" ], 227 | "name" : "My Client Name", 228 | "lastModified" : 1548439762286, 229 | "required_user_groups" : [ ] 230 | } 231 | ``` 232 | 233 | 234 | #### Change Secret 235 | Here is an example of performing a PUT request to change a secret. 236 | 237 | ``` 238 | PUT /SASLogon/oauth/clients/1le3s6/secret 239 | Content-Type: application/json 240 | Authorization: Bearer 6eb2f4f9eeee48d4ac40c4c86509e3d7 241 | Accept: application/json 242 | ``` 243 | 244 | `Body:` 245 | 246 | ```json 247 | { 248 | "clientId" : "1le3s6", 249 | "secret" : "new_secret" 250 | } 251 | ``` 252 | 253 | `Response:` 254 | 255 | ```json 256 | { 257 | "status" : "ok", 258 | "message" : "secret updated" 259 | } 260 | ``` 261 | 262 | 263 | #### Delete Client 264 | Here is an example of deleting a client. 265 | 266 | ``` 267 | DELETE /SASLogon/oauth/clients/8h4yGk 268 | ``` 269 | 270 | 271 | #### Obtain Token to Create Client 272 | Here is an example of using a consul ACL token to obtain an OAuth access token. The OAuth access token can be used to create a new client. 273 | 274 | ``` 275 | POST /SASLogon/oauth/clients/consul 276 | X-Consul-Token: 29c4700f-ea89-41cd-8bc4-4198ccaa5bf9 277 | Accept: application/json 278 | ``` 279 | 280 | `Response:` 281 | 282 | ```json 283 | { 284 | "access_token" : "eyJhbGciOiJSUzI1NiIsImtpZCI6ImxlZ2FjeS10b2tlbi1rZXkiLCJ0eXAiOiJKV1QifQ.eyJqdGkiOiIzNTM4ZTQxNTEyNDY0NmU3YTJiZjA1NDBlNTM3MjNlNSIsInN1YiI6IjAzMzNiODlkLTc5MjUtNDllZS04N2Y3LTQ4YzY1Mzg2N2RlZCIsInNjb3BlIjpbIm9wZW5pZCIsImdyb3VwMSIsImdyb3VwMiIsImdyb3VwMyJdLCJjbGllbnRfaWQiOiJhcHAiLCJjaWQiOiJhcHAiLCJhenAiOiJhcHAiLCJncmFudF90eXBlIjoicGFzc3dvcmQiLCJ1c2VyX2lkIjoiMDMzM2I4OWQtNzkyNS00OWVlLTg3ZjctNDhjNjUzODY3ZGVkIiwib3JpZ2luIjoidWFhIiwidXNlcl9uYW1lIjoiYm9iIiwiZW1haWwiOiJub25lIiwiYXV0aF90aW1lIjoxNTIyMTY3MTY3LCJyZXZfc2lnIjoiOWEzYzI0ZWQiLCJpYXQiOjE1MjIxNjcxNjcsImV4cCI6MTUyMjIxMDM2NywiaXNzIjoiaHR0cHM6Ly9leGFtcGxlLnNhcy5jb20vU0FTTG9nb24vb2F1dGgvdG9rZW4iLCJ6aWQiOiJ1YWEiLCJhdWQiOlsiYXBwIiwib3BlbmlkIl19.EOpYXf5acyiTn1wY5Tjr9vdu5Ez_UyPnYriMPlR9DkDTPtxxphdCiQweMEx8bjevWmFhDV-m4MDFm9F551F36cyhkpaXq39Xu6My_iDdc-xdAMvm04PHhz6p2NDSjCrmg9L5remIK-WQDyN3klkKNQvuN2V8jklVoXVMj_bBgpg", 285 | "token_type" : "bearer", 286 | "expires_in" : 43199, 287 | "scope" : "uaa.admin", 288 | "jti" : "fd558f0226df43cfbe12e044e3ac1d45" 289 | } 290 | ``` 291 | 292 | 293 | 294 | version 1, last updated 21 NOV, 2019 295 | -------------------------------------------------------------------------------- /DataManagement/README.md: -------------------------------------------------------------------------------- 1 | # SAS REST API Examples 2 | 3 | ## Data Management 4 | 5 | This repository contains SAS contributed examples that show the capabilities of the Data Management REST APIs. You can use these examples for learning or for validating your environment. 6 | 7 | You are encouraged to contribute your own examples in the [User Contributions repository](../User_and_Aggregated_Samples). 8 | 9 | ## Examples 10 | 11 | * [Data Quality](dataQuality.md) 12 | * [Data Sources](dataSources.md) 13 | * [Data Tables](dataTables.md) 14 | * [Row Sets](rowSets.md) 15 | -------------------------------------------------------------------------------- /DataManagement/catalog/overview.md: -------------------------------------------------------------------------------- 1 | 2 | #### Context 3 | 4 | This API is used to define and manage [metadata](#Metadata). 5 | 6 | ##### Background and Overview 7 | 8 | This API provides the basic interface to discover, find, and elaborate on metadata within the environment. Metadata in the context of this API refers to descriptive information about any currently defined asset. 9 | 10 | ##### Use Cases 11 | - retrieve metadata for assets 12 | - define metadata for information consumed, used, or related to assets 13 | - integrate metadata with third-party systems 14 | - find metadata for assets 15 | - build and manage 'bots' which populate the catalog with table metadata 16 | 17 | #### Concepts 18 | As part of managing metadata, catalog first requires information about the kind of metadata that will be introduced. Consumers describe the information they wish to manage by providing one or more *type definitions*. Metadata content is added using the Catalog API as *instances* that specify a type definition. The type definition is used to validate and interpret the data in the instance. 19 | 20 | These concepts are described in more detail below. 21 | 22 | ##### Type Definitions 23 | Type definitions define the kind of entities and relationships (along with any attributes) that are allowed for an asset. Type definitions are analogous to the concept of a *class* in an object oriented system; or that of a *DDL* in a relational model. 24 | 25 | Type definition names must be unique. 26 | 27 | There are four kinds of type definitions: 28 | 29 | ###### Attribute Type Definitions 30 | Attribute Type Definitions describe properties for the remaining kinds of type definitions. For example, an Entity Type Definition that describes an individual may reference attribute type definitions for contact information such as a phone number or mailing address. 31 | 32 | ####### Enumerations 33 | Attribute definitions can describe a list of allowed values by specifying `ENUM` as the attributeKind field of the Attribute Type Definition. Enumerations have a list of `elementDefinitions` that describe the allowed values. 34 | 35 | ####### Attribute Definitions 36 | Attribute type definitions are referenced in type definitions as the `type` field in their `attributes` list; these model elements are known as `attribute definitions`. 37 | 38 | A `typeCriteria` object can be included within an attribute definition. This inclusion enables the expression of constraints on the content that are allowed within the attribute's value at run time. 39 | - minLength: the shortest acceptable value; only valid for string types 40 | - maxLength: the longest acceptable value; only valid for string types 41 | - minimum: the smallest acceptable value; only valid for numeric types 42 | - maximum: the largest acceptable value; only valid for numeric types 43 | - minItems: the smallest number of items allowed in the collection; only valid for collections 44 | - maxItems: the largest number of items allowed in the collection; only valid for collections 45 | - required: indicates that the attribute value must be specified 46 | 47 | For attribute definitions of type `collection`, the type criteria must include an `items` element that contains a list of attribute definitions that constitute the elements in the collection. Note that specifying additional collection valued attributes in this 'items' list is not supported; the model does not support collections of collections within a single attribute. 48 | 49 | ###### Entity Type Definitions 50 | Entity Type Definitions describe the nouns in the system. Some examples are data sets or reports. 51 | 52 | Entity type definitions can have a *base type* that simplifies modeling by incorporating properties from the base type into the set of properties of the entity type definition. This acts like inheritance of fields in an object-oriented system. 53 | 54 | ###### Classification Type Definitions 55 | Classification Type Definitions describe a kind of annotation that can be related to Instances. For instance, a Security classification can be attached to a dataset to describe the sensitivity of the dataset. 56 | 57 | Like Entity type definitions, classification type definitions can have a base type that incorporates properties from the base type into the set of properties of the classification type definition. 58 | 59 | ####### Classification Hierarchies 60 | Classification instances support arrangement in a hierarchy. This structure is useful, for example, when instances represent part of a taxonomy. It is important to remember, however, that this hierarchy is unrelated to the derivation hierarchy. Instances in a hierarchy of a classification need not adhere to the same hierarchy used to model the classification instances. 61 | 62 | ###### Relationship Type Definitions 63 | Relationship Type Definitions describe the kinds of connections that can occur between *entity* and *classification* instances. 64 | 65 | Relationship type definitions describe directed relationships between entity and classification instances of specific types. Entities and classifications can appear on either endpoint of a relationship type definition in any combination (e.g., entity to entity, entity to classification, classification to classification, and classification to entity). For instance, relationship type definitions may describe: 66 | - a hierarchical file system with a relationship between parent and child folder entities 67 | - a taxonomy built from classification instances 68 | - a security classification between a dataset entity and a 'Sensitive' classification instance 69 | 70 | Both entity and classification type definitions support the concept of a base type. Base types specified in the relationship type definition allow any type derived from that base to participate in the relationship. 71 | 72 | ##### Instances 73 | Instances are used to capture the metadata of objects in the system. If we extend our object-oriented analogy from type definitions, classes are to type definitions as objects are to instances. For example, a dataSet type definition describes the properties and relationships for any dataset, but a dataset instance captures metadata for a specific dataset. 74 | 75 | There are three kinds of instances: 76 | 77 | ###### Entities 78 | Entities are records of specific objects that capture the metadata of that object. For instance, a dataset instance may specify a name of 'BASEBALL.sashdat' with row and column counts derived from a table in a particular library within the Viya system. 79 | 80 | ####### Uniqueness Constraints 81 | Unlike type definitions, entity instance names do not have to be unique. 82 | 83 | Entities have a `resourceId` field that is used to refer to the URI for the original object. If the type definition metaCategory is set to `PRIMARY`, the resourceId fields must be unique among instances of that type. 84 | 85 | ###### Classifications 86 | Classifications serve as annotations that are typically referenced many times. While entities tend to refer to specific resources, classifications are used to add additional dimensions to the information captured by an entity. For instance, many datasets may be associated with a 'Sensitive' security classification. 87 | 88 | ####### Uniqueness Constraints 89 | Classification instances can be arranged within a hierarchy by specifying a `parentID`. Names must be unique across classification instances with the same parent. If no parent is specified, names must be unique across all the classification instances without a parent. 90 | 91 | ###### Relationships 92 | Relationships serve to identify connections between entities and classifications. For instance, our BASEBALL.sashdat table entity may have a relationship to the SASHELP library entity. The type of the relationship conveys the semantics of the connection (along with any attributes attached to the relationship). 93 | 94 | ##### Search 95 | One of the primary use cases for the catalog service is discovering assets that are available for use. The catalog supports the traditional filter semantics that are common across SAS APIs; but these tend to require very precise knowledge about the assets of interest. 96 | 97 | To fully support the discovery use case, the Catalog API also supports information retrieval techniques in the form of a search engine that allows retrieval of information using a query syntax that returns results based on relevance to one or more search criteria. 98 | 99 | To enable search for different kinds of SAS assets, a *search index definition* for some assets has been added to the Catalog API. The index definition describes which entity and relationship definitions should be included in the search index, along with the properties to index. 100 | 101 | When updates to the catalog are made (such as creating new instances, updating existing instances, or deleting instances), indices that reference the type of the instance (or instances) being manipulated are automatically updated. 102 | 103 | ##### Tags 104 | Tags provide a way to attach user-provided labels to entities. 105 | 106 | When tags are incorporated into search index definitions, users can use tags like a virtual bookmark and rapidly recall or share entities that have been tagged. 107 | 108 | ##### Views 109 | When entities, classifications and relationships are combined, the result is a directed graph that captures the structure of information within the Catalog API. It is frequently useful to be able to query the graph in a way that returns the elements of the graph all once, rather than iteratively asking the Catalog API for more information. Selecting a set of related instances is performed thru a *View*, which conceptually serves as a saved query. 110 | 111 | Views are expressed using a Graph query syntax: 112 | - () describes an entity 113 | - -[]-, -[]->, <-[]- describes relationships 114 | - <> describes a classification. 115 | 116 | Each of these can be given a named projection, that allows matching objects to be referenced later in the query. 117 | 118 | Information is retrieved by matching graphs against the pattern described by the query and returning the parts that are interesting. For example, matching everything in the catalog uses the query 119 | 120 | match (x) return x 121 | 122 | Property constraints can further reduce the set of results. For example, to return an entity with a specific ID use: 123 | 124 | match(x {id:7462f4c3-f225-42cf-bc3d-0fdfcf09b190}) 125 | return x 126 | 127 | Each of the elements can be further constrained with type information. For example, to return all of the `dataSet` instances use: 128 | 129 | match(x:dataSet) return x 130 | 131 | or to return the dataSet and its dataFields use: 132 | 133 | match(x:dataSet)-[]->(y:dataField) return x,y 134 | 135 | Type constraints can specify lists of types: 136 | 137 | (y:sasColumn|casColumn)
    // either one 138 | (x)-[r:eq(role, "Associated)]->(y)
    // Only association rels 139 | (x)-[r:in(role,"Associated","Composition")]->(y) // either role 140 | 141 | Match clauses can reference projections that have been previously defined. For instance, to get a dataset, its columns, and the semantic classifications attached to the columns: 142 | 143 | match (t:dataSet {id:"..."})-[r:dataSetDataFields]-(c:dataField) 144 | match (c)-[sc:semanticClassifications]-> 145 | return t,r,c,scr,sc 146 | 147 | Relationships can include a path length expression: 148 | 149 | -[r*..2]-> // Up to two relationships away 150 | -[r*2..4]-> // between 2 and 4 relationships away 151 | 152 | where the lower and upper bounds are expressed in the range following the asterisk. This approach is useful when views have to traverse multiple relationships. 153 | 154 | ##### Support for history 155 | Entity instances can be configured to maintain old revisions according to a policy that is configured on either the entity or the entity's type definition. Before any changes are applied to the instance, a copy of the current state is written to the catalog service. 156 | 157 | Entity instances and type definitions allow you to specify: 158 | - a policy that controls how history records are retained 159 | - a parameter that governs the policy 160 | - a view that describes what content is maintained as part of the history 161 | 162 | For instance, a policy of `depth` and a parameter of `10` means that at most 10 different revisions will be maintained within the catalog service. The view is used to determine which entities, relationships, and classifications are to be included within the history record. 163 | 164 | The policy `none` indicates that no history is to be kept. 165 | 166 | If no history configuration is set for an instance, the behavior is determined by the type definition. This also allows the configuration to be set on a base type of the type definition, which is then inherited by types derived from the base type. 167 | 168 | ##### Agents 169 | Agents are used to introduce content into the catalog. 170 | 171 | The Catalog API enables constructing, running, and monitoring agents. Agents write their results back to the catalog service using the same concepts and interfaces that are documented here. -------------------------------------------------------------------------------- /DataManagement/catalog/postman/catalog/create-and-run-discovery-agent/README.md: -------------------------------------------------------------------------------- 1 | # Create and Run a Discovery Agent 2 | ## Overview 3 | This collection leverages the Catalog API to create and run a Discovery Agent. 4 | 5 | ## Prerequisites 6 | 7 | ### Variables 8 | The Postman collection comes with variables that you must assign either at the collection or environment level. Assign values to the following variables prior to running the collection: 9 | - `sasserver` - the location of the SAS Viya server; for example: https://myserver.sas.com 10 | - `access_token` 11 | Other variables are assigned programmatically during the REST calls using code in the Postman Tests tab. 12 | 13 | ## Usage 14 | 1. Download the JSON collection and the sasserver.env. Then import the files into Postman. 15 | 2. Select sasserver.env as the environment and edit your environment variables to match those contained in the collection requests (sasserver, access_token). 16 | 3. Be sure to authenticate to your server before testing the endpoints. 17 | 4. You can run one request at a time. You can also run the collection, but uncheck DELETE Discovery Agent, GET Discovery Agents, and PUT Update Discovery Agent if you do so. The GET Discovery Agent State request has code in the Tests tab that will execute the request until the "running" state is ended. 18 | 19 | ## Endpoints Used 20 | - [/catalog/bots](https://developer.sas.com/rest-apis/catalog/createAgent) - Create an Agent 21 | - [/catalog/bots/{agentId}/state](https://developer.sas.com/rest-apis/catalog/updateAgentRunState) - Update Agents run state 22 | - [/catalog/bots/{agentId}/state](https://developer.sas.com/rest-apis/catalog/getAgentRunState) - Get an Agent's execution state 23 | - [/catalog/bots/{agentId}](https://developer.sas.com/rest-apis/catalog/getAgent) - Get an Agent by its ID 24 | - [catalog/bots/{agentId}](https://developer.sas.com/rest-apis/catalog/deleteAgent) - Delete an Agent by its ID 25 | - [/catalog/bots](https://developer.sas.com/rest-apis/catalog/getAgents) -Get a list of Agents 26 | - [/catalog/bots](https://developer.sas.com/rest-apis/catalog/updateAgent) - Update an Agent by its ID 27 | 28 | ## Supported Versions 29 | - Viya 4 30 | - 2023.09 31 | ## Additional Resources 32 | -------------------------------------------------------------------------------- /DataManagement/catalog/postman/catalog/create-and-search-on-tags/README.md: -------------------------------------------------------------------------------- 1 | # Create and Search on Tags 2 | ## Overview 3 | This collection leverages the Catalog API to create and search tags. 4 | - In this use case, three instances are created and named Groceries, Rent and Going Out. Each represents a log of the different expenses a person might use to track spending. 5 | - A tag is created named Expenses. The tag is applied to the instances. 6 | - The tag is searched using the `/search` endpoint. 7 | - Get the tag by `tag_name` and `tag_id`. 8 | - Update the tag name. 9 | - Remove an instance from a tag. 10 | - Delete a tag. 11 | - Use the `/deletions` endpoint to delete the instances. 12 | 13 | **NOTE**: Making changes to the tag/instances outside of the requests in this collection or executing the requests in a different order might void some of the variables that are used in the requests. Some examples are: updating the tag instance's ID or name, changing the environment variables before some requests, or deleting any environment variables. If you do make any changes, update the environment variables accordingly to avoid any issues. You can also run the two delete requests to clean up the tags and instances. 14 | 15 | ### Variables 16 | The Postman collection comes with variables that you must assign in the sasserver.env prior to running the collection: 17 | - `sasserver` - the location of the SAS Viya server; for example: https://myserver.sas.com 18 | - `access_token` 19 | 20 | Create or assign values in your environment to the following: 21 | - `tag_name` - the name of the tag to be created and applied to the instances. Set to "Expenses" by default. Can be edited to fit your use case. 22 | 23 | Other variables are assigned programmatically during the REST calls using code in the Postman Tests tab. 24 | 25 | ## Usage 26 | 1. Download the JSON collection and the sasserver.env. Import the files into Postman. 27 | 2. Select sasserver.env as the environment. Edit your environment variables to match those contained in the collection requests (sasserver, access_token) or by running `Delete Tag` as it resets the value back to "Expenses". 28 | 3. Authenticate to your server before testing the endpoints by running the first request: `0. Get token`. 29 | - For the Postman collection only, the IDs for the created sample instances are saved in environment variables that follow the pattern: `sample_instance[0|1|2]_id`. If you wish to have a specific name (ex: `expense0_id`), be sure to make that change within the other requests as well. These changes are made in the Tests tab and the request body. 30 | ## Endpoints Used 31 | - [/catalog/instances](https://developer.sas.com/rest-apis/catalog/createInstance) - Create instances 32 | - [/catalog/tags](https://developer.sas.com/rest-apis/catalog#tags) - Create/Get/Update a tag 33 | - [/catalog/search](https://developer.sas.com/rest-apis/catalog#search) - Search 34 | - [/catalog/deletions](https://developer.sas.com/rest-apis/catalog#deletions) - Deletions 35 | ## Supported Versions 36 | - Viya 4 37 | - 2023.09 38 | ## Additional Resources 39 | - Full documentation of the Catalog API can be found [here](http://swagger.na.sas.com/swagger-ui/?url=/apis/catalog/v1/openapi-all.json). 40 | -------------------------------------------------------------------------------- /DataManagement/catalog/postman/catalog/create-and-use-asset/README.md: -------------------------------------------------------------------------------- 1 | # Create and Use Asset 2 | 3 | ## Overview 4 | 5 | This collection leverages the Catalog API to create and use an asset. 6 | 7 | Before creating an asset, a schema must first be defined. Afterwards, assets can be created according to this defined schema. 8 | 9 | In the Catalog API, a schema for an asset is defined using a type definition. For this use case, we create a type definition for a new asset type named *publicDataSet*. 10 | 11 | With the schema defined, assets and relationships can be created using the endpoints of instances. In the Catalog API, an instance of an asset type is known as an entity. The scenario shows both how to create a single asset and how to use an archive to create or update assets and relationships. The relationship in this scenario is adding a contact to an asset. 12 | 13 | The assets are queried using both a view and a filter on the instances endpoint. 14 | 15 | ## Prerequisites 16 | 17 | ### Variables 18 | 19 | The Postman collection comes with variables that you must assign either at the collection or the environment level. Assign values to the following variables prior to running the collection: 20 | 21 | - `sasserver` - the location of the SAS Viya server; for example: https://myserver.sas.com 22 | - `access_token` 23 | - `username` 24 | Other variables are assigned programmatically during the REST calls using code in the Postman Tests tab. 25 | 26 | ## Usage 27 | 28 | 1. Download the JSON collection and the sasserver.env. Then import the files into Postman. 29 | 2. Select sasserver.env as the environment and edit your environment variables to match those contained in the collection requests (sasserver, access_token, and username). 30 | 3. Be sure to authenticate to your server before testing the endpoints. 31 | 32 | ## Endpoints Used 33 | 34 | - [/catalog/definitions](https://developer.sas.com/rest-apis/catalog/createTypeDefinition) - Create Type Definition 35 | - [/catalog/instances](https://developer.sas.com/rest-apis/catalog/createInstance) - Create an Instance 36 | - [/catalog/instances](https://developer.sas.com/rest-apis/catalog/getInstances) - Get a list of Instances using a filter 37 | - [/catalog/instances](https://developer.sas.com/rest-apis/catalog/createOrUpdateInstanceArchive) - Create or update objects from an archive 38 | - [/catalog/instances](https://developer.sas.com/rest-apis/catalog/queryArchive) - Get an archive of objects based on a view 39 | - [/catalog/instances](https://developer.sas.com/rest-apis/catalog/deleteInstance) - Delete an Instance by its Instance ID 40 | - [/catalog/definitions](https://developer.sas.com/rest-apis/catalog/deleteTypeDefinition) - Delete a Type Definition by its ID 41 | 42 | ## Supported Versions 43 | 44 | - Viya 4 45 | - 2023.10 46 | 47 | ## Additional Resources 48 | -------------------------------------------------------------------------------- /DataManagement/catalog/postman/catalog/download-upload-to-cas-profiled-metrics-data/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Download or Upload Metadata 3 | 4 | You can perform operations to download metadata to a file or upload metadata to a library in the CAS server. You can handle metadata as in-memory tables in a library. The metadata can be of various levels of detail, such as data dictionaries, detailed metrics, or a combination of data dictionaries and additional profile metrics. 5 | 6 | ## Overview 7 | 8 | This collection utilizes the Catalog API to either download metadata for datasets or upload metadata to a library in a CAS server. 9 | 10 | You can specify the type of metadata to download or upload to the CAS server through the `level` parameter. Below are the three different values for the `level` option: 11 | 12 | 1. `datadictionary`: This option provides basic metadata about the table and the columns such as tablesize, row count, column count, and others. 13 | 14 | 2. `detailedMetrics`: This option provides metadata about the columns with additional metrics such as dataType, columnOrdinalPosition, and others. 15 | 16 | 3. `dataDictionaryAndProfile`: This option provides extensive metadata combining both data dictionary and profile metrics. The metadata includes computed metrics such as sentiment analysis, useful keywords, privacy, and others. 17 | 18 | The `delimiter` parameter allows you to specify the type of delimiter used to separate fields in a row when downloading metadata. With the `prefix` parameter, you can provide a prefix. The `dateTimeStampSuffix` boolean parameter determines whether a date timestamp suffix should be added to the downloaded file name. The `prefix` and `dateTimeStampSuffix` parameters influence the downloadable file name. They can be seen in the Content-Disposition response header. 19 | 20 | To upload table metadata to CAS, you need to provide the `serverName` (the name of the CAS Server) and `casLibName` (the name of the accessible CAS library for data upload). Users can also specify `level`, `prefix`, and `dateTimeStampSuffix` parameters. 21 | 22 | In this Postman collection: 23 | 24 | - Steps 1 through 4 execute a discovery agent to generate metrics for datasets stored in the Samples CAS Library. 25 | - Steps 5 through 9 offer examples of downloading metadata using different values for `level`, `prefix`, and `dateTimeStampSuffix` parameters. 26 | - Steps 10 through 12 demonstrate how to upload metadata to a "Public" library in CAS that uses various parameters like `level`, `prefix`, and `dateTimeStampSuffix`. 27 | 28 | ## Prerequisites 29 | 30 | ### Variables 31 | The Postman collection comes with variables you must assign either at the collection or the environment level. Assign values to the following variables prior to running the collection: 32 | - `sasserver` - the location of the SAS Viya server; for example: https://myserver.sas.com 33 | - `access_token` 34 | Other variables are assigned programmatically during the REST calls using code in the Postman Tests tab. 35 | 36 | ## Usage 37 | 1. Download the JSON collection and the sasserver.env. Then import the files into Postman. 38 | 2. Select sasserver.env as the environment and edit your environment variables to match those contained in the collection requests (sasserver and access_token). 39 | 3. Be sure to authenticate to your server before testing the endpoints. 40 | 4. You can run one request at a time or run the collection. The first step is to run a Discovery Agent to generate the data. Then you can run requests to download the metadata. 41 | 42 | ## Endpoints Used 43 | Create and execute Agent 44 | - [/catalog/bots](https://developer.sas.com/rest-apis/catalog/createAgent) - Create an Agent 45 | - [/catalog/bots/{agentId}/state](https://developer.sas.com/rest-apis/catalog/updateAgentRunState) - Update an Agent's run state 46 | - [/catalog/bots/{agentId}/state](https://developer.sas.com/rest-apis/catalog/getAgentRunState) - Get an Agent's execution status 47 | - [/catalog/instances/](https://developer.sas.com/rest-apis/catalog/downloadInstances) - Download instances 48 | - [/catalog/instances/](https://developer.sas.com/rest-apis/catalog/uploadInstances) - Upload instances metadata to CAS 49 | 50 | ## Supported Versions 51 | - Viya 4 52 | - 2023.09 53 | ## Additional Resources 54 | -------------------------------------------------------------------------------- /DataManagement/catalog/postman/catalog/overview.md: -------------------------------------------------------------------------------- 1 | 2 | #### Context 3 | 4 | This API is used to define and manage [metadata](#Metadata). 5 | 6 | ##### Background and Overview 7 | 8 | This API provides the basic interface to discover, find, and elaborate on metadata within the environment. Metadata in the context of this API refers to descriptive information about any currently defined asset. 9 | 10 | ##### Use Cases 11 | - retrieve metadata for assets 12 | - define metadata for information consumed, used, or related to assets 13 | - integrate metadata with third-party systems 14 | - find metadata for assets 15 | - build and manage 'bots' which populate the catalog with table metadata 16 | 17 | #### Concepts 18 | As part of managing metadata, catalog first requires information about the kind of metadata that will be introduced. Consumers describe the information they wish to manage by providing one or more *type definitions*. Metadata content is added using the Catalog API as *instances* that specify a type definition. The type definition is used to validate and interpret the data in the instance. 19 | 20 | These concepts are described in more detail below. 21 | 22 | ##### Type Definitions 23 | Type definitions define the kind of entities and relationships (along with any attributes) that are allowed for an asset. Type definitions are analogous to the concept of a *class* in an object oriented system; or that of a *DDL* in a relational model. 24 | 25 | Type definition names must be unique. 26 | 27 | There are four kinds of type definitions: 28 | 29 | ###### Attribute Type Definitions 30 | Attribute Type Definitions describe properties for the remaining kinds of type definitions. For example, an Entity Type Definition that describes an individual may reference attribute type definitions for contact information such as a phone number or mailing address. 31 | 32 | ####### Enumerations 33 | Attribute definitions can describe a list of allowed values by specifying `ENUM` as the attributeKind field of the Attribute Type Definition. Enumerations have a list of `elementDefinitions` that describe the allowed values. 34 | 35 | ####### Attribute Definitions 36 | Attribute type definitions are referenced in type definitions as the `type` field in their `attributes` list; these model elements are known as `attribute definitions`. 37 | 38 | A `typeCriteria` object can be included within an attribute definition. This inclusion enables the expression of constraints on the content that are allowed within the attribute's value at run time. 39 | - minLength: the shortest acceptable value; only valid for string types 40 | - maxLength: the longest acceptable value; only valid for string types 41 | - minimum: the smallest acceptable value; only valid for numeric types 42 | - maximum: the largest acceptable value; only valid for numeric types 43 | - minItems: the smallest number of items allowed in the collection; only valid for collections 44 | - maxItems: the largest number of items allowed in the collection; only valid for collections 45 | - required: indicates that the attribute value must be specified 46 | 47 | For attribute definitions of type `collection`, the type criteria must include an `items` element that contains a list of attribute definitions that constitute the elements in the collection. Note that specifying additional collection valued attributes in this 'items' list is not supported; the model does not support collections of collections within a single attribute. 48 | 49 | ###### Entity Type Definitions 50 | Entity Type Definitions describe the nouns in the system. Some examples are data sets or reports. 51 | 52 | Entity type definitions can have a *base type* that simplifies modeling by incorporating properties from the base type into the set of properties of the entity type definition. This acts like inheritance of fields in an object-oriented system. 53 | 54 | ###### Classification Type Definitions 55 | Classification Type Definitions describe a kind of annotation that can be related to Instances. For instance, a Security classification can be attached to a dataset to describe the sensitivity of the dataset. 56 | 57 | Like Entity type definitions, classification type definitions can have a base type that incorporates properties from the base type into the set of properties of the classification type definition. 58 | 59 | ####### Classification Hierarchies 60 | Classification instances support arrangement in a hierarchy. This structure is useful, for example, when instances represent part of a taxonomy. It is important to remember, however, that this hierarchy is unrelated to the derivation hierarchy. Instances in a hierarchy of a classification need not adhere to the same hierarchy used to model the classification instances. 61 | 62 | ###### Relationship Type Definitions 63 | Relationship Type Definitions describe the kinds of connections that can occur between *entity* and *classification* instances. 64 | 65 | Relationship type definitions describe directed relationships between entity and classification instances of specific types. Entities and classifications can appear on either endpoint of a relationship type definition in any combination (e.g., entity to entity, entity to classification, classification to classification, and classification to entity). For instance, relationship type definitions may describe: 66 | - a hierarchical file system with a relationship between parent and child folder entities 67 | - a taxonomy built from classification instances 68 | - a security classification between a dataset entity and a 'Sensitive' classification instance 69 | 70 | Both entity and classification type definitions support the concept of a base type. Base types specified in the relationship type definition allow any type derived from that base to participate in the relationship. 71 | 72 | ##### Instances 73 | Instances are used to capture the metadata of objects in the system. If we extend our object-oriented analogy from type definitions, classes are to type definitions as objects are to instances. For example, a dataSet type definition describes the properties and relationships for any dataset, but a dataset instance captures metadata for a specific dataset. 74 | 75 | There are three kinds of instances: 76 | 77 | ###### Entities 78 | Entities are records of specific objects that capture the metadata of that object. For instance, a dataset instance may specify a name of 'BASEBALL.sashdat' with row and column counts derived from a table in a particular library within the Viya system. 79 | 80 | ####### Uniqueness Constraints 81 | Unlike type definitions, entity instance names do not have to be unique. 82 | 83 | Entities have a `resourceId` field that is used to refer to the URI for the original object. If the type definition metaCategory is set to `PRIMARY`, the resourceId fields must be unique among instances of that type. 84 | 85 | ###### Classifications 86 | Classifications serve as annotations that are typically referenced many times. While entities tend to refer to specific resources, classifications are used to add additional dimensions to the information captured by an entity. For instance, many datasets may be associated with a 'Sensitive' security classification. 87 | 88 | ####### Uniqueness Constraints 89 | Classification instances can be arranged within a hierarchy by specifying a `parentID`. Names must be unique across classification instances with the same parent. If no parent is specified, names must be unique across all the classification instances without a parent. 90 | 91 | ###### Relationships 92 | Relationships serve to identify connections between entities and classifications. For instance, our BASEBALL.sashdat table entity may have a relationship to the SASHELP library entity. The type of the relationship conveys the semantics of the connection (along with any attributes attached to the relationship). 93 | 94 | ##### Search 95 | One of the primary use cases for the catalog service is discovering assets that are available for use. The catalog supports the traditional filter semantics that are common across SAS APIs; but these tend to require very precise knowledge about the assets of interest. 96 | 97 | To fully support the discovery use case, the Catalog API also supports information retrieval techniques in the form of a search engine that allows retrieval of information using a query syntax that returns results based on relevance to one or more search criteria. 98 | 99 | To enable search for different kinds of SAS assets, a *search index definition* for some assets has been added to the Catalog API. The index definition describes which entity and relationship definitions should be included in the search index, along with the properties to index. 100 | 101 | When updates to the catalog are made (such as creating new instances, updating existing instances, or deleting instances), indices that reference the type of the instance (or instances) being manipulated are automatically updated. 102 | 103 | ##### Tags 104 | Tags provide a way to attach user-provided labels to entities. 105 | 106 | When tags are incorporated into search index definitions, users can use tags like a virtual bookmark and rapidly recall or share entities that have been tagged. 107 | 108 | ##### Views 109 | When entities, classifications and relationships are combined, the result is a directed graph that captures the structure of information within the Catalog API. It is frequently useful to be able to query the graph in a way that returns the elements of the graph all once, rather than iteratively asking the Catalog API for more information. Selecting a set of related instances is performed thru a *View*, which conceptually serves as a saved query. 110 | 111 | Views are expressed using a Graph query syntax: 112 | - () describes an entity 113 | - -[]-, -[]->, <-[]- describes relationships 114 | - <> describes a classification. 115 | 116 | Each of these can be given a named projection, that allows matching objects to be referenced later in the query. 117 | 118 | Information is retrieved by matching graphs against the pattern described by the query and returning the parts that are interesting. For example, matching everything in the catalog uses the query 119 | 120 | match (x) return x 121 | 122 | Property constraints can further reduce the set of results. For example, to return an entity with a specific ID use: 123 | 124 | match(x {id:7462f4c3-f225-42cf-bc3d-0fdfcf09b190}) 125 | return x 126 | 127 | Each of the elements can be further constrained with type information. For example, to return all of the `dataSet` instances use: 128 | 129 | match(x:dataSet) return x 130 | 131 | or to return the dataSet and its dataFields use: 132 | 133 | match(x:dataSet)-[]->(y:dataField) return x,y 134 | 135 | Type constraints can specify lists of types: 136 | 137 | (y:sasColumn|casColumn)
    // either one 138 | (x)-[r:eq(role, "Associated)]->(y)
    // Only association rels 139 | (x)-[r:in(role,"Associated","Composition")]->(y) // either role 140 | 141 | Match clauses can reference projections that have been previously defined. For instance, to get a dataset, its columns, and the semantic classifications attached to the columns: 142 | 143 | match (t:dataSet {id:"..."})-[r:dataSetDataFields]-(c:dataField) 144 | match (c)-[sc:semanticClassifications]-> 145 | return t,r,c,scr,sc 146 | 147 | Relationships can include a path length expression: 148 | 149 | -[r*..2]-> // Up to two relationships away 150 | -[r*2..4]-> // between 2 and 4 relationships away 151 | 152 | where the lower and upper bounds are expressed in the range following the asterisk. This approach is useful when views have to traverse multiple relationships. 153 | 154 | ##### Support for history 155 | Entity instances can be configured to maintain old revisions according to a policy that is configured on either the entity or the entity's type definition. Before any changes are applied to the instance, a copy of the current state is written to the catalog service. 156 | 157 | Entity instances and type definitions allow you to specify: 158 | - a policy that controls how history records are retained 159 | - a parameter that governs the policy 160 | - a view that describes what content is maintained as part of the history 161 | 162 | For instance, a policy of `depth` and a parameter of `10` means that at most 10 different revisions will be maintained within the catalog service. The view is used to determine which entities, relationships, and classifications are to be included within the history record. 163 | 164 | The policy `none` indicates that no history is to be kept. 165 | 166 | If no history configuration is set for an instance, the behavior is determined by the type definition. This also allows the configuration to be set on a base type of the type definition, which is then inherited by types derived from the base type. 167 | 168 | ##### Agents 169 | Agents are used to introduce content into the catalog. 170 | 171 | The Catalog API enables constructing, running, and monitoring agents. Agents write their results back to the catalog service using the same concepts and interfaces that are documented here. -------------------------------------------------------------------------------- /DataManagement/catalog/postman/catalog/sasserver.postman_environment.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "d172c802-b052-4988-91e2-a7ff836b0bd1", 3 | "name": "sasserver", 4 | "values": [ 5 | { 6 | "key": "sasserver", 7 | "value": "", 8 | "type": "default", 9 | "enabled": true 10 | }, 11 | { 12 | "key": "username", 13 | "value": "", 14 | "type": "default", 15 | "enabled": true 16 | }, 17 | { 18 | "key": "password", 19 | "value": "", 20 | "type": "default", 21 | "enabled": true 22 | }, 23 | { 24 | "key": "access_token", 25 | "value": "", 26 | "type": "any", 27 | "enabled": true 28 | }, 29 | { 30 | "key": "bearerToken", 31 | "value": "", 32 | "type": "any", 33 | "enabled": true 34 | }, 35 | { 36 | "key": "refresh_token", 37 | "value": "", 38 | "type": "default", 39 | "enabled": true 40 | }, 41 | { 42 | "key": "client_id", 43 | "value": "api.client", 44 | "type": "default", 45 | "enabled": true 46 | }, 47 | { 48 | "key": "client_secret", 49 | "value": "api.secret", 50 | "type": "default", 51 | "enabled": true 52 | }, 53 | { 54 | "key": "client_token", 55 | "value": "", 56 | "type": "default", 57 | "enabled": true 58 | }, 59 | { 60 | "key": "authcodeurl", 61 | "value": "", 62 | "type": "default", 63 | "enabled": true 64 | }, 65 | { 66 | "key": "authorization_code", 67 | "value": "", 68 | "type": "default", 69 | "enabled": true 70 | } 71 | ], 72 | "_postman_variable_scope": "environment", 73 | "_postman_exported_at": "2023-08-21T17:36:36.766Z", 74 | "_postman_exported_using": "Postman/10.17.2" 75 | } 76 | -------------------------------------------------------------------------------- /DataManagement/catalog/postman/catalog/use-search-to-lookup-resources/README.md: -------------------------------------------------------------------------------- 1 | # Search and Find Assets 2 | 3 | ## Overview 4 | 5 | This collection leverages the Catalog API to support search capabilities. 6 | 7 | - Using search with facets to find data sets with a free text query. 8 | 9 | - Using suggestions to retrieve suggested values for searchers on a given facet. 10 | 11 | - Specifying an index to limit the type of resources returned by the request. 12 | 13 | - Find data sets that have been updated from a specified time period. 14 | 15 | - Find resources based on the provided indices and keyword. 16 | 17 | ## Prerequisites 18 | 19 | ### Variables 20 | 21 | The Postman collection comes with variables that must be assigned either at the collection or the environment level. Assign values to the following variables prior to running the collection: 22 | 23 | - `sasserver` - the location of the SAS Viya server; for example: https://myserver.sas.com 24 | - `access_token` 25 | Other variables are assigned programmatically during the REST calls using code in the Postman Tests tab. 26 | 27 | ## Usage 28 | 29 | 1. Download the JSON collection and the sasserver.env. Then import the files into Postman. 30 | 2. Select sasserver.env as the environment and edit your environment variables to match those contained in the collection requests (sasserver and access_token). 31 | 3. Be sure to authenticate to your server before testing the endpoints. 32 | 33 | ## Endpoints Used 34 | 35 | - [/catalog/search](https://developer.sas.com/rest-apis/catalog/getSearchResults) - Get Search Results 36 | - [/catalog/search/facets](https://developer.sas.com/rest-apis/catalog/getSearchFacets) - Get Search Facets 37 | - [/catalog/search/suggestions](https://developer.sas.com/rest-apis/catalog/getSearchSuggestions) - Retrieve suggested values for searches on a given field 38 | 39 | ## Supported Versions 40 | 41 | - Viya 4 42 | - 2023.10 43 | 44 | ## Additional Resources 45 | -------------------------------------------------------------------------------- /DataManagement/catalog/python/catalog/create-and-run-discovery-agent/README.md: -------------------------------------------------------------------------------- 1 | # Create and Run a Discovery Agent 2 | ## Overview 3 | This program leverages the Catalog API to create and run a Discovery Agent. 4 | #### Variables to assign: 5 | - sasserver - the SAS Viya server URL 6 | - username 7 | - password 8 | ### Packages and Python Version 9 | - python 3 10 | - requests, json 11 | ## Usage 12 | 1. Download the Python program or the Jupyter Notebook file. 13 | 2. Edit your variables to match your environment. 14 | 3. Proceed to run the program or Notebook commands. 15 | ## Endpoints Used 16 | - [/catalog/bots](https://developer.sas.com/rest-apis/catalog/createAgent) - Create an Agent 17 | - [/catalog/bots/{agentId}/state](https://developer.sas.com/rest-apis/catalog/updateAgentRunState) - Update Agents run state 18 | - [/catalog/bots/{agentId}/state](https://developer.sas.com/rest-apis/catalog/getAgentRunState) - Get an Agent's execution state 19 | - [/catalog/bots/{agentId}](https://developer.sas.com/rest-apis/catalog/getAgent) - Get an Agent by its ID 20 | - [catalog/bots/{agentId}](https://developer.sas.com/rest-apis/catalog/deleteAgent) - Delete an Agent by its ID 21 | - [/catalog/bots](https://developer.sas.com/rest-apis/catalog/getAgents) -Get a list of Agents 22 | - [/catalog/bots](https://developer.sas.com/rest-apis/catalog/updateAgent) - Update an Agent by its ID 23 | 24 | ## Supported Versions 25 | 26 | - Viya 4 27 | - 2023.10 28 | 29 | ## Additional Resources 30 | -------------------------------------------------------------------------------- /DataManagement/catalog/python/catalog/create-and-run-discovery-agent/create-and-run-discovery-agent.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "c21bd38a", 6 | "metadata": {}, 7 | "source": [ 8 | "# Create and Run a Discovery Agent\n", 9 | "\n", 10 | "A Discovery Agent ingests, analyzes, and stores metadata about the data related assets in a data connection. Agents are especially useful when metadata is not ingested in some other way, through events or via the catalog API. The catalog service enables constructing, running, and monitoring Agents as independent, event driven processes. Agents store the metadata they collect into the catalog. " 11 | ] 12 | }, 13 | { 14 | "cell_type": "markdown", 15 | "id": "1faef169", 16 | "metadata": {}, 17 | "source": [ 18 | "## Imports and Global Variables" 19 | ] 20 | }, 21 | { 22 | "cell_type": "markdown", 23 | "id": "5aa5fe6d", 24 | "metadata": {}, 25 | "source": [ 26 | "Run this cell before any of the others as it imports packages and sets variables that will be used throughout the notebook" 27 | ] 28 | }, 29 | { 30 | "cell_type": "code", 31 | "execution_count": null, 32 | "id": "ac9717dc", 33 | "metadata": {}, 34 | "outputs": [], 35 | "source": [ 36 | "import requests\n", 37 | "import json\n", 38 | "sasserver = \"https://your_server\"\n", 39 | "print (sasserver)" 40 | ] 41 | }, 42 | { 43 | "cell_type": "markdown", 44 | "id": "d5a5b14b", 45 | "metadata": {}, 46 | "source": [ 47 | "## Get Access token" 48 | ] 49 | }, 50 | { 51 | "cell_type": "code", 52 | "execution_count": null, 53 | "id": "f515fc00", 54 | "metadata": { 55 | "scrolled": false 56 | }, 57 | "outputs": [], 58 | "source": [ 59 | "url = sasserver + \"/SASLogon/oauth/token#password\"\n", 60 | "\n", 61 | "payload={\n", 62 | " 'grant_type': 'password',\n", 63 | " 'username': 'your_username',\n", 64 | " 'password': 'your_password'\n", 65 | "}\n", 66 | "files=[\n", 67 | "\n", 68 | "]\n", 69 | "headers = {\n", 70 | " 'Authorization': 'Basic c2FzLmVjOg==',\n", 71 | "}\n", 72 | "\n", 73 | "response = requests.request(\"POST\", url, headers=headers, data=payload, files=files, verify=False)\n", 74 | "print(response)\n", 75 | "response = response.json()\n", 76 | "print(response)\n", 77 | "access_token = response[\"access_token\"]" 78 | ] 79 | }, 80 | { 81 | "cell_type": "markdown", 82 | "id": "b4b0331e", 83 | "metadata": {}, 84 | "source": [ 85 | "## Create Discovery Agent" 86 | ] 87 | }, 88 | { 89 | "cell_type": "code", 90 | "execution_count": null, 91 | "id": "c5071148", 92 | "metadata": {}, 93 | "outputs": [], 94 | "source": [ 95 | "url = sasserver + \"/catalog/bots\"\n", 96 | "\n", 97 | "payload = json.dumps({\n", 98 | " \"provider\": \"TABLE-BOT\",\n", 99 | " \"name\": \"Samples Discovery Agent\",\n", 100 | " \"description\": \"Ingest, analyze, and store metadata from Samples caslib\",\n", 101 | " \"parameters\": {\n", 102 | " \"datasourceURI\": \"/dataSources/providers/cas/sources/cas-shared-default~fs~Samples\",\n", 103 | " \"region\": \"US NC\"\n", 104 | " }\n", 105 | "})\n", 106 | "headers = {\n", 107 | " 'Content-Type': 'application/json',\n", 108 | " 'Authorization': 'Bearer ' + access_token\n", 109 | "}\n", 110 | "\n", 111 | "response = requests.request(\"POST\", url, headers=headers, data=payload, verify=False)\n", 112 | "print(response)\n", 113 | "response = response.json()\n", 114 | "print(response)\n", 115 | "bot_id = response[\"id\"]\n", 116 | "\n", 117 | "\n" 118 | ] 119 | }, 120 | { 121 | "cell_type": "markdown", 122 | "id": "54dc4992", 123 | "metadata": {}, 124 | "source": [ 125 | "## Run Discovery Agent" 126 | ] 127 | }, 128 | { 129 | "cell_type": "code", 130 | "execution_count": null, 131 | "id": "93a0ca7d", 132 | "metadata": {}, 133 | "outputs": [], 134 | "source": [ 135 | "url = sasserver + \"/catalog/bots/\" + bot_id + \"/state?value=running\"\n", 136 | "\n", 137 | "payload = {}\n", 138 | "headers = {\n", 139 | " 'Accept': 'text/plain',\n", 140 | " 'Authorization': 'Bearer ' + access_token\n", 141 | "}\n", 142 | "\n", 143 | "response = requests.request(\"PUT\", url, headers=headers, data=payload, verify=False)\n", 144 | "print(response)\n", 145 | "print(response.text)\n" 146 | ] 147 | }, 148 | { 149 | "cell_type": "markdown", 150 | "id": "d218f0fa", 151 | "metadata": {}, 152 | "source": [ 153 | "## Get Discovery Agent state" 154 | ] 155 | }, 156 | { 157 | "cell_type": "markdown", 158 | "id": "b3cbd5e2", 159 | "metadata": {}, 160 | "source": [ 161 | "Repeat this code snippet until the response is idle." 162 | ] 163 | }, 164 | { 165 | "cell_type": "code", 166 | "execution_count": null, 167 | "id": "d7aeeb68", 168 | "metadata": {}, 169 | "outputs": [], 170 | "source": [ 171 | "url = sasserver + \"/catalog/bots/\" + bot_id + \"/state\"\n", 172 | "\n", 173 | "payload = {}\n", 174 | "headers = {\n", 175 | " 'Accept': 'text/plain',\n", 176 | " 'Authorization': 'Bearer ' + access_token\n", 177 | "}\n", 178 | "\n", 179 | "response = requests.request(\"GET\", url, headers=headers, data=payload, verify=False)\n", 180 | "print(response)\n", 181 | "print(response.text)\n" 182 | ] 183 | }, 184 | { 185 | "cell_type": "markdown", 186 | "id": "73d67b73", 187 | "metadata": {}, 188 | "source": [ 189 | "## Post /instances#archive" 190 | ] 191 | }, 192 | { 193 | "cell_type": "markdown", 194 | "id": "19fa0595", 195 | "metadata": {}, 196 | "source": [ 197 | "This request will return instances with metadata from the Samples Library that was analyzed by the Discovery Agent." 198 | ] 199 | }, 200 | { 201 | "cell_type": "code", 202 | "execution_count": null, 203 | "id": "2157e064", 204 | "metadata": {}, 205 | "outputs": [], 206 | "source": [ 207 | "url = sasserver + \"/catalog/instances\"\n", 208 | "\n", 209 | "payload = json.dumps({\n", 210 | " \"query\": \"match (l:casLibrary {name:\\\"Samples\\\"})-[r:dataStoreDataSets]->(t:casTable)-[rc:dataSetDataFields]->(c:casColumn) return t,rc,c\"\n", 211 | "})\n", 212 | "headers = {\n", 213 | " 'Content-Type': 'application/vnd.sas.metadata.instance.query+json',\n", 214 | " 'Accept': 'application/vnd.sas.metadata.instance.archive+json',\n", 215 | " 'Authorization': 'Bearer ' + access_token\n", 216 | "}\n", 217 | "response = requests.request(\"POST\", url, headers=headers, data=payload, verify=False)\n", 218 | "\n", 219 | "print(response.text)\n" 220 | ] 221 | }, 222 | { 223 | "cell_type": "markdown", 224 | "id": "b994cd01", 225 | "metadata": {}, 226 | "source": [ 227 | "# Optional Discovery Agent Requests" 228 | ] 229 | }, 230 | { 231 | "cell_type": "markdown", 232 | "id": "494aead6", 233 | "metadata": {}, 234 | "source": [ 235 | "## Get Discovery Agent History" 236 | ] 237 | }, 238 | { 239 | "cell_type": "markdown", 240 | "id": "277944cc", 241 | "metadata": {}, 242 | "source": [ 243 | "This request returns the Agents execution history." 244 | ] 245 | }, 246 | { 247 | "cell_type": "code", 248 | "execution_count": null, 249 | "id": "4bf523e7", 250 | "metadata": {}, 251 | "outputs": [], 252 | "source": [ 253 | "url = sasserver + \"/catalog/bots/\" + bot_id + \"/history\"\n", 254 | "\n", 255 | "payload = {}\n", 256 | "headers = {\n", 257 | " 'Accept': 'application/vnd.sas.collection+json',\n", 258 | " 'Accept-Item': 'application/vnd.sas.metadata.bot.history+json',\n", 259 | " 'Authorization': 'Bearer ' + access_token\n", 260 | "}\n", 261 | "\n", 262 | "response = requests.request(\"GET\", url, headers=headers, data=payload, verify=False)\n", 263 | "\n", 264 | "print(response.text)\n" 265 | ] 266 | }, 267 | { 268 | "cell_type": "markdown", 269 | "id": "8a370e59", 270 | "metadata": {}, 271 | "source": [ 272 | "## Get Discovery Agent" 273 | ] 274 | }, 275 | { 276 | "cell_type": "code", 277 | "execution_count": null, 278 | "id": "ccf48b26", 279 | "metadata": {}, 280 | "outputs": [], 281 | "source": [ 282 | "url = sasserver + \"/catalog/bots/\" + bot_id\n", 283 | "\n", 284 | "payload = {}\n", 285 | "headers = {\n", 286 | " 'Accept': 'application/vnd.sas.metadata.scheduled.bot+json',\n", 287 | " 'Authorization': 'Bearer ' + access_token\n", 288 | "}\n", 289 | "\n", 290 | "response = requests.request(\"GET\", url, headers=headers, data=payload, verify=False)\n", 291 | "print(response)\n", 292 | "e_tag = response.headers[\"ETag\"]\n", 293 | "print ('ETag='+ e_tag)\n", 294 | "response = response.json()\n", 295 | "print(response) \n" 296 | ] 297 | }, 298 | { 299 | "cell_type": "markdown", 300 | "id": "c2b0d4b9", 301 | "metadata": {}, 302 | "source": [ 303 | "## Update Discovery Agent" 304 | ] 305 | }, 306 | { 307 | "cell_type": "markdown", 308 | "id": "51d4c71f", 309 | "metadata": {}, 310 | "source": [ 311 | "This code snippet can be used to update fields or the jobParameters in the Discovery Agent Body." 312 | ] 313 | }, 314 | { 315 | "cell_type": "code", 316 | "execution_count": null, 317 | "id": "01a9c5ca", 318 | "metadata": {}, 319 | "outputs": [], 320 | "source": [ 321 | "url = sasserver + \"/catalog/bots/\" + bot_id\n", 322 | "\n", 323 | "payload = json.dumps({\n", 324 | " \"provider\": \"TABLE-BOT\",\n", 325 | " \"name\": \"Samples Discovery Agent\",\n", 326 | " \"id\": bot_id,\n", 327 | " \"description\": \"Ingest, analyze, and store metadata from Samples caslib\",\n", 328 | " \"parameters\": {\n", 329 | " \"datasourceURI\": \"/dataSources/providers/cas/sources/cas-shared-default~fs~Samples\",\n", 330 | " \"region\": \"US NC\"\n", 331 | " },\n", 332 | " \"jobParameters\": {\n", 333 | " \"getNLPSemanticID\": \"0\",\n", 334 | " \"identifyLanguage\": \"0\",\n", 335 | " \"mineForKeywords\": \"0\"\n", 336 | " }\n", 337 | "})\n", 338 | "headers = {\n", 339 | " 'If-Match': e_tag,\n", 340 | " 'Accept': 'application/vnd.sas.metadata.bot+json',\n", 341 | " 'Content-Type': 'application/json',\n", 342 | " 'Authorization': 'Bearer ' + access_token \n", 343 | "}\n", 344 | "\n", 345 | "response = requests.request(\"PUT\", url, headers=headers, data=payload, verify=False)\n", 346 | "\n", 347 | "print(response.text)\n" 348 | ] 349 | }, 350 | { 351 | "cell_type": "markdown", 352 | "id": "2a4dc3e7", 353 | "metadata": {}, 354 | "source": [ 355 | "## Delete Discovery Agent" 356 | ] 357 | }, 358 | { 359 | "cell_type": "code", 360 | "execution_count": null, 361 | "id": "0bf70f41", 362 | "metadata": {}, 363 | "outputs": [], 364 | "source": [ 365 | "url = sasserver + \"/catalog/bots/\" + bot_id\n", 366 | "payload = {}\n", 367 | "headers = {\n", 368 | " 'Authorization': 'Bearer ' + access_token\n", 369 | "}\n", 370 | "\n", 371 | "response = requests.request(\"DELETE\", url, headers=headers, data=payload, verify=False)\n", 372 | "print(response)\n" 373 | ] 374 | }, 375 | { 376 | "cell_type": "code", 377 | "execution_count": null, 378 | "id": "a3e7caef", 379 | "metadata": {}, 380 | "outputs": [], 381 | "source": [] 382 | } 383 | ], 384 | "metadata": { 385 | "kernelspec": { 386 | "display_name": "Python 3 (ipykernel)", 387 | "language": "python", 388 | "name": "python3" 389 | }, 390 | "language_info": { 391 | "codemirror_mode": { 392 | "name": "ipython", 393 | "version": 3 394 | }, 395 | "file_extension": ".py", 396 | "mimetype": "text/x-python", 397 | "name": "python", 398 | "nbconvert_exporter": "python", 399 | "pygments_lexer": "ipython3", 400 | "version": "3.10.9" 401 | } 402 | }, 403 | "nbformat": 4, 404 | "nbformat_minor": 5 405 | } 406 | -------------------------------------------------------------------------------- /DataManagement/catalog/python/catalog/create-and-search-on-tags/README.md: -------------------------------------------------------------------------------- 1 | # Create and Search on Tags 2 | ## Overview 3 | This python notebook leverages the Catalog API to create and search tags. 4 | - In this use case, three instances are created and named Groceries, Rent and Going Out. Each represents a log of the different expenses a person might use to track spending. 5 | - A tag is created named Expenses. The tag is applied to the instances. 6 | - The tag is searched using the `/search` endpoint. 7 | - Get the tag by `tag_name` and `tag_id`. 8 | - Update the tag name. 9 | - Remove an instance from a tag. 10 | - Delete a tag. 11 | - Use the `/deletions` endpoint to delete the instances. 12 | 13 | #### Variables to assign: 14 | - sasserver - the SAS Viya server URL 15 | - username 16 | - password 17 | ### Python Version and Packages used 18 | - python 3.10+ 19 | - requests, json 20 | ## Usage 21 | 1. Download the Python program or the Jupyter Notebook file. 22 | 2. Edit your variables to match your environment. 23 | 3. Proceed to run the program or Notebook commands. 24 | ## Endpoints Used 25 | - [/catalog/instances](https://developer.sas.com/rest-apis/catalog/createInstance) - Create instances 26 | - [/catalog/tags](https://developer.sas.com/rest-apis/catalog#tags) - Create/Get/Update a tag 27 | - [/catalog/search](https://developer.sas.com/rest-apis/catalog#search) - Search 28 | - [/catalog/deletions](https://developer.sas.com/rest-apis/catalog#deletions) - Deletions 29 | 30 | ## Supported Versions 31 | 32 | - Viya 4 33 | - 2023.10 34 | 35 | ## Additional Resources 36 | -------------------------------------------------------------------------------- /DataManagement/catalog/python/catalog/create-and-use-asset/README.md: -------------------------------------------------------------------------------- 1 | # Create and Use Asset 2 | 3 | ## Overview 4 | 5 | This notebook leverages the Catalog API to create and use an asset. 6 | 7 | Before creating an asset, a schema must first be defined. Afterwards, assets can be created according to this defined schema. 8 | 9 | In the Catalog API, a schema for an asset is defined using a type definition. For this use case, we create a type definition for a new asset type named *publicDataSet*. 10 | 11 | With the schema defined, assets and relationships can be created using instances endpoints. In the Catalog AP, an instance of an asset type is known as an entity. The scenario shows both how to create a single asset and how to use an archive to create or update assets and relationships. The relationship in this scenario is adding a contact to an asset. 12 | 13 | The assets are queried using both a view and a filter on the instances endpoint. 14 | 15 | ## Prerequisites 16 | 17 | #### Variables to assign 18 | 19 | - sasserver - the SAS Viya server URL 20 | - username 21 | - password 22 | 23 | ### Packages and Python Version 24 | - python 3 25 | - requests, json, format_date_time, datetime, mktime 26 | 27 | ## Usage 28 | 1. Download the Python program or the Jupyter Notebook file. 29 | 2. Edit your variables to match your environment. 30 | 3. Proceed to run the program or Notebook commands. 31 | 32 | ## Endpoints Used 33 | 34 | - [/catalog/definitions](https://developer.sas.com/rest-apis/catalog/createTypeDefinition) - Create Type Definition 35 | - [/catalog/instances](https://developer.sas.com/rest-apis/catalog/createInstance) - Create an Instance 36 | - [/catalog/instances](https://developer.sas.com/rest-apis/catalog/getInstances) - Get a list of Instances using a filter 37 | - [/catalog/instances](https://developer.sas.com/rest-apis/catalog/createOrUpdateInstanceArchive) - Create or update objects from an archive 38 | - [/catalog/instances](https://developer.sas.com/rest-apis/catalog/queryArchive) - Get an archive of objects based on a view 39 | - [/catalog/instances](https://developer.sas.com/rest-apis/catalog/deleteInstance) - Delete an Instance by its Instance ID 40 | - [/catalog/definitions](https://developer.sas.com/rest-apis/catalog/deleteTypeDefinition) - Delete a Type Definition by its ID 41 | 42 | ## Supported Versions 43 | 44 | - Viya 4 45 | - 2023.10 46 | 47 | ## Additional Resources 48 | -------------------------------------------------------------------------------- /DataManagement/catalog/python/catalog/download-upload-to-cas-profiled-metrics-data/README.md: -------------------------------------------------------------------------------- 1 | # Download or Upload Metadata 2 | 3 | You can perform operations to download metadata to a file or upload metadata to a library in the CAS server. You can handle metadata as in-memory tables in a library. The metadata can be of various levels of detail, such as data dictionaries, detailed metrics, or a combination of data dictionaries and additional profile metrics. 4 | 5 | ## Overview 6 | 7 | This collection utilizes the Catalog API to either download metadata for datasets or upload metadata to a library in a CAS server. 8 | 9 | You can specify the type of metadata to download or upload to the CAS server through the `level` parameter. Below are the three different values for the `level` option: 10 | 11 | 1. `datadictionary`: This option provides basic metadata about the table and the columns such as tablesize,row count, column count, and others. 12 | 13 | 2. `detailedMetrics`: This option provides metadata about the columns with additional metrics such as dataType,columnOrdinalPosition, and others. 14 | 15 | 3. `dataDictionaryAndProfile`: This option provides extensive metadata combining both data dictionary and profile metrics. The metadata includes computed metrics such as sentiment analysis, useful keywords, privacy, and others. 16 | 17 | The `delimiter` parameter allows you to specify the type of delimiter used to separate fields in a row when downloading metadata. With the `prefix` parameter, you can provide a prefix, while the `dateTimeStampSuffix` boolean parameter determines whether a date timestamp suffix should be added to the downloaded file name. The `prefix` and `dateTimeStampSuffix` parameters influence the downloadable file name. This can be seen in the Content-Disposition response header. 18 | 19 | To upload table metadata to CAS, you need to provide the `serverName` (the name of the CAS Server) and `casLibName` (the name of the accessible CAS library for data upload). You can also specify `level`, `prefix`, and `dateTimeStampSuffix` parameters. 20 | 21 | In this Python notebook, the first few requests are setup to create and execute discovery agent to retrieve metadata about tables that are in in the Samples CASLibrary. The second set of requests provides examples of downloading metadata using different values for `level`, `prefix`, and `dateTimeStampSuffix` parameters. 22 | There are examples to demonstrate how to upload metadata to a "Public" library in CAS that uses parameters like `level`, `prefix`, and `dateTimeStampSuffix`. 23 | 24 | ## Prerequisites 25 | 26 | #### Variables to assign: 27 | - sasserver - the SAS Viya server URL 28 | - username 29 | - password 30 | 31 | ### Packages and Python Version 32 | - python 3.7+ 33 | - requests, json, time 34 | ## Usage 35 | 1. Download the Python program or the Jupyter Notebook file. 36 | 2. Edit your variables to match your environment. 37 | 3. Proceed to run the program or Notebook commands. 38 | ## Endpoints Used 39 | Create and execute Agent 40 | Create and execute Agent 41 | - [/catalog/bots](https://developer.sas.com/rest-apis/catalog/createAgent) - Create an Agent 42 | - [/catalog/bots/{agentId}/state](https://developer.sas.com/rest-apis/catalog/updateAgentRunState) - Update an Agent's run state 43 | - [/catalog/bots/{agentId}/state](https://developer.sas.com/rest-apis/catalog/getAgentRunState) - Get an Agent's execution status 44 | - [/catalog/instances/](https://developer.sas.com/rest-apis/catalog/downloadInstances) - Download instances 45 | - [/catalog/instances/](https://developer.sas.com/rest-apis/catalog/uploadInstances) - Upload instances metadata to CAS 46 | 47 | ## Supported Versions 48 | - Viya 4 49 | - 2023.10 50 | ## Additional Resources 51 | -------------------------------------------------------------------------------- /DataManagement/catalog/python/catalog/download-upload-to-cas-profiled-metrics-data/download-upload-to-cas-profiled-metrics-data_requests_notebook.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "cd3b1161", 6 | "metadata": {}, 7 | "source": [ 8 | "\n", 9 | "# API Requests from Postman Collection\n", 10 | "This notebook contains API requests extracted from the provided Postman collection.\n" 11 | ] 12 | }, 13 | { 14 | "cell_type": "code", 15 | "execution_count": null, 16 | "id": "b46bb498", 17 | "metadata": {}, 18 | "outputs": [], 19 | "source": [ 20 | "\n", 21 | "# 0. /SASLogon/oauth/token\n", 22 | "import requests\n", 23 | "import json\n", 24 | "import urllib3\n", 25 | "# Disable all warnings from urllib3\n", 26 | "urllib3.disable_warnings()\n", 27 | "\n", 28 | "sasserver = \"https://your_server\"\n", 29 | "payload = {\n", 30 | " 'grant_type': 'password',\n", 31 | " 'username': 'your_username',\n", 32 | " 'password': 'your_password'\n", 33 | "}\n", 34 | "\n", 35 | "url = f\"{sasserver}/SASLogon/oauth/token\"\n", 36 | "headers = {'Authorization': 'Basic c2FzLmVjOg=='}\n", 37 | "response = requests.post(url, headers=headers, data=payload,verify=False)\n", 38 | "access_token = response.json()[\"access_token\"]\n", 39 | "\n", 40 | "print(json.dumps(response.json(), indent=4))" 41 | ] 42 | }, 43 | { 44 | "cell_type": "code", 45 | "execution_count": null, 46 | "id": "c98f47a3", 47 | "metadata": {}, 48 | "outputs": [], 49 | "source": [ 50 | "\n", 51 | "# 1. Create Discovery Agent\n", 52 | "url = f\"{sasserver}/catalog/bots\"\n", 53 | "headers = {\n", 54 | " 'Content-Type': 'application/json',\n", 55 | " 'Authorization': 'Bearer ' + access_token\n", 56 | "}\n", 57 | "\n", 58 | "payload = json.dumps({\n", 59 | " \"provider\": \"TABLE-BOT\",\n", 60 | " \"name\": \"Crawl Samples Use Case (CAS)\",\n", 61 | " \"description\": \"Crawl the Samples caslib\",\n", 62 | " \"parameters\": {\n", 63 | " \t\"datasourceURI\": \"/dataSources/providers/cas/sources/cas-shared-default~fs~Samples\",\n", 64 | " \"region\": \"US NC\"\n", 65 | " }\n", 66 | "})\n", 67 | "\n", 68 | "response = requests.post(url, headers=headers, data=payload, verify=False)\n", 69 | "botId = response.json()[\"id\"]\n", 70 | "print(json.dumps(response.json(), indent=4))\n", 71 | "\n", 72 | " " 73 | ] 74 | }, 75 | { 76 | "cell_type": "code", 77 | "execution_count": null, 78 | "id": "5932e3f6", 79 | "metadata": {}, 80 | "outputs": [], 81 | "source": [ 82 | "\n", 83 | "# 2. Run Discovery Agent\n", 84 | "url = f\"{sasserver}/catalog/bots/{botId}/state?value=running\"\n", 85 | "headers = {\n", 86 | " 'Accept': 'text/plain',\n", 87 | " 'Authorization': 'Bearer ' + access_token\n", 88 | "}\n", 89 | "\n", 90 | "response = requests.put(url, headers=headers, data=None, verify=False)\n", 91 | "print(response.text)\n", 92 | " " 93 | ] 94 | }, 95 | { 96 | "cell_type": "code", 97 | "execution_count": null, 98 | "id": "ebe296a4", 99 | "metadata": {}, 100 | "outputs": [], 101 | "source": [ 102 | "\n", 103 | "# 3. Discovery Agent state\n", 104 | "import time\n", 105 | "url = f\"{sasserver}/catalog/bots/{botId}/state\"\n", 106 | "response = requests.get(url, headers=headers, data=None, verify=False)\n", 107 | "start_time = time.time()\n", 108 | "\n", 109 | "while response.text != 'idle':\n", 110 | " response = requests.get(url, headers=headers, data=None, verify=False)\n", 111 | " print(response.text)\n", 112 | " time.sleep(5)\n", 113 | "end_time = time.time()\n", 114 | "\n", 115 | "print(f\"Agent took {round(end_time - start_time)}s to run\")\n", 116 | " " 117 | ] 118 | }, 119 | { 120 | "cell_type": "code", 121 | "execution_count": null, 122 | "id": "b50988b1", 123 | "metadata": {}, 124 | "outputs": [], 125 | "source": [ 126 | "\n", 127 | "# 4. Discovery Agent\n", 128 | "url = f\"{sasserver}/catalog/bots/{botId}\"\n", 129 | "headers = {\n", 130 | " 'Accept': 'application/vnd.sas.metadata.bot.summary+json',\n", 131 | " 'Authorization': 'Bearer ' + access_token\n", 132 | "}\n", 133 | "response = requests.get(url, headers=headers, data=None, verify=False)\n", 134 | "print(json.dumps(response.json(), indent=4))\n", 135 | " " 136 | ] 137 | }, 138 | { 139 | "cell_type": "code", 140 | "execution_count": null, 141 | "id": "fdbbac6a", 142 | "metadata": {}, 143 | "outputs": [], 144 | "source": [ 145 | "\n", 146 | "# 5. Download dataDictionary filtered by name with prefix\n", 147 | "url = f\"{sasserver}/catalog/instances?filter=contains(name,COST)&level=dataDictionary&prefix=simpledownload\"\n", 148 | "headers = {\n", 149 | " 'Accept': 'text/csv',\n", 150 | " 'Authorization': 'Bearer ' + access_token\n", 151 | "}\n", 152 | "response = requests.get(url, headers=headers, data=None, verify=False)\n", 153 | "print(response.text) " 154 | ] 155 | }, 156 | { 157 | "cell_type": "code", 158 | "execution_count": null, 159 | "id": "652314bc", 160 | "metadata": {}, 161 | "outputs": [], 162 | "source": [ 163 | "\n", 164 | "# 6. Download dataDictionary, multiple tables filtered by name with prefix\n", 165 | "url = f\"{sasserver}/catalog/instances/?filter=or(contains(name,COST),contains(name,WARRANTY))&level=dataDictionary&prefix=multipletables\"\n", 166 | "headers = {\n", 167 | " 'Accept': 'text/csv',\n", 168 | " 'Authorization': 'Bearer ' + access_token\n", 169 | "}\n", 170 | "response = requests.get(url, headers=headers, data=None, verify=False)\n", 171 | "print(response.text) " 172 | ] 173 | }, 174 | { 175 | "cell_type": "code", 176 | "execution_count": null, 177 | "id": "472e8af2", 178 | "metadata": {}, 179 | "outputs": [], 180 | "source": [ 181 | "# 7. Download dataDictionary, filtered by name, prefix and dateTimeStampSuffix set to false\n", 182 | "\n", 183 | "url = f\"{sasserver}/catalog/instances/?filter=or(contains(name,COST),contains(name,WARRANTY))&level=dataDictionary&prefix=multipletables_nodatetimesuffix&dateTimeStampSuffix=false\"\n", 184 | "\n", 185 | "headers = {'Accept': 'text/csv', 'Authorization': 'Bearer ' + access_token}\n", 186 | "response = requests.get(url, headers=headers,data=None, verify=False)\n", 187 | "print(response.status_code)\n", 188 | "print(response.text)" 189 | ] 190 | }, 191 | { 192 | "cell_type": "code", 193 | "execution_count": null, 194 | "id": "007704d0", 195 | "metadata": {}, 196 | "outputs": [], 197 | "source": [ 198 | "# 8. Upload dataDictionary to CAS filtered by name with prefix\n", 199 | "\n", 200 | "url = f\"{sasserver}/catalog/instances/?filter=contains(name,COST)\"\n", 201 | "\n", 202 | "headers = {'Authorization': 'Bearer ' + access_token, 'Content-Type': 'application/vnd.sas.metadata.instance.upload.request+json', 'Accept': 'application/vnd.sas.metadata.instance.upload.request+json'}\n", 203 | "# Replace placeholders in the body with actual values\n", 204 | "data = '''{\n", 205 | " \"level\": \"dataDictionary\",\n", 206 | " \"prefix\": \"dataDictionary_cost_table_upload\",\n", 207 | " \"dateTimeStampSuffix\": true,\n", 208 | " \"serverName\": \"cas-shared-default\",\n", 209 | " \"caslibName\": \"Public\"\n", 210 | "}'''\n", 211 | "response = requests.post(url, headers=headers, data=data,verify=False)\n", 212 | "print(response.status_code)\n", 213 | "print(response.text)\n" 214 | ] 215 | }, 216 | { 217 | "cell_type": "code", 218 | "execution_count": null, 219 | "id": "57db10c4", 220 | "metadata": {}, 221 | "outputs": [], 222 | "source": [ 223 | "# 9. Download detailedMetrics filtered by name with prefix\n", 224 | "\n", 225 | "url = f\"{sasserver}/catalog/instances/?filter=contains(name,COST)&level=detailedMetrics&prefix=detailedmetrics_costTable\"\n", 226 | "\n", 227 | "headers = {'Accept': 'text/csv','Authorization': 'Bearer ' + access_token}\n", 228 | "response = requests.get(url, headers=headers,verify=False)\n", 229 | "print(response.status_code)\n", 230 | "print(response.text)\n" 231 | ] 232 | }, 233 | { 234 | "cell_type": "code", 235 | "execution_count": null, 236 | "id": "af6de40e", 237 | "metadata": {}, 238 | "outputs": [], 239 | "source": [ 240 | "# 10. Upload detailedMetrics to CAS filtered by name with prefix\n", 241 | "# Replace placeholders in the URL with actual values\n", 242 | "url = f\"{sasserver}/catalog/instances/?filter=contains(name,COST)\"\n", 243 | "# Replace placeholders in the headers with actual values\n", 244 | "headers = { 'Authorization': 'Bearer ' + access_token,'Content-Type': 'application/vnd.sas.metadata.instance.upload.request+json', 'Accept': 'application/vnd.sas.metadata.instance.upload.request+json'}\n", 245 | "# Replace placeholders in the body with actual values\n", 246 | "data = '''{\n", 247 | " \"level\": \"detailedMetrics\",\n", 248 | " \"prefix\": \"detailedMetrics_cost_table_upload\",\n", 249 | " \"dateTimeStampSuffix\": true,\n", 250 | " \"serverName\": \"cas-shared-default\",\n", 251 | " \"caslibName\": \"Public\"\n", 252 | "}'''\n", 253 | "response = requests.post(url, headers=headers, data=data,verify=False)\n", 254 | "print(response.status_code)\n", 255 | "print(response.text)" 256 | ] 257 | }, 258 | { 259 | "cell_type": "code", 260 | "execution_count": null, 261 | "id": "a4793643", 262 | "metadata": {}, 263 | "outputs": [], 264 | "source": [ 265 | "# 11. Download profile Metrics filtered by name with prefix\n", 266 | "# Replace placeholders in the URL with actual values\n", 267 | "url = f\"{sasserver}/catalog/instances?filter=contains(name,COST)&level=dataDictionaryAndProfile\"\n", 268 | "# Replace placeholders in the headers with actual values\n", 269 | "headers = {'Authorization': 'Bearer ' + access_token, 'Content-Type': 'application/vnd.sas.metadata.instance.upload.request+json', 'Accept': 'text/csv'}\n", 270 | "response = requests.get(url, headers=headers,verify=False)\n", 271 | "print(response.status_code)\n", 272 | "print(response.text)" 273 | ] 274 | }, 275 | { 276 | "cell_type": "code", 277 | "execution_count": null, 278 | "id": "e3bc53a7", 279 | "metadata": {}, 280 | "outputs": [], 281 | "source": [ 282 | "# 12. Upload profileMetrics to CAS with filter all data in the Samples discovery agent crawled library\n", 283 | "# Replace placeholders in the URL with actual values\n", 284 | "url = f\"{sasserver}/catalog/instances?filter=contains(resourceId,'cas~fs~cas-shared-default~fs~Samples')\"\n", 285 | "# Replace placeholders in the headers with actual values\n", 286 | "headers = { 'Authorization': 'Bearer ' + access_token,'Content-Type': 'application/vnd.sas.metadata.instance.upload.request+json', 'Accept': 'application/vnd.sas.metadata.instance.upload.request+json'}\n", 287 | "# Replace placeholders in the body with actual values\n", 288 | "data = '''{\n", 289 | " \"level\": \"dataDictionaryAndProfile\",\n", 290 | " \"prefix\": \"dataDictionaryAndProfile_all_Samples_table_upload\",\n", 291 | " \"dateTimeStampSuffix\": true,\n", 292 | " \"serverName\": \"cas-shared-default\",\n", 293 | " \"caslibName\": \"Public\"\n", 294 | "}'''\n", 295 | "response = requests.post(url, headers=headers, data=data, verify=False)\n", 296 | "print(response.status_code)\n", 297 | "print(response.text)" 298 | ] 299 | }, 300 | { 301 | "cell_type": "code", 302 | "execution_count": null, 303 | "id": "32dc5bc4", 304 | "metadata": {}, 305 | "outputs": [], 306 | "source": [ 307 | "\n", 308 | "# 13. Delete Discovery Agent\n", 309 | "url = f\"{sasserver}/catalog/bots/{botId}\"\n", 310 | "headers = {\n", 311 | " 'Authorization': 'Bearer ' + access_token\n", 312 | "}\n", 313 | "response = requests.delete(url, headers=headers, data=None, verify=False)\n", 314 | "print(response.text)\n", 315 | " " 316 | ] 317 | } 318 | ], 319 | "metadata": { 320 | "kernelspec": { 321 | "display_name": "Python 3 (ipykernel)", 322 | "language": "python", 323 | "name": "python3" 324 | }, 325 | "language_info": { 326 | "codemirror_mode": { 327 | "name": "ipython", 328 | "version": 3 329 | }, 330 | "file_extension": ".py", 331 | "mimetype": "text/x-python", 332 | "name": "python", 333 | "nbconvert_exporter": "python", 334 | "pygments_lexer": "ipython3", 335 | "version": "3.10.4" 336 | } 337 | }, 338 | "nbformat": 4, 339 | "nbformat_minor": 5 340 | } 341 | -------------------------------------------------------------------------------- /DataManagement/catalog/python/catalog/use-search-to-lookup-resources/README.md: -------------------------------------------------------------------------------- 1 | # Search and Find Assets 2 | 3 | ## Overview 4 | 5 | This collection leverages the Catalog API to support search capabilities. 6 | 7 | - Using search with facets to find data sets with a free text query. 8 | 9 | - Using suggestions to retrieve suggested values for searchers on a given facet. 10 | 11 | - Specifying an index to limit the type of resources returned by the request. 12 | 13 | - Find data sets that have been updated from a specified time period. 14 | 15 | - Find resources based on the provided indices and keyword. 16 | 17 | ## Prerequisites 18 | 19 | #### Variables to assign: 20 | - sasserver - the SAS Viya server URL 21 | - username 22 | - password 23 | 24 | ### Python Version and Packages 25 | - python 3.10+ 26 | - requests, json, datetime 27 | 28 | ## Usage 29 | 1. Download the Python program or the Jupyter Notebook file. 30 | 2. Edit your variables to match your environment. 31 | 3. Proceed to run the program or Notebook commands 32 | 33 | ## Endpoints Used 34 | 35 | - [/catalog/search](https://developer.sas.com/rest-apis/catalog/getSearchResults) - Get Search Results 36 | - [/catalog/search/facets](https://developer.sas.com/rest-apis/catalog/getSearchFacets) - Get Search Facets 37 | - [/catalog/search/suggestions](https://developer.sas.com/rest-apis/catalog/getSearchSuggestions) - Retrieve suggested values for searches on a given field 38 | 39 | ## Supported Versions 40 | 41 | - Viya 4 42 | - 2023.10 43 | 44 | ## Additional Resources 45 | -------------------------------------------------------------------------------- /DataManagement/catalog/python/catalog/use-search-to-lookup-resources/use-search-to-lookup-resources.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "cd3b1161", 6 | "metadata": {}, 7 | "source": [ 8 | "# Search and find assets\n", 9 | "\n", 10 | "0. [Get Access Token](#authentication)\n", 11 | "1. [Search for facets related toLibrary](#find-facets)\n", 12 | "2. [Get data sets with Library.name facet](#use-facets)\n", 13 | "3. [Get data sets with free text query](#get-tables)\n", 14 | "4. [Get the 'datesets' search indices](#get-index)\n", 15 | "5. [Get list of suggestions for 'Name' facet within the datasets index](#get-suggestions)\n", 16 | "6. [Search for tables with 'WARRANTY' in the name that have been updated since yesterday](#get-last-updated)\n", 17 | "7. [Find all crawled tables that contain columns classified as Date](#get-crawled-tables)\n", 18 | "8. [Search for reports related to \"inventory\"](#get-crawled-tables)\n", 19 | "\n", 20 | "> Please make sure you run [Imports and Global Variables](#imports) before executing anything else in this notebook. Also ensure you are authenticated by running [Get Access Token](#authentication).\n" 21 | ] 22 | }, 23 | { 24 | "cell_type": "markdown", 25 | "id": "4886ddf3", 26 | "metadata": {}, 27 | "source": [ 28 | "## **Imports and Global Variables** \n", 29 | "\n", 30 | "> _**NOTE**_: Run this cell before any of the others\n", 31 | "\n", 32 | "- Imports packages and sets variables that will be used throughout the notebook\n", 33 | "\n", 34 | "- Update `sasserver` to your server url\n", 35 | "\n", 36 | "- You can change other variables to fit your use case. This will be used through out the exmaple." 37 | ] 38 | }, 39 | { 40 | "cell_type": "code", 41 | "execution_count": 2, 42 | "id": "fdd1fa83", 43 | "metadata": {}, 44 | "outputs": [], 45 | "source": [ 46 | "import requests\n", 47 | "import json\n", 48 | "from datetime import datetime, timedelta\n", 49 | "\n", 50 | "sasserver = \"https://your_server_url\"\n", 51 | "username = 'your_username'\n", 52 | "password = 'your_password'\n", 53 | "\n", 54 | "cas_library = 'Samples'\n", 55 | "cas_table_name = 'WATER_CLUSTER'" 56 | ] 57 | }, 58 | { 59 | "cell_type": "markdown", 60 | "id": "4e142ca7", 61 | "metadata": {}, 62 | "source": [ 63 | "## Get Access Token \n", 64 | "\n", 65 | "- This gets and sets the `access_token` that will be used for the current section\n", 66 | "\n", 67 | "- Run this periodically/as needed because sometimes, the authentication may expire after a certain amount of time\n" 68 | ] 69 | }, 70 | { 71 | "cell_type": "code", 72 | "execution_count": null, 73 | "id": "b46bb498", 74 | "metadata": {}, 75 | "outputs": [], 76 | "source": [ 77 | "url = f\"{sasserver}/SASLogon/oauth/token\"\n", 78 | "\n", 79 | "payload = {\n", 80 | " 'grant_type': 'password',\n", 81 | " 'username': username,\n", 82 | " 'password': password\n", 83 | "}\n", 84 | "\n", 85 | "headers = {\n", 86 | " 'Authorization': 'Basic c2FzLmVjOg=='\n", 87 | "}\n", 88 | "\n", 89 | "response = requests.post(url, headers=headers, data=payload,verify=False)\n", 90 | "\n", 91 | "if response.status_code == 200:\n", 92 | " access_token = 'Bearer ' + response.json()[\"access_token\"]\n", 93 | " duration = round(int(response.json()['expires_in']) / 60)\n", 94 | " valid_until = datetime.now() + timedelta(minutes=duration)\n", 95 | " print(f\"access_token is: {access_token}\")\n", 96 | " print(f\"This token will be valid until: {valid_until}\")\n", 97 | "else:\n", 98 | " print('Authentication failed')" 99 | ] 100 | }, 101 | { 102 | "cell_type": "markdown", 103 | "id": "e2d89b40", 104 | "metadata": {}, 105 | "source": [ 106 | "## Search for facets related to Library " 107 | ] 108 | }, 109 | { 110 | "cell_type": "code", 111 | "execution_count": null, 112 | "id": "c98f47a3", 113 | "metadata": {}, 114 | "outputs": [], 115 | "source": [ 116 | "url = f\"{sasserver}/catalog/search/facets?q=Library\"\n", 117 | "headers = {\n", 118 | " 'Authorization': access_token\n", 119 | "}\n", 120 | "\n", 121 | "response = requests.get(url, headers=headers, data=payload, verify=False)\n", 122 | "print(json.dumps(response.json(), indent=4))" 123 | ] 124 | }, 125 | { 126 | "cell_type": "markdown", 127 | "id": "3f9aea9d", 128 | "metadata": {}, 129 | "source": [ 130 | "## Get CAS library with facet Library.name " 131 | ] 132 | }, 133 | { 134 | "cell_type": "code", 135 | "execution_count": null, 136 | "id": "5932e3f6", 137 | "metadata": {}, 138 | "outputs": [], 139 | "source": [ 140 | "url = f\"{sasserver}/catalog/search?q=Library.name:'{cas_library}'&indices=datasets\"\n", 141 | "headers = {\n", 142 | " 'Authorization': access_token\n", 143 | "}\n", 144 | "\n", 145 | "response = requests.get(url, headers=headers, data=None, verify=False)\n", 146 | "\n", 147 | "responseBody = response.json()\n", 148 | "print(json.dumps(responseBody, indent=4))\n", 149 | " " 150 | ] 151 | }, 152 | { 153 | "cell_type": "markdown", 154 | "id": "a2be1af7", 155 | "metadata": {}, 156 | "source": [ 157 | "## Get data sets with fuzzy search " 158 | ] 159 | }, 160 | { 161 | "cell_type": "code", 162 | "execution_count": null, 163 | "id": "ebe296a4", 164 | "metadata": {}, 165 | "outputs": [], 166 | "source": [ 167 | "url = f\"{sasserver}/catalog/search?q={cas_table_name}&indices=datasets\"\n", 168 | "headers = {\n", 169 | " 'Authorization': access_token\n", 170 | "}\n", 171 | "\n", 172 | "response = requests.get(url, headers=headers, data=None, verify=False)\n", 173 | "\n", 174 | "responseBody = response.json()\n", 175 | "print(json.dumps(responseBody, indent=4))" 176 | ] 177 | }, 178 | { 179 | "cell_type": "markdown", 180 | "id": "eb69c2f2", 181 | "metadata": {}, 182 | "source": [ 183 | "## Get the 'datesets' search indices " 184 | ] 185 | }, 186 | { 187 | "cell_type": "code", 188 | "execution_count": null, 189 | "id": "b50988b1", 190 | "metadata": {}, 191 | "outputs": [], 192 | "source": [ 193 | "url = f\"{sasserver}/catalog/search/indices?filter=eq(name,'datasets')\"\n", 194 | "headers = {\n", 195 | " 'Authorization': access_token\n", 196 | "}\n", 197 | "response = requests.get(url, headers=headers, data=None, verify=False)\n", 198 | "print(json.dumps(response.json(), indent=4))" 199 | ] 200 | }, 201 | { 202 | "cell_type": "markdown", 203 | "id": "b1d7c986", 204 | "metadata": {}, 205 | "source": [ 206 | "## Get list of suggestions for 'Name' facet within the datasets index " 207 | ] 208 | }, 209 | { 210 | "cell_type": "code", 211 | "execution_count": null, 212 | "id": "fdbbac6a", 213 | "metadata": {}, 214 | "outputs": [], 215 | "source": [ 216 | "url = f\"{sasserver}/catalog/search/suggestions?facet=Name&indices=datasets&q=\"\n", 217 | "headers = {\n", 218 | " 'Authorization': access_token\n", 219 | "}\n", 220 | "response = requests.get(url, headers=headers, data=None, verify=False)\n", 221 | "print(json.dumps(response.json(), indent=4))\n", 222 | " " 223 | ] 224 | }, 225 | { 226 | "cell_type": "markdown", 227 | "id": "b033cd8a", 228 | "metadata": {}, 229 | "source": [ 230 | "## Search for tables whose names contain 'WARRANTY' and were updated on the previous day" 231 | ] 232 | }, 233 | { 234 | "cell_type": "code", 235 | "execution_count": null, 236 | "id": "652314bc", 237 | "metadata": {}, 238 | "outputs": [], 239 | "source": [ 240 | "yesterday = (datetime.now() - timedelta(days=1)).strftime(\"%Y-%m-%d\")\n", 241 | "today = datetime.today().strftime(\"%Y-%m-%d\")\n", 242 | "url = f\"{sasserver}/catalog/search?indices=datasets&q=DateModified:[{yesterday} TO {today}]+Name:WARRANTY\"\n", 243 | "print(url)\n", 244 | "headers = {\n", 245 | " 'Authorization': access_token\n", 246 | "}\n", 247 | "response = requests.get(url, headers=headers, data=None, verify=False)\n", 248 | "print(json.dumps(response.json(), indent=4))\n", 249 | " " 250 | ] 251 | }, 252 | { 253 | "cell_type": "markdown", 254 | "id": "708020ef", 255 | "metadata": {}, 256 | "source": [ 257 | "## Find all crawled tables that contain columns classified as Date " 258 | ] 259 | }, 260 | { 261 | "cell_type": "code", 262 | "execution_count": null, 263 | "id": "f30af307", 264 | "metadata": {}, 265 | "outputs": [], 266 | "source": [ 267 | "url = f\"{sasserver}/catalog/search?indices=datasets&q=Column.semanticType:'date'\"\n", 268 | "headers = {\n", 269 | " 'Authorization': access_token\n", 270 | "}\n", 271 | "response = requests.get(url, headers=headers, data=None, verify=False)\n", 272 | "print(json.dumps(response.json(), indent=4))\n", 273 | " " 274 | ] 275 | }, 276 | { 277 | "cell_type": "markdown", 278 | "id": "69f61714", 279 | "metadata": {}, 280 | "source": [ 281 | "## Search for reports related to \"inventory\" " 282 | ] 283 | }, 284 | { 285 | "cell_type": "code", 286 | "execution_count": null, 287 | "id": "32dc5bc4", 288 | "metadata": {}, 289 | "outputs": [], 290 | "source": [ 291 | "url = f\"{sasserver}/catalog/search?q=inventory&indices=reports\"\n", 292 | "headers = {\n", 293 | " 'Authorization': access_token\n", 294 | "}\n", 295 | "response = requests.get(url, headers=headers, data=None, verify=False)\n", 296 | "print(json.dumps(response.json(), indent=4))" 297 | ] 298 | } 299 | ], 300 | "metadata": { 301 | "kernelspec": { 302 | "display_name": "Python 3", 303 | "language": "python", 304 | "name": "python3" 305 | }, 306 | "language_info": { 307 | "codemirror_mode": { 308 | "name": "ipython", 309 | "version": 3 310 | }, 311 | "file_extension": ".py", 312 | "mimetype": "text/x-python", 313 | "name": "python", 314 | "nbconvert_exporter": "python", 315 | "pygments_lexer": "ipython3", 316 | "version": "3.11.5" 317 | } 318 | }, 319 | "nbformat": 4, 320 | "nbformat_minor": 5 321 | } 322 | -------------------------------------------------------------------------------- /DataManagement/glossary/import.csv: -------------------------------------------------------------------------------- 1 | Name,Type,Path,Description,singleLineTextAttribute,multiLineTextAttribute,singleSelectAttribute, 2 | Sample_DefaultTerm,,,A term using the default term type,,,, 3 | Sample_ChildTerm,,Sample_DefaultTerm,A child of Sample_DefaultTerm,,,, 4 | Sample_GrandchildTerm,,Sample_DefaultTerm\Sample_ChildTerm,A child of Sample_ChildTerm,,,, 5 | Sample_CustomTerm,Sample Term Type,,A term using a custom term type with attributes,singleLine,"multi 6 | line",Item 1, 7 | -------------------------------------------------------------------------------- /DataManagement/glossary/postman/glossary/drafts-use-cases/README.md: -------------------------------------------------------------------------------- 1 | #### Create, Read, Update, and Delete Drafts 2 | ##### Overview 3 | This collection uses the Glossary API to create, read, update, and delete draft terms. 4 | 5 | ##### Variables to assign: 6 | The Postman collection comes with variables that you must assign either at the collection or environment level. Assign values to the following variables prior to running the collection: 7 | - `sasserver` - the location of the SAS Viya server; for example: https://myserver.sas.com 8 | - `username` 9 | - `password` 10 | Other variables are assigned programmatically during the REST calls using code in the Postman Tests tab. 11 | 12 | ##### Usage 13 | 1. Download the JSON collection and the sasserver.env file. Then Import the files into Postman. 14 | 2. Select sasserver.env as the environment. Edit your environment variables to match your collection requests. 15 | 3. Authenticate to your server before testing by running the first request: `0. Get Token`. 16 | 17 | ##### Endpoints Used 18 | - [/glossary/termTypes](https://developer.sas.com/rest-apis/glossary/createTermType) - Create a Term Type 19 | - [/glossary/terms?publish=true](https://developer.sas.com/rest-apis/glossary/createTerm) - Create a Term 20 | - [/glossary/terms?publish=false](https://developer.sas.com/rest-apis/glossary/createTerm) - Create a Draft 21 | - [/glossary/terms/{termId}/draft](https://developer.sas.com/rest-apis/glossary/createDraftFromTerm) - Create a Draft from a published Term 22 | - [/glossary/terms/{termId}/draft/state](https://developer.sas.com/rest-apis/glossary/updatePublishDraft) - Publish a Draft by its ID 23 | - [/glossary/terms/{termId}/draft](https://developer.sas.com/rest-apis/glossary/getDraft) - Get a Draft by its ID 24 | - [/glossary/terms?allowDrafts=all](https://developer.sas.com/rest-apis/glossary/getTerms) - Get Drafts via filter 25 | - [/glossary/terms/{termId}/draft](https://developer.sas.com/rest-apis/glossary/updateDraft) - Update a Draft by its ID 26 | - [/glossary/terms/{termId}/draft](https://developer.sas.com/rest-apis/glossary/patchDraft) - Patch a Draft by its ID 27 | - [/glossary/terms/{termId}/draft](https://developer.sas.com/rest-apis/glossary/deleteDraft) - Delete a Draft by its ID 28 | - [/glossary/termTypes/{termTypeId}](https://developer.sas.com/rest-apis/glossary/deleteTermType) - Delete a Term Type by its ID 29 | 30 | ##### Supported Versions 31 | - Viya 4 32 | 33 | ##### Additional Resources 34 | -------------------------------------------------------------------------------- /DataManagement/glossary/postman/glossary/import-terms-use-cases/README.md: -------------------------------------------------------------------------------- 1 | #### Import Term Use Cases 2 | ##### Overview 3 | This program uses the Glossary and Catalog APIs to import terms from a CSV file and retrieve the log. 4 | 5 | ##### Variables to assign: 6 | The Postman collection comes with variables that you must assign either at the collection or environment level. Assign values to the following variables prior to running the collection: 7 | - `sasserver` - the location of the SAS Viya server; for example: https://myserver.sas.com 8 | - `username` 9 | - `password` 10 | Other variables are assigned programmatically during the REST calls using code in the Postman Tests tab. 11 | 12 | ##### Usage 13 | 1. Download the JSON collection and the sasserver.env. Import the files into Postman. 14 | 2. Select sasserver.env as the environment. Edit your environment variables to match those contained in the collection requests (sasserver, access_token). 15 | 3. Authenticate to your server before testing the endpoints by running the first request: `0. Get token`. 16 | 17 | ##### Endpoints Used 18 | - [/glossary/termTypes](https://developer.sas.com/rest-apis/glossary/createTermType) - Create a Term Type 19 | - [/glossary/termTypes/{termTypeId}](https://developer.sas.com/rest-apis/glossary/deleteTermType) - Delete a Term Type 20 | - [/glossary/importTerms](https://developer.sas.com/rest-apis/glossary/importTerms) - Create Terms by Importing CSV File 21 | - [/glossary/terms/{termId}](https://developer.sas.com/rest-apis/glossary/getTerm) - Get a Term 22 | - [/glossary/terms](https://developer.sas.com/rest-apis/glossary/getTerms) - Get Terms by Filter 23 | - [/glossary/terms/{termId}](https://developer.sas.com/rest-apis/glossary/deleteTerm) - Delete a Term 24 | - [/jobs/{jobId}](https://developer.sas.com/rest-apis/jobExecution-v7?operation=getJob) - Get Import Job 25 | - [/files/{fileId}/content](https://developer.sas.com/rest-apis/files-v9?operation=getfileContentForGivenId) - Get Import Log 26 | 27 | ##### Supported Versions 28 | - Viya 4 29 | 30 | ##### Additional Resources 31 | -------------------------------------------------------------------------------- /DataManagement/glossary/postman/glossary/term-type-use-cases/README.md: -------------------------------------------------------------------------------- 1 | #### Create, Read, Update, and Delete Term Types 2 | ##### Overview 3 | This collection leverages the Glossary API to create, read, update, and delete term types. 4 | 5 | ##### Variables to assign: 6 | The Postman collection comes with variables that you must assign either at the collection or environment level. Assign values to the following variables prior to running the collection: 7 | - `sasserver` - the location of the SAS Viya server; for example: https://myserver.sas.com 8 | - `username` 9 | - `password` 10 | Other variables are assigned programmatically during the REST calls using code in the Postman Tests tab. 11 | 12 | ##### Usage 13 | 1. Download the JSON collection and the sasserver.env file. Then import the files into Postman. 14 | 2. Select sasserver.env as the environment. Edit your environment variables to match those contained in the collection requests (sasserver, username, password). 15 | 3. Authenticate to your server before testing the endpoints by running the first request: `0. Get token`. 16 | 17 | ##### Endpoints Used 18 | - [/glossary/termTypes] (https://developer.sas.com/rest-apis/glossary/getTermTypes) - Get Term Types via filter 19 | - [/glossary/termTypes] (https://developer.sas.com/rest-apis/glossary/createTermType) - Create a Term Type 20 | - [/glossary/termTypes/{termTypeId}] (https://developer.sas.com/rest-apis/glossary/getTermType) - Get a Term Type by its ID 21 | - [/glossary/termTypes/{termTypeId}] (https://developer.sas.com/rest-apis/glossary/updateTermType) - Update a Term Type by its ID 22 | - [/glossary/termTypes/{termTypeId}] (https://developer.sas.com/rest-apis/glossary/deleteTermType) - Delete a Term Type by its ID 23 | 24 | ##### Supported Versions 25 | - Viya 4 26 | 27 | ##### Additional Resources 28 | -------------------------------------------------------------------------------- /DataManagement/glossary/postman/glossary/terms-use-cases/README.md: -------------------------------------------------------------------------------- 1 | #### Term Use Cases 2 | ##### Overview 3 | This program uses the Glossary and Catalog API to search, create, read, update, and delete terms. 4 | 5 | ##### Variables to assign: 6 | The Postman collection comes with variables that you must assign either at the collection or environment level. Assign values to the following variables prior to running the collection: 7 | - `sasserver` - the location of the SAS Viya server; for example: https://myserver.sas.com 8 | - `username` 9 | - `password` 10 | Other variables are assigned programmatically during the REST calls using code in the Postman Tests tab. 11 | 12 | ##### Usage 13 | 1. Download the JSON collection and the sasserver.env. Import the files into Postman. 14 | 2. Select sasserver.env as the environment. Edit your environment variables to match those contained in the collection requests (sasserver, access_token). 15 | 3. Authenticate to your server before testing the endpoints by running the first request: `0. Get token`. 16 | 17 | ##### Endpoints Used 18 | - [/glossary/termTypes](https://developer.sas.com/rest-apis/glossary/createTermType) - Create a Term Type 19 | - [/glossary/termTypes/{termTypeId}](https://developer.sas.com/rest-apis/glossary/deleteTermType) - Delete a Term Type 20 | - [/glossary/terms](https://developer.sas.com/rest-apis/glossary/createTerm) - Create a Term 21 | - [/glossary/terms/{termId}](https://developer.sas.com/rest-apis/glossary/getTerm) - Get a Term by its ID 22 | - [/glossary/terms](https://developer.sas.com/rest-apis/glossary/getTerms) - Get a Term by Filter 23 | - [/glossary/terms/{termId}](https://developer.sas.com/rest-apis/glossary/updateTerm) - Update a Term by its ID 24 | - [/glossary/terms/{termId}](https://developer.sas.com/rest-apis/glossary/patchTerm) - Patch a Term by its ID 25 | - [/glossary/terms/{termId}](https://developer.sas.com/rest-apis/glossary/deleteTerm) - Delete a Term by its ID 26 | - [/catalog/search](https://developer.sas.com/rest-apis/catalog/getSearchResults) -Search for Terms 27 | - [/catalog/instances](https://developer.sas.com/rest-apis/catalog/createInstance) - Create an Instance 28 | - [/catalog/instances/{instanceId}](https://developer.sas.com/rest-apis/catalog/deleteInstance) - Delete an Instance 29 | 30 | ##### Supported Versions 31 | - Viya 4 32 | 33 | ##### Additional Resources 34 | -------------------------------------------------------------------------------- /DataManagement/glossary/python/glossary/drafts-use-cases/README.md: -------------------------------------------------------------------------------- 1 | #### Create, Read, Update, and Delete Drafts 2 | ##### Overview 3 | This program uses the Glossary API to create, read, update, and delete draft terms. 4 | 5 | ##### Variables to assign: 6 | - `sasserver` - the location of the SAS Viya server; for example: https://myserver.sas.com 7 | - `username` 8 | - `password` 9 | 10 | ##### Packages and Python Version 11 | - python 3 12 | - requests, json 13 | 14 | ##### Usage 15 | 1. Download the Python program or the Jupyter Notebook file. 16 | 2. Edit your variables to match your environment. 17 | 3. Proceed to run the program or Notebook commands. 18 | 19 | ##### Endpoints Used 20 | - [/glossary/termTypes](https://developer.sas.com/rest-apis/glossary/createTermType) - Create a Term Type 21 | - [/glossary/terms?publish=true](https://developer.sas.com/rest-apis/glossary/createTerm) - Create a Term 22 | - [/glossary/terms?publish=false](https://developer.sas.com/rest-apis/glossary/createTerm) - Create a Draft 23 | - [/glossary/terms/{termId}/draft](https://developer.sas.com/rest-apis/glossary/createDraftFromTerm) - Create a Draft from a Term 24 | - [/glossary/terms/{termId}/draft/state](https://developer.sas.com/rest-apis/glossary/updatePublishDraft) - Publish a Draft by its ID 25 | - [/glossary/terms/{termId}/draft](https://developer.sas.com/rest-apis/glossary/getDraft) - Get a Draft by its ID 26 | - [/glossary/terms?allowDrafts=all](https://developer.sas.com/rest-apis/glossary/getTerms) - Get Drafts via filter 27 | - [/glossary/terms/{termId}/draft](https://developer.sas.com/rest-apis/glossary/updateDraft) - Update a Draft by its ID 28 | - [/glossary/terms/{termId}/draft](https://developer.sas.com/rest-apis/glossary/patchDraft) - Patch a Draft by its ID 29 | - [/glossary/terms/{termId}/draft](https://developer.sas.com/rest-apis/glossary/deleteDraft) - Delete a Draft by its ID 30 | - [/glossary/termTypes/{termTypeId}](https://developer.sas.com/rest-apis/glossary/deleteTermType) - Delete a Term Type by its ID 31 | 32 | ##### Supported Versions 33 | - Viya 4 34 | 35 | ##### Additional Resources 36 | -------------------------------------------------------------------------------- /DataManagement/glossary/python/glossary/import-terms-use-cases/README.md: -------------------------------------------------------------------------------- 1 | #### Import Term Use Cases 2 | ##### Overview 3 | This program uses the Glossary and Catalog APIs to import terms from a CSV file and retrieve the log. 4 | 5 | ##### Variables to assign: 6 | - `sasserver` - the location of the SAS Viya server; for example: https://myserver.sas.com 7 | - `username` 8 | - `password` 9 | 10 | ##### Packages and Python Version 11 | - python 3 12 | - requests, json 13 | 14 | ##### Usage 15 | 1. Download the Python program or the Jupyter Notebook file. 16 | 2. Edit the variables to match the environment. 17 | 3. Proceed to run the program or Notebook commands. 18 | 19 | ##### Endpoints Used 20 | - [/glossary/termTypes](https://developer.sas.com/rest-apis/glossary/createTermType) - Create a Term Type 21 | - [/glossary/termTypes/{termTypeId}](https://developer.sas.com/rest-apis/glossary/deleteTermType) - Delete a Term Type 22 | - [/glossary/importTerms](https://developer.sas.com/rest-apis/glossary/importTerms) - Create Terms by Importing CSV File 23 | - [/glossary/terms/{termId}](https://developer.sas.com/rest-apis/glossary/getTerm) - Get a Term 24 | - [/glossary/terms](https://developer.sas.com/rest-apis/glossary/getTerms) - Get Terms by Filter 25 | - [/glossary/terms/{termId}](https://developer.sas.com/rest-apis/glossary/deleteTerm) - Delete a Term 26 | - [/jobs/{jobId}](https://developer.sas.com/rest-apis/jobExecution-v7?operation=getJob) - Get Import Job 27 | - [/files/{fileId}/content](https://developer.sas.com/rest-apis/files-v9?operation=getfileContentForGivenId) - Get Import Log 28 | 29 | ##### Supported Versions 30 | - Viya 4 31 | 32 | ##### Additional Resources 33 | -------------------------------------------------------------------------------- /DataManagement/glossary/python/glossary/term-type-use-cases/README.md: -------------------------------------------------------------------------------- 1 | #### Create, Read, Update, and Delete Term Types 2 | ##### Overview 3 | This program leverages the Glossary API to create, read, update, and delete term types. 4 | 5 | ##### Variables to assign: 6 | - `sasserver` - the location of the SAS Viya server; for example: https://myserver.sas.com 7 | - `username` 8 | - `password` 9 | 10 | ##### Packages and Python Version 11 | - python 3 12 | - requests, json 13 | 14 | ##### Usage 15 | 1. Download the Python program or the Jupyter Notebook file. 16 | 2. Edit the variables to match the environment. 17 | 3. Proceed to run the program or Notebook commands. 18 | 19 | ##### Endpoints Used 20 | - [/glossary/termTypes] (https://developer.sas.com/rest-apis/glossary/getTermTypes) - Get Term Types via filter 21 | - [/glossary/termTypes] (https://developer.sas.com/rest-apis/glossary/createTermType) - Create a Term Type 22 | - [/glossary/termTypes/{termTypeId}] (https://developer.sas.com/rest-apis/glossary/getTermType) - Get a Term Type by its ID 23 | - [/glossary/termTypes/{termTypeId}] (https://developer.sas.com/rest-apis/glossary/updateTermType) - Update a Term Type by its ID 24 | - [/glossary/termTypes/{termTypeId}] (https://developer.sas.com/rest-apis/glossary/deleteTermType) - Delete a Term Type by its ID 25 | 26 | ##### Supported Versions 27 | - Viya 4 28 | 29 | ##### Additional Resources 30 | -------------------------------------------------------------------------------- /DataManagement/glossary/python/glossary/terms-use-cases/README.md: -------------------------------------------------------------------------------- 1 | #### Term Use Cases 2 | ##### Overview 3 | This program uses the Glossary and Catalog API to search, create, read, update, and delete terms. 4 | 5 | ##### Variables to assign: 6 | - `sasserver` - the location of the SAS Viya server; for example: https://myserver.sas.com 7 | - `username` 8 | - `password` 9 | 10 | ##### Packages and Python Version 11 | - python 3 12 | - requests, json 13 | 14 | ##### Usage 15 | 1. Download the Python program or the Jupyter Notebook file. 16 | 2. Edit the variables to match the environment. 17 | 3. Proceed to run the program or Notebook commands. 18 | 19 | ##### Endpoints Used 20 | - [/glossary/termTypes](https://developer.sas.com/rest-apis/glossary/createTermType) - Create a Term Type 21 | - [/glossary/termTypes/{termTypeId}](https://developer.sas.com/rest-apis/glossary/deleteTermType) - Delete a Term Type 22 | - [/glossary/terms](https://developer.sas.com/rest-apis/glossary/createTerm) - Create a Term 23 | - [/glossary/terms/{termId}](https://developer.sas.com/rest-apis/glossary/getTerm) - Get a Term by its ID 24 | - [/glossary/terms](https://developer.sas.com/rest-apis/glossary/getTerms) - Get a Term by Filter 25 | - [/glossary/terms/{termId}](https://developer.sas.com/rest-apis/glossary/updateTerm) - Update a Term by its ID 26 | - [/glossary/terms/{termId}](https://developer.sas.com/rest-apis/glossary/patchTerm) - Patch a Term by its ID 27 | - [/glossary/terms/{termId}](https://developer.sas.com/rest-apis/glossary/deleteTerm) - Delete a Term by its ID 28 | - [/catalog/search](https://developer.sas.com/rest-apis/catalog/getSearchResults) -Search for Terms 29 | - [/catalog/instances](https://developer.sas.com/rest-apis/catalog/createInstance) - Create an Instance 30 | - [/catalog/instances/{instanceId}](https://developer.sas.com/rest-apis/catalog/deleteInstance) - Delete an Instance 31 | 32 | ##### Supported Versions 33 | - Viya 4 34 | 35 | ##### Additional Resources 36 | -------------------------------------------------------------------------------- /DataManagement/images/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sassoftware/devsascom-rest-api-samples/8371b14b9e354a79d8993d8eb9c87f4110708209/DataManagement/images/.gitkeep -------------------------------------------------------------------------------- /DataManagement/images/RowSets_RowSetPaginationHorizontal1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sassoftware/devsascom-rest-api-samples/8371b14b9e354a79d8993d8eb9c87f4110708209/DataManagement/images/RowSets_RowSetPaginationHorizontal1.png -------------------------------------------------------------------------------- /DataManagement/images/RowSets_RowSetPaginationHorizontal2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sassoftware/devsascom-rest-api-samples/8371b14b9e354a79d8993d8eb9c87f4110708209/DataManagement/images/RowSets_RowSetPaginationHorizontal2.png -------------------------------------------------------------------------------- /DataManagement/images/RowSets_RowSetPaginationHorizontal3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sassoftware/devsascom-rest-api-samples/8371b14b9e354a79d8993d8eb9c87f4110708209/DataManagement/images/RowSets_RowSetPaginationHorizontal3.png -------------------------------------------------------------------------------- /DataManagement/images/RowSets_RowSetPaginationHorizontal4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sassoftware/devsascom-rest-api-samples/8371b14b9e354a79d8993d8eb9c87f4110708209/DataManagement/images/RowSets_RowSetPaginationHorizontal4.png -------------------------------------------------------------------------------- /DecisionManagement/README.md: -------------------------------------------------------------------------------- 1 | # SAS REST API Examples 2 | 3 | ## Decision Management (Models and Decisions) 4 | 5 | This repository contains SAS contributed examples that show the capabilities of the Decision Management REST APIs. You can use these examples for learning or for validating your environment. 6 | 7 | You are encouraged to contribute your own examples in the [User Contributions repository](../User_and_Aggregated_Samples). 8 | 9 | ## Examples 10 | _**Note:** These examples are for the latest release of SAS Viya. Examples that are only applicable to SAS Viya 3.5 are located in the [viya35](viya35/) directory._ 11 | 12 | * [Business Rules](businessRules.md) 13 | * [Data Mining](dataMining.md) 14 | * [Decisions](decisions.md) 15 | * [Micro Analytic Score](microAnalyticScore.md) 16 | * [Model Management](modelManagement.md) 17 | * [Model Publish](modelPublish.md) 18 | * [Model Repository](modelRepository.md) 19 | * [Reference Data](referenceData.md) 20 | * [Score Definitions](scoreDefinitions.md) 21 | * [Score Executions](scoreExecutions.md) 22 | * [Subject Contacts](subjectContacts.md) 23 | * [Treatment Definitions](treatmentDefinitions.md) 24 | 25 | -------------------------------------------------------------------------------- /DecisionManagement/dataMining.md: -------------------------------------------------------------------------------- 1 | # Data Mining API 2 | The Data Mining API provides resources for training, scoring, and comparing data mining models. 3 | 4 | ## API Request Examples Grouped by Object Type 5 | 6 |
    7 | Modules 8 | 9 | * [Score a model](#score-model) 10 |
    11 | 12 |
    13 | Retraining 14 | 15 | * [Download retraining sample code](#download-retraining-sample-code) 16 | * [Initiate retraining](#initiate-retraining) 17 | * [Perform batch retraining](#perform-batch-retraining) 18 | * [Set the project retrain state](#set-project-retrain-state) 19 |
    20 | 21 | 22 | #### Score a Model 23 | Here is an example of an endpoint with no HATEOAS links, but it is surfaced in the UI from the *Download Score API* action. 24 | ``` 25 | POST /dataMining/projects/9d226d3d-f719-4d7b-bf89-cee2f9088cd0/models/2aa54b31-4a9d-426b-980f-d60286cef227/scoreExecutions?holdoutDataUri=/dataTables/dataSources/cas~fs~cas~fs~DMINE/tables/HMEQ HTTP/1.1 26 | 27 | Host: example.com:80 28 | Accept: application/vnd.sas.score.execution+json 29 | ``` 30 | *Note: This POST does not require a body.* 31 | 32 | 33 | #### Download Retraining Sample Code 34 | Here is an example of an endpoint that is referenced by the link with the *batchSampleCode* relation on a data mining project. 35 | ``` 36 | GET /dataMining/projects/9d226d3d-f719-4d7b-bf89-cee2f9088cd0/retrainingSampleCode?type=sas HTTP/1.1 37 | Host: example.com:80 38 | Accept: application/vnd.sas.source.text+json 39 | ``` 40 | 41 | #### Initiate Retraining 42 | Here is an example of an endpoint that is referenced by the link with the *startRetraining* relation on a data mining project. 43 | ``` 44 | POST /dataMining/projects/9d226d3d-f719-4d7b-bf89-cee2f9088cd0/retrainJobs?dataUri=/dataTables/dataSources/cas~fs~cas~fs~DMINE HTTP/1.1 45 | Host: example.com:80 46 | Accept: application/vnd.sas.job.execution.job+json 47 | ``` 48 | *Note: This POST does not require a body.* 49 | 50 | #### Perform Batch Retraining 51 | Here is an example of an endpoint that is referenced by the link with the *startBatchRetraining* relation on a data mining project. 52 | ``` 53 | POST /dataMining/projects/9d226d3d-f719-4d7b-bf89-cee2f9088cd0/retrainJobs?action=batch&dataUri=/dataTables/dataSources/cas~fs~cas~fs~DMINE HTTP/1.1 54 | Host: example.com:80 55 | Accept: application/vnd.sas.job.execution.job+json 56 | ``` 57 | *Note: This POST does not require a body.* 58 | 59 | #### Set the Project Retrain State 60 | Here is an example of an endpoint that is referenced by the link with the *retrainingState* relation on a data mining project. 61 | 62 | ``` 63 | PUT /dataMining/projects/9d226d3d-f719-4d7b-bf89-cee2f9088cd0/retrainJobs?state=needed HTTP/1.1 64 | Host: example.com:80 65 | Accept: application/vnd.sas.analytics.project+json 66 | ``` 67 | 68 | 69 | version 5, last updated 19 NOV, 2019 70 | -------------------------------------------------------------------------------- /DecisionManagement/images/MASExampleCode.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sassoftware/devsascom-rest-api-samples/8371b14b9e354a79d8993d8eb9c87f4110708209/DecisionManagement/images/MASExampleCode.jpg -------------------------------------------------------------------------------- /DecisionManagement/images/sequence-analysis.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sassoftware/devsascom-rest-api-samples/8371b14b9e354a79d8993d8eb9c87f4110708209/DecisionManagement/images/sequence-analysis.png -------------------------------------------------------------------------------- /DecisionManagement/images/sequence-score-with-mapped-code.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sassoftware/devsascom-rest-api-samples/8371b14b9e354a79d8993d8eb9c87f4110708209/DecisionManagement/images/sequence-score-with-mapped-code.png -------------------------------------------------------------------------------- /DecisionManagement/images/sequence-score-with-score-definition.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sassoftware/devsascom-rest-api-samples/8371b14b9e354a79d8993d8eb9c87f4110708209/DecisionManagement/images/sequence-score-with-score-definition.png -------------------------------------------------------------------------------- /DecisionManagement/scoreDefinitions.md: -------------------------------------------------------------------------------- 1 | # Score Definitions API 2 | Score definitions are used by the Score Execution API to generate mapped code, which is then used to generate the score for the input data. 3 | 4 | A score definition contains the following details: 5 | 6 | 1. Input data that needs to be scored. 7 | 2. Details about the score object whose logic is used to produce a score. 8 | 3. Mappings between the input data columns and the variables of the mapped code of the score object. 9 | 10 | #### Why Use this API? 11 | * Users can test the score objects by generating and executing the code. 12 | * Users can use the definition in the score execution to score the input data. 13 | * Can be used in a consistent way for generating a score for the input data using different types of score objects like Decisions and Models. 14 | * Can be used in a consistent way for generating mapped code using different types of score objects such as decisions and models. 15 | 16 | ## API Request Examples Grouped by Object Type 17 | 18 |
    19 | Create a Score Definition 20 | 21 | * [Specifying the type of input data as a CAS table](#specifying-input-data-type-cas-table) 22 | * [Specifying the type of input data as inline](#specifying-input-data-inline) 23 | * [Specifying the type of input data as scenario](#specifying-input-data-scenario) 24 |
    25 | 26 |
    27 | Update Score Definitions 28 | 29 | * [Replacing all parts of the score definition with new data](#replacing-score-definition-new-data) 30 |
    31 | 32 |
    33 | Searching a Score Definition 34 | 35 | * [Search by name](#search-by-name) 36 | * [Search by the score object URI](#search-by-uri) 37 | * [Search by the score object type](#search-by-type) 38 |
    39 | 40 |
    41 | Getting the Mapped Code for Score Objects 42 | 43 | * [Get the mapped code for score objects](#get-mapped-code-score-objects) 44 |
    45 | 46 |
    47 | Delete a Score Definition 48 | 49 | * [Delete a score definition](#delete-score-definition) 50 |
    51 | 52 | ### Creating a Score Definition 53 | Here are some examples of creating a score definition. 54 |
    55 | 56 | #### Example 1: Specifying the Type of Input Data as a CAS Table 57 | ```json 58 | { 59 | "POST": "/definitions", 60 | "headers": { 61 | "Content-Type": "application/vnd.sas.score.definition+json", 62 | "Accept": "application/vnd.sas.score.definition+json" 63 | }, 64 | "body": { 65 | "name": "My Score Definition", 66 | "objectDescriptor": { 67 | "uri": "/businessRules/ruleSets/0d25d749-24e0-4e5d-a773-ea7a1eb0fdc5" 68 | }, 69 | "inputData": { 70 | "type": "CASTable", 71 | "serverName": "edmcas", 72 | "tableName": "BADCAR_DEMO", 73 | "libraryName": "HPS" 74 | }, 75 | "mappings": [ 76 | { 77 | "variableName": "Make", 78 | "mappingType": "datasource", 79 | "mappingValue": "make" 80 | }, 81 | { 82 | "variableName": "Model", 83 | "mappingType": "datasource", 84 | "mappingValue": "model" 85 | }, 86 | { 87 | "variableName": "Odometer", 88 | "mappingType": "datasource", 89 | "mappingValue": "vehodo" 90 | }, 91 | { 92 | "variableName": "Maximum_Mileage", 93 | "mappingType": "static", 94 | "mappingValue": 100000 95 | } 96 | ] 97 | } 98 | } 99 | ``` 100 | 101 | #### Example 2: Specifying the Type of Input Data as Inline 102 | ```json 103 | { 104 | "POST": "/definitions", 105 | "headers": { 106 | "Content-Type": "application/vnd.sas.score.definition+json", 107 | "Accept": "application/vnd.sas.score.definition+json" 108 | }, 109 | "body": { 110 | "name": "My Inline Score Definition", 111 | "objectDescriptor": { 112 | "uri": "/decisions/flows/17ee66ee-63d6-11e6-8b77-86f30ca893d3" 113 | }, 114 | "inputData": { 115 | "type": "Inline", 116 | "code": "data BADCAR_DEMO; dcl varchar(100) make; dcl varchar(100) model; dcl double vehodo;\nmethod init(); \"make\" = 'HYUNDAI'; \"model\" = 'ELANTRA'; \"vehodo\" = 108811; output;\n\"make\" = 'FORD'; \"model\" = 'FOCUS'; \"vehodo\" = 98038; output; end; enddata;", 117 | "outputTableName": "CARS" 118 | }, 119 | "mappings": [ 120 | { 121 | "variableName": "Make", 122 | "mappingType": "datasource", 123 | "mappingValue": "make" 124 | }, 125 | { 126 | "variableName": "Model", 127 | "mappingType": "datasource", 128 | "mappingValue": "model" 129 | }, 130 | { 131 | "variableName": "Odometer", 132 | "mappingType": "datasource", 133 | "mappingValue": "vehodo" 134 | }, 135 | { 136 | "variableName": "Maximum_Mileage", 137 | "mappingType": "static", 138 | "mappingValue": 100000 139 | } 140 | ] 141 | } 142 | } 143 | ``` 144 | 145 | NOTE: For clarity, the example above is shown as YAML below. 146 | 147 | ```yaml 148 | POST: "/definitions" 149 | headers: 150 | Content-Type: application/vnd.sas.score.definition+json 151 | Accept: application/vnd.sas.score.definition+json 152 | body: 153 | name: My Inline Score Definition 154 | objectDescriptor: 155 | uri: "/decisions/flows/17ee66ee-63d6-11e6-8b77-86f30ca893d3" 156 | inputData: 157 | type: Inline 158 | code: 159 | data BADCAR_DEMO; 160 | dcl varchar(100) make; 161 | dcl varchar(100) model; 162 | dcl double vehodo; 163 | 164 | method init(); 165 | "make" = 'HYUNDAI'; 166 | "model" = 'ELANTRA'; 167 | "vehodo" = 108811; 168 | output; 169 | 170 | "make" = 'FORD'; 171 | "model" = 'FOCUS'; 172 | "vehodo" = 98038; 173 | output; 174 | end; 175 | enddata; 176 | outputTableName: CARS 177 | mappings: 178 | - variableName: Make 179 | mappingType: datasource 180 | mappingValue: make 181 | - variableName: Model 182 | mappingType: datasource 183 | mappingValue: model 184 | - variableName: Odometer 185 | mappingType: datasource 186 | mappingValue: vehodo 187 | - variableName: Maximum_Mileage 188 | mappingType: static 189 | mappingValue: 100000 190 | ``` 191 | #### Example 3: Specifying the Type of Input Data as Scenario 192 | ```json 193 | { 194 | "POST": "/definitions", 195 | "headers": { 196 | "Content-Type": "application/vnd.sas.score.definition+json", 197 | "Accept": "application/vnd.sas.score.definition+json" 198 | }, 199 | "body": { 200 | "name": "My Scenario Score Definition", 201 | "objectDescriptor": { 202 | "uri": "/decisions/flows/17ee66ee-63d6-11e6-8b77-86f30ca893d3" 203 | }, 204 | "inputData": { 205 | "type": "Scenario" 206 | }, 207 | "mappings": [ 208 | { 209 | "variableName": "Make", 210 | "mappingType": "static", 211 | "mappingValue": "HYUNDAI" 212 | }, 213 | { 214 | "variableName": "Model", 215 | "mappingType": "static", 216 | "mappingValue": "ELANTRA" 217 | }, 218 | { 219 | "variableName": "Odometer", 220 | "mappingType": "static", 221 | "mappingValue": 108811 222 | }, 223 | { 224 | "variableName": "Maximum_Mileage", 225 | "mappingType": "static", 226 | "mappingValue": 100000 227 | }, 228 | { 229 | "variableName": "RejectCar", 230 | "mappingType": "expected", 231 | "mappingValue": true 232 | } 233 | ] 234 | } 235 | } 236 | ``` 237 | 238 | ### Updating a Score Definition 239 | Here is an example of replacing all parts of the score definition with new data. 240 | 241 | ```json 242 | { 243 | "PUT": "/definitions/{definitionId}", 244 | "headers": { 245 | "Content-Type": "application/vnd.sas.score.definition+json", 246 | "Accept": "application/vnd.sas.score.definition+json", 247 | "If-Match": "" 248 | }, 249 | "body": { 250 | "name": "My Score Definition", 251 | "objectDescriptor": { 252 | "uri": "/businessRules/ruleSets/0d25d749-24e0-4e5d-a773-ea7a1eb0fdc5" 253 | }, 254 | "inputData": { 255 | "type": "CASTable", 256 | "serverName": "edmcas", 257 | "tableName": "BADCAR_DEMO", 258 | "libraryName": "HPS" 259 | }, 260 | "mappings": [ 261 | { 262 | "variableName": "Make", 263 | "mappingType": "datasource", 264 | "mappingValue": "make" 265 | }, 266 | { 267 | "variableName": "Model", 268 | "mappingType": "datasource", 269 | "mappingValue": "model" 270 | }, 271 | { 272 | "variableName": "Odometer", 273 | "mappingType": "datasource", 274 | "mappingValue": "vehodo" 275 | }, 276 | { 277 | "variableName": "Maximum_Mileage", 278 | "mappingType": "static", 279 | "mappingValue": 50000 280 | } 281 | ] 282 | } 283 | } 284 | ``` 285 | 286 | ### Searching a Score Definition 287 | Here are some examples of searching a score definition. 288 | Note: Accept-Item can be application/vnd.sas.summary+json, application/vnd.sas.score.definition+json or application/vnd.sas.score.definition.summary+json 289 |
    290 | #### Example 1: Search by Name 291 | ```json 292 | { 293 | "GET": "/definitions?filter=eq(name,'')", 294 | "headers": { 295 | "Accept": "application/vnd.sas.collection+json", 296 | "Accept-Item": "application/vnd.sas.score.definition+json" 297 | } 298 | } 299 | ``` 300 | 301 | #### Example 2: Search by the Score Object URI 302 | ```json 303 | { 304 | "GET": "/definitions?filter=eq(objectDescriptor.uri,'')", 305 | "headers": { 306 | "Accept": "application/vnd.sas.collection+json", 307 | "Accept-Item": "application/vnd.sas.score.definition+json" 308 | } 309 | } 310 | ``` 311 | 312 | #### Example 3: Search by the Score Object Type 313 | ```json 314 | { 315 | "GET": "/definitions?filter=eq(objectDescriptor.type,'')", 316 | "headers": { 317 | "Accept": "application/vnd.sas.collection+json", 318 | "Accept-Item": "application/vnd.sas.score.definition+json" 319 | } 320 | } 321 | ``` 322 | 323 | ### Getting the Mapped Code for Score Objects 324 | Here is an example of getting the mapped code for score objects. 325 | ```json 326 | { 327 | "POST": "/definitions/{definitionId}/mappedCode", 328 | "headers": { 329 | "Content-Type": "application/vnd.sas.score.code.generation.request+json", 330 | "Accept": "application/vnd.sas.score.mapped.code+json" 331 | }, 332 | "body": { 333 | "hints": { 334 | "outputLibraryName": "PUBLIC" 335 | } 336 | } 337 | } 338 | ``` 339 | 340 | ### Deleting a Score Definition 341 | Here is an example of deleting a score definition/ 342 | ```json 343 | { 344 | "DELETE": "/definitions/{definitionId}" 345 | } 346 | ``` 347 | 348 | 349 | version 3, last updated 21 March 2024 -------------------------------------------------------------------------------- /DecisionManagement/viya35/businessRules_viya35.md: -------------------------------------------------------------------------------- 1 | # Business Rules API 2 | The Business Rules API manages a repository of business rules that are organized within rule sets. These rule sets enable users to perform the following actions: 3 | 4 | * create rules composed of conditions and actions 5 | * organize them into logical sets 6 | * create revisions of their rule sets 7 | * generate code to be able to leverage the rules within operational processes such as transactional web services 8 | 9 | In addition, rule sets can be included in decision flows, which can also be consumed by other operational processes. 10 | 11 | An example of a rule set and its contained rules is a loan approval where multiple rules around various aspects of the customer need to be verified within one logical set of rules as shown below: 12 | 13 | * age - if age < 18 then approved = false 14 | * geographical requirements - if isCitizen = true then approved = false 15 | * creditScore - if creditScore < 300 then approved = false 16 | 17 | #### Revisions 18 | This API enables you to not only do basic create, update, delete, and read capabilities with rule sets, but also allows users to create revisions of rule sets. Users also have the capability to delete locked revisions. However, the current unlocked version cannot be deleted. 19 | 20 | Revisions are versions of the rule set and contained rules that are associated with a major and minor number and can be locked. Once they are locked, you cannot unlock a revision for auditing purposes. The API controls the major and minor numbering of the revisions and locking. Users have control to request a major or minor revision to be created, and a new number is assigned for them based on the current revisions available. 21 | 22 | After a new version is created, any existing revision is locked to prevent multiple revisions being edited at once. The `ruleSetName` and `description` are not tracked within the revision but all other fields are tracked. 23 | 24 | #### Why Use this API? 25 | This API manages business rules and retrieves the code to be able to leverage the rules within an operational process. 26 | 27 | ## API Request Examples 28 | 29 | * [Create a rule set](#create-rule-set) 30 | * [Get a rule set](#get-rule-set) 31 | * [Delete a rule set](#delete-rule-set) 32 | * [Get the collection of rule sets](#get-collection-rule-sets) 33 | * [Add a rule to a rule set](#add-rule-to-rule-set) 34 | * [Add a rule referencing a lookup in a condition to a rule set](#add-rule-ref-lookup-condition-rule-set) 35 | * [Update the ordering of rules within a rule set](#update-ordering-rules-rule-set) 36 | * [Delete a rule from a rule set](#delete-rule-from-rule-set) 37 | * [Create a minor revision of the rule set](#create-revision-rule-set) 38 | * [Convert a rule action](#convert-rule-action) 39 | * [Convert a rule condition](#convert-rule-condition) 40 | 41 | #### Create a Rule Set 42 | 43 | Here is an example of how to create a rule set. 44 | 45 | ```json 46 | { 47 | "POST": "/businessRules/ruleSets", 48 | "headers": { 49 | "Content-Type": "application/vnd.sas.business.rule.set+json", 50 | "Accept": "application/vnd.sas.business.rule.set+json" 51 | }, 52 | "body": { 53 | "name": "Cost Categorization", 54 | "ruleSetType": "assignment", 55 | "description": "Determine cost categorization for vehicle", 56 | "signature": [ 57 | { 58 | "name": "vehicleCost", 59 | "dataType": "decimal", 60 | "direction": "input" 61 | }, 62 | { 63 | "name": "model", 64 | "dataType": "string", 65 | "direction": "input", 66 | "length": 100, 67 | "defaultValue": "FORD" 68 | }, 69 | { 70 | "name": "accidents", 71 | "dataType": "dataGrid", 72 | "direction": "input", 73 | "dataGridExtension": [ 74 | { 75 | "name": "accidentType", 76 | "dataType": "string", 77 | "length": 100 78 | }, 79 | { 80 | "name": "repairCost", 81 | "dataType": "decimal" 82 | } 83 | ] 84 | }, 85 | { 86 | "name": "isHighCost", 87 | "dataType": "boolean", 88 | "direction": "output" 89 | }, 90 | { 91 | "name": "hasDocumentedPricing", 92 | "dataType": "boolean", 93 | "direction": "output" 94 | } 95 | ] 96 | } 97 | } 98 | ``` 99 |
    100 | 101 | #### Get a Rule Set 102 | 103 | Here is an example of how to get a rule set. 104 | 105 | ```json 106 | { 107 | "GET": "/businessRules/ruleSets/{ruleSetId}", 108 | "headers": { 109 | "Accept": "application/vnd.sas.business.rule.set+json" 110 | } 111 | } 112 | ``` 113 |
    114 | 115 | #### Delete a Rule Set 116 | 117 | Here is an example of how to delete a rule set. 118 | 119 | ```json 120 | { 121 | "DELETE": "/businessRules/ruleSets/{ruleSetId}" 122 | } 123 | ``` 124 |
    125 | 126 | #### Get the Collection of Rule Sets 127 | 128 | Here is an example of how to get the collection of rule sets. 129 | 130 | ```json 131 | { 132 | "GET": "/businessRules/ruleSets", 133 | "headers": { 134 | "Accept": "application/vnd.sas.collection+json" 135 | } 136 | } 137 | ``` 138 |
    139 | 140 | #### Add a Rule to a Rule Set 141 | 142 | Here is an example of how to add a rule to a rule set. 143 | 144 | ```json 145 | { 146 | "POST": "/businessRules/ruleSets/{ruleSetId}/rules", 147 | "headers": { 148 | "Content-Type": "application/vnd.sas.business.set+json", 149 | "Accept": "application/vnd.sas.business.set+json" 150 | }, 151 | "body": { 152 | "name": "Vehicle Categorization", 153 | "description": "Look at vehicle cost to determine category", 154 | "ruleFiredTrackingEnabled": true, 155 | "conditional": "if", 156 | "conditions": [ 157 | { 158 | "term": { 159 | "name": "vehicleCost" 160 | }, 161 | "expression": "> 15000", 162 | "type": "decisionTable" 163 | } 164 | ], 165 | "actions": [ 166 | { 167 | "term": { 168 | "name": "isHighCost" 169 | }, 170 | "expression": " true ", 171 | "type": "assignment" 172 | } 173 | ] 174 | } 175 | } 176 | ``` 177 |
    178 | 179 | #### Add a Rule Referencing a Lookup in a Condition to a Rule Set 180 | 181 | Here is an example of how to add a rule referencing a lookup in a condition to a rule set. 182 | 183 | ```json 184 | { 185 | "POST": "/businessRules/ruleSets/{ruleSetId}/rules", 186 | "headers": { 187 | "Content-Type": "application/vnd.sas.business.set+json", 188 | "Accept": "application/vnd.sas.business.set+json" 189 | }, 190 | "body": { 191 | "name": "Vehicle Categorization", 192 | "description": "Look at vehicle cost to determine category", 193 | "ruleFiredTrackingEnabled": true, 194 | "conditional": "if", 195 | "conditions": [ 196 | { 197 | "term": { 198 | "name": "model" 199 | }, 200 | "lookup": { 201 | "id": "50ef4e9d-2127-4560-8ab2-7ef11a7fb1af" 202 | }, 203 | "type": "lookup" 204 | } 205 | ], 206 | "actions": [ 207 | { 208 | "term": { 209 | "name": "hasDocumentedPricing" 210 | }, 211 | "expression": "true", 212 | "type": "assignment" 213 | } 214 | ] 215 | } 216 | } 217 | ``` 218 |
    219 | 220 | #### Update the Ordering of Rules within a Rule Set 221 | 222 | Here is an example of how to update the ordering of rules within a rule set. 223 | 224 | ```json 225 | { 226 | "PUT": "/businessRules/ruleSets/{ruleSetId}/order", 227 | "headers": { 228 | "Content-Type": "application/vnd.sas.selection+json", 229 | "Accept": "application/vnd.sas.selection+json", 230 | "If-Unmodified-Since" : "Mon, 07 Aug 2017 12:57:52 GMT" 231 | }, 232 | "body": { 233 | "type": "id", 234 | "template": "/businessRules/ruleSets/6c91ee3c-110e-4599-8224-45e29f34ad55/rules/{id}", 235 | "resources": [ 236 | "6b2b4721-c0ca-4d66-ab4d-d0732fc5266a", 237 | "a0e9bdc9-659e-4419-852c-083d270e2ea8", 238 | "e51ca7ed-2232-482d-9b8d-1432f87f5f12", 239 | "83a16244-3be2-415b-a8f1-4b261cd7cf27" 240 | ] 241 | } 242 | 243 | } 244 | ``` 245 |
    246 | 247 | #### Delete a Rule from a Rule Set 248 | 249 | Here is an example of how to delete a rule from a rule set. 250 | 251 | ```json 252 | { 253 | "DELETE": "/businessRules/ruleSets/{ruleSetId}/rules/{ruleId}" 254 | } 255 | ``` 256 |
    257 | 258 | #### Create a Minor Revision of the Rule Set 259 | 260 | Here is an example of how to create a minor revision of the rule set. 261 | 262 | ```json 263 | { 264 | "POST": "/businessRules/ruleSets/{ruleSetId}/revisions?revisionType=minor", 265 | "headers": { 266 | "Content-Type": "application/vnd.sas.business.rule.set+json", 267 | "Accept": "application/vnd.sas.business.rule.set+json" 268 | }, 269 | "body": { 270 | "name": "Cost Categorization", 271 | "description": "Determine cost categorization for vehicle", 272 | "signature": [ 273 | { 274 | "name": "vehicleCost", 275 | "dataType": "decimal", 276 | "direction": "input" 277 | }, 278 | { 279 | "name": "isHighCost", 280 | "dataType": "boolean", 281 | "direction": "output" 282 | } 283 | ] 284 | } 285 | } 286 | ``` 287 |
    288 | 289 | #### Convert a Rule Action 290 | 291 | Here is an example of how to convert a rule action to a different target type. 292 | 293 | ```json 294 | { 295 | "POST": "/businessRules/ruleSets/{ruleSetId}/actionConversion", 296 | "headers": { 297 | "Content-Type": "application/vnd.sas.business.rule.action.conversion+json", 298 | "Accept": "application/vnd.sas.business.rule.action+json" 299 | }, 300 | "body": { 301 | "source": { 302 | "term": { 303 | "creationTimeStamp": "2017-06-14T17:12:20.148Z", 304 | "modifiedTimeStamp": "2017-06-14T17:12:48.933Z", 305 | "createdBy": "sasdemo", 306 | "modifiedBy": "sasdemo", 307 | "id": "6bd1bd30-f260-42bc-532c-fb834ef2dffa", 308 | "name": "approved", 309 | "dataType": "decimal", 310 | "direction": "output" 311 | }, 312 | "expression": "0", 313 | "status": "valid", 314 | "id": "1c762292-6203-405a-8e1d-45aa899314b2", 315 | "type": "assignment" 316 | }, 317 | "targetType": "complex" 318 | } 319 | } 320 | ``` 321 |
    322 | 323 | #### Convert a Rule Condition 324 | 325 | Here is an example of how to convert a rule condition to a different target type. 326 | 327 | ```json 328 | { 329 | "POST": "/businessRules/ruleSets/{ruleSetId}/conditionConversion", 330 | "headers": { 331 | "Content-Type": "application/vnd.sas.business.rule.condition.conversion+json", 332 | "Accept": "application/vnd.sas.business.rule.condition+json" 333 | }, 334 | "body": { 335 | "source": { 336 | "term": { 337 | "creationTimeStamp": "2017-06-14T17:12:20.117Z", 338 | "modifiedTimeStamp": "2017-06-14T17:12:48.914Z", 339 | "createdBy": "sasdemo", 340 | "modifiedBy": "sasdemo", 341 | "id": "94591e7b-7b7d-4efa-9c60-b2c3a00d7739", 342 | "name": "age", 343 | "dataType": "decimal", 344 | "direction": "input" 345 | }, 346 | "expression": "< 18", 347 | "status": "valid", 348 | "id": "0b9a512e-5134-4bd3-93ab-63fedde9d98a", 349 | "type": "decisionTable" 350 | }, 351 | "targetType": "complex" 352 | } 353 | } 354 | ``` 355 |
    356 | 357 | version 5, last updated on 29 October, 2024 358 | 359 | 360 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SAS REST API Examples - SAS Viya Preview 2 | ## Overview 3 | This is a preview repository containing examples showing the capabilities of SAS REST APIs. You can use these examples for learning or for validating your environment. If you have comments or see needed corrections, please open an issue in GitHub. 4 | 5 | The APIs are group into the following categories: 6 | 7 | | API Category | Description | 8 | | ------ | ------ | 9 | | Visualization | Provide access to reports and report images | 10 | | Compute | Act on SAS compute and analytic servers, including Cloud Analytic Services (CAS) | 11 | | Text Analytics | Provide analysis and categorization of text documents | 12 | | Data Management | Enable data manipulation and data quality operations on data sources | 13 | | Decision Management | Provide access to machine scoring and business rules | 14 | | Core Services | Provide operations for shared resources such as files and folders | 15 | 16 | Within each grouping will be a folder for SAS and User contributions (we encourage external participation). 17 | 18 | 19 | ## Installation/Usage 20 | The examples in this repository offer sample REST API calls, including valid http methods, headers, and body content, where applicable. Sample responses are also included. Requests are submitted by standard REST call methods: Postman, cURL, application code, etc. 21 | 22 | ## [](#contributing)Contributing 23 | 24 | We welcome your contributions! Please read [CONTRIBUTING.md](https://github.com/sassoftware/devsascom-rest-api-samples/blob/master/CONTRIBUTING.md) for details on how to submit contributions to this project. 25 | 26 | ## [](#license)License 27 | 28 | This project is licensed under the [Apache 2.0 License](https://github.com/sassoftware/devsascom-rest-api-samples/blob/master/LICENSE). 29 | 30 | ## Additional Resources 31 | - [developer.sas.com](https://developer.sas.com/home.html)- the SAS developer portal that contains a comprensive list of our REST APIs and their documentation. 32 | - [Developers Community](https://communities.sas.com/t5/Developers/bd-p/developers)- provides a forum for collaboration, Q&A, and knowledge and resource sharing for SAS integration with open source technologies 33 | - [support.sas.com](https://support.sas.com/en/support-home.html)- SAS support web site incorperating documentation, technical support, customer news, tips and tricks 34 | - [blog articles for developers](https://blogs.sas.com/content/tag/developers/)- SAS blog articles geared towards developers 35 | - [blog articles for SAS REST APIs](https://blogs.sas.com/content/tag/rest-apis/)- SAS blog articles specifically covering SAS REST APIs and their usage 36 | 37 | -------------------------------------------------------------------------------- /TextAnalytics/README.md: -------------------------------------------------------------------------------- 1 | # SAS REST API Examples 2 | 3 | ## Text Analytics 4 | 5 | This repository contains SAS contributed examples that show the capabilities of the Text Analytics REST APIs. You can use these examples for learning or for validating your environment. 6 | 7 | You are encouraged to contribute your own examples in the [User Contributions repository](../User_and_Aggregated_Samples). 8 | 9 | ## Examples 10 | 11 | * [Categorization](categorization.md) 12 | * [Concepts](concepts.md) 13 | * [Sentiment Analysis](sentimentAnalysis.md) 14 | * [Text Parsing](textParsing.md) 15 | * [Topics](topics.md) 16 | -------------------------------------------------------------------------------- /User_and_Aggregated_Samples/SAS/README.md: -------------------------------------------------------------------------------- 1 | # SAS REST API Examples 2 | ## Overview 3 | This folder contains subfolder with examples of using the SAS® Viya REST API using SAS Code. You can use these examples for learning or for validating your environment. You are encouraged to contribute your own examples. 4 | -------------------------------------------------------------------------------- /User_and_Aggregated_Samples/SAS/create-va-svg-img/README.md: -------------------------------------------------------------------------------- 1 | One of the most useful features of the [SAS® Viya REST API](https://developer.sas.com/rest-apis/) is the ability to leverage the reportImages service to generate SVG images of Visual Analytics Report(s). This is particularly useful for SAS developers who are making updates to a report's data source(s) and would like to get a quick view of how these data changes are reflected in Visual Analytics. More information on the reportImages service can be found on [developer.sas.com](https://developer.sas.com/rest-apis/reportImages) 2 | 3 | The SAS code in this folder uses the reportImages service to programmatically open a Visual Analytics report and generate an SVG image from it. When the program finishes the SVG image is automatically displayed in SAS Studio's results tab. This allows the SAS developer to instantly get a view of the Visual Analytics report's current state. 4 | 5 | ![](./create_VA_svg_image.png) 6 | 7 | The image above shows an SVG image of a SAS Visual Analytics report (created via the reportImages service) presented in the SAS Studio results tab. 8 | 9 | Code Prerequisites: 10 | 11 | * All code included in this folder must be submitted in a SAS Studio 5.1 (or later) session within a Viya 3.4 (or later) environment which contains the SAS Viya services that are being called. 12 | * The Visual Analytics Report's URI must be placed in the macro call at the bottom of the code 13 | * example: %create_VA_svg_image(/reports/reports/9d9d1a82-1e39-4284-a278-c3a05388ea72) 14 | * All of the report's data sources are currently available in memory 15 | 16 | Notes: 17 | * This code by default creates an SVG image with dimensions of 800x600. This default size can be changed by placing different values in the two %let statements at the top of the code. 18 | * By default, the reportImages service renders an SVG image of the first tab in a Visual Analytics report. If you would like to create an SVG image of a different tab you can do so by adding the sectionIndex parameter to the API call. More information on the reportImages service parameters can be found on [developer.sas.com](https://developer.sas.com/rest-apis/reportImages) 19 | -------------------------------------------------------------------------------- /User_and_Aggregated_Samples/SAS/create-va-svg-img/create-va-svg-img.sas: -------------------------------------------------------------------------------- 1 | /******************************************************************************\ 2 | * Copyright 2019 SAS Institute Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | * Author: Michael Drutar 17 | * 18 | * Input: The desired image width and height of the SVG image. 19 | * The internal report id (UID) of the Visual Analytics report that the 20 | * SVG image will created from (this is placed in the macro call at the 21 | * bottom of this program). 22 | * 23 | * Output: SVG Image file displayed in the SAS Studio Results window 24 | * 25 | * All code included in this section must be submitted in a SAS Studio 5.1 (or later) 26 | * session within a Viya 3.4 (or later) environment which contains the SAS Viya services 27 | * that are being called. 28 | \******************************************************************************/ 29 | 30 | 31 | 32 | /* Input desired image width and height */ 33 | %let width=800; 34 | %let height=600; 35 | 36 | %macro create_VA_svg_image(report_uri); 37 | 38 | * Base URI for the service call; 39 | %let BASE_URI=%sysfunc(getoption(servicesbaseurl)); 40 | 41 | /* -------------------------------------------------------------- */ 42 | /* Step 1 - Create a job */ 43 | /* -------------------------------------------------------------- */ 44 | 45 | /* Create input for the job request */ 46 | data create_params; 47 | request_params = "'" || trim('{"reportUri" : "') || "&report_uri" || trim('","layoutType" : "entireSection","refresh":false,"selectionType" : "report","size" : "' || "&width" || 'x' || "&height" || '","version" : 1}' || "'"); 48 | call symput('request_params',request_params); 49 | run; 50 | 51 | /* create filenames to hold responses*/ 52 | filename startjob temp; 53 | filename resp_hdr temp; 54 | 55 | /* Make request */ 56 | proc http 57 | method="POST" 58 | oauth_bearer=sas_services 59 | url="&BASE_URI/reportImages/jobs" 60 | ct="application/vnd.sas.report.images.job.request+json" 61 | in=&request_params. 62 | /* place response in filenames */ 63 | out=startjob 64 | headerout=resp_hdr 65 | headerout_overwrite; 66 | 67 | run; 68 | 69 | /* Use JSON LIBNAME engine to read in response */ 70 | libname startjob json; 71 | 72 | /* capture the job id for step 2 */ 73 | data _NULL_; 74 | set startjob.root; 75 | call symputx('job_id',id); 76 | run; 77 | 78 | /* -------------------------------------------------------------- */ 79 | /* Step 2 - Retrieve job status & duration (In a Macro!) */ 80 | /* -------------------------------------------------------------- */ 81 | 82 | %let status=0; 83 | %macro jobstatus; 84 | %do %until (&status ne 0); 85 | /* clear filenames and libname librefs if they exist*/ 86 | %if %sysfunc(fexist(res_hdr)) = 1 %then %do; 87 | filename res_hdr clear; 88 | %end; 89 | %if %sysfunc(fexist(j_status)) = 1 %then %do; 90 | filename j_status clear; 91 | libname j_status clear; 92 | %end; 93 | /* assign filenames */ 94 | filename j_status temp; 95 | filename res_hdr temp; 96 | /* Make request */ 97 | proc http 98 | method="GET" 99 | oauth_bearer=sas_services 100 | url="&BASE_URI/reportImages/jobs/&job_id" 101 | out=j_status 102 | headerout=res_hdr 103 | headerout_overwrite; 104 | run; 105 | 106 | /* Read response */ 107 | libname j_status json; 108 | /* Determine state and reset status */ 109 | data job_status; 110 | set j_status.root; 111 | if state = 'running' then status = 0; 112 | else if state = 'completed' then status = 1; 113 | call symputx('status',status); 114 | run; 115 | 116 | /* Wait one second */ 117 | data _NULL_; 118 | time_slept=sleep(1,1); 119 | run; 120 | 121 | %end; 122 | %mend jobstatus; 123 | /*call the macro*/ 124 | %jobstatus; 125 | 126 | /* ---------------------------------------------------------------------- */ 127 | /* Step 3 - Display the generated SVG image within the results window */ 128 | /* ---------------------------------------------------------------------- */ 129 | 130 | /* retrieve image url */ 131 | data _NULL_; 132 | set j_status.Images_links(obs = 1); 133 | call symput('image_link',compress(href)); 134 | run; 135 | 136 | /* create dataset to display image */ 137 | data showImage; 138 | Url_Link = ''; 139 | RUN; 140 | 141 | /* Display the Image */ 142 | title1 'An SVG image file of the requested report is below!'; 143 | proc report data=WORK.showImage nowd noheader; 144 | column Url_Link; 145 | run; 146 | %mend create_VA_svg_image; 147 | 148 | 149 | 150 | /* -------------------------------------------------------------- */ 151 | /* Create and View SVG Image */ 152 | /* -------------------------------------------------------------- */ 153 | 154 | /* place your report uri in the macro call below: */ 155 | /* example: %create_VA_svg_image(/reports/reports/9d9d1a82-1e39-4284-a278-c3a05388ea72) */ 156 | %create_VA_svg_image(<- report URI ->) 157 | -------------------------------------------------------------------------------- /User_and_Aggregated_Samples/SAS/create-va-svg-img/create_VA_svg_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sassoftware/devsascom-rest-api-samples/8371b14b9e354a79d8993d8eb9c87f4110708209/User_and_Aggregated_Samples/SAS/create-va-svg-img/create_VA_svg_image.png -------------------------------------------------------------------------------- /VisualInvestigator/README.md: -------------------------------------------------------------------------------- 1 | # SAS REST API Examples 2 | 3 | ## Visual Investigator 4 | 5 | This repository contains SAS contributed examples that show the capabilities of the SAS Visual Investigator REST APIs. You can use these examples for learning or for validating your environment. 6 | 7 | You are encouraged to contribute your own examples in the [User Contributions repository](../User_and_Aggregated_Samples). 8 | 9 | ## Examples 10 | _**Note:** These examples are for the latest release of SAS Viya 3.5._ 11 | 12 | * [Search and Discovery](viSearchAndDiscovery.md) 13 | * [Workflow](viWorkflow.md) 14 | 15 | For more information, see the [SAS Visual Investigator REST API](https://developer.sas.com/apis/vi/rest/VisualInvestigator/) documentation. 16 | -------------------------------------------------------------------------------- /Visualization/README.md: -------------------------------------------------------------------------------- 1 | # SAS REST API Examples 2 | 3 | ## Visualization and Reports 4 | 5 | This repository contains SAS contributed examples that show the capabilities of the Visualization REST APIs. You can use these examples for learning or for validating your environment. 6 | 7 | You are encouraged to contribute your own examples in the [User Contributions repository](../User_and_Aggregated_Samples). 8 | 9 | ## Examples 10 | 11 | * [Report Images](reportImages.md) 12 | * [Report Transforms](reportTransforms.md) 13 | -------------------------------------------------------------------------------- /Visualization/error-codes.md: -------------------------------------------------------------------------------- 1 | #### Levels of Severity 2 | 3 | **Fatal Errors** 4 | 5 | For errors from which there is no recovery, or for errors that are caused 6 | by unexpected system problems, the API uses the standard error response 7 | type to propagate error messages and codes to the client: 8 | `application/vnd.sas.error`. 9 | 10 | The same response occurs when the request parameters or body 11 | cannot be processed by Spring prior to the service code being called. 12 | Fatal errors return immediately to the client with a 400 or 500 level 13 | `application/vnd.sas.error` response. 14 | 15 | **Severe Errors** 16 | 17 | Not all error codes are returned as `application/vnd.sas.error`. Many 18 | are caught and recorded, but do not immediately halt the transformation. 19 | This permits a response of type `application/vnd.sas.report.transform` 20 | and getting information about the problem. 21 | 22 | A typical case is when there are mismatches between variables in 23 | original and replacement data sources. Each mismatch by itself prevents 24 | the overall transform from being completed, but processing must continue 25 | because the application wants to know about all the errors in the 26 | response. In this case, the error code is returned with a localized 27 | message in the transform's "`errorMessages`" list, which lets the 28 | application interpret the error codes. 29 | 30 | Severe errors do prevent the transformation from completing. For 31 | example, if columns cannot be matched when creating `dataMappedReports`, 32 | the response transform's BIRD report will not be altered, or, if the 33 | result was supposed to be saved to a new BIRD report, nothing will be 34 | persisted. 35 | 36 | Schema validation errors and warnings do not necessarily stop processing 37 | of the transform. If the process can continue, it will; but generally, 38 | if the client requires processing a report that is not schema-valid, it 39 | should override the query parameter "`validate=false`" to cause the 40 | process to skip validation entirely. 41 | 42 | 43 | 44 | **Problems** 45 | 46 | Questionable values or situations in the report are recorded in the 47 | response transform's `messages` list. If the transform action is to 48 | create semantic evaluation, this is where to look for individual 49 | problems. These messages have an error code value of zero. 50 | 51 | #### Error Code Table 52 | 53 | Errors are grouped by functional area. Some of the errors are shared 54 | by endpoints that use common platform services. 55 | 56 | | HTTP Status Code |Error Code | Resource(s) |Description |Severity | 57 | |----------------|-----------|--------------------|----------------------------------------------------------------------|--------------------------| 58 | | 200(+msgs) | 27505 | dataMappedReports | Data: Cannot change the data source as specified. | Severe: Result returned, but left unchanged.| 59 | | 200(+msgs) | 27506 | dataMappedReports | Data: Cannot obtain data service executor | Severe | 60 | | 200(+msgs) | 27507 | dataMappedReports | Data: Cannot obtain data service executor | Severe | 61 | | 200(+msgs) | 27508 | dataMappedReports | Data: Failure in getting metadata about replacement table. | Severe: Usually means the replacement table doesn't exist. | 62 | | 200(+msgs) | 27510 | dataMappedReports | Data: No replacement data source was specified. | Fatal: No attempt was made to change anything. | 63 | | 200(+msgs) | 27511 | dataMappedReports | Data: One or more source columns could not be matched to a replacement. | Severe | 64 | | 200(+msgs) | 27512 | dataMappedReports | Data: Original and replacement column names do not match. | Severe | 65 | | 200(+msgs) | 27513 | dataMappedReports | Data: Original column usage conflicts with replacement column usage attribute.| Severe | 66 | | 200(+msgs) | 27515 | dataMappedReports | Data: Transform data change parameters are inconsistent. | Severe | 67 | | 200(+msgs) | 27532 | dataMappedReports, translationworksheets | Report repository: Invalid folder URI for writing result report. | Severe: Changes to transform may have happened but report content was not saved. | 68 | | 200(+msgs) | 27533 | dataMappedReports, translationworksheets| Report repository: Invalid report URI | Severe: Changes to transform may have happened, but report content persistence failed | 69 | | 200(+msgs) | 27540 | ALL | Schema: Report failed schema validation | Severe. Validation completed. See the messages. | 70 | | 200(+msgs) | 27541 | ALL | Schema: XML Schema processing failed or schema not found | Severe. Validation was skipped, but other processing continued. | 71 | | 200(+msgs) | 27541 | translatedReports | The requested localization not present in report | Severe | 72 | | 200(+msgs) | 27560 | translationWorksheets | Worksheet: empty or otherwise invalid worksheet content | Severe | 73 | | 400 | 27509 | dataMappedReports | Data: Invalid combination of original and replacement data sources. | Fatal | 74 | | 400 | 27514 | dataMappedReports | Data: The replacement data source specified was not found. | Fatal | 75 | | 400 | 27534 | convertedReports | Report: converting between XML and JSON formats failed. | Fatal | 76 | | 400 | 27535 | ALL | Report: Input BIRD report content is invalid. | Fatal | 77 | | 400 | 27537 | dataMappedReports, translationworksheets, translatedReports | Report content is not present in transform. | Fatal | 78 | | 400 | 27570 | rethemedReports | The specified report theme does not exist. | Fatal | 79 | | 409,412,428 | 27561 | translationWorksheets | Worksheet: Update failed because report has changed or precondition omitted or precondition incorrect | Fatal | 80 | | 500, 403 | 27530 | dataMappedReports, translationworksheets | Report repository: content read failed. | Fatal | 81 | | 500, 403 | 27531 | dataMappedReports, translationworksheets, translatedReports| Report repository: content write failed. | Fatal | 82 | | 500 | 27536 | ALL | Report: JSON content serialization or deserialization failed. | Fatal | 83 | | 500 | 27550 | translatedReports | Translation failure with unknown cause. | Fatal | -------------------------------------------------------------------------------- /Visualization/reportImages.md: -------------------------------------------------------------------------------- 1 | # Report Images API 2 | The Report Images service delivers SVG images that represent either an 3 | entire report or elements of a report. Clients that present a view of 4 | the folder structure or thumbnails of a report are candidates for using 5 | this service. 6 | 7 | For example, you want to produce an image that is representative of an 8 | entire report. You create a job which returns 'state==running'. Then you 9 | poll (following the "self" link) until the job is completed. When 10 | completed, the job returns a URI, which is then passed to the browser 11 | for rendering. 12 | 13 | By default a single image that represents the report is produced at the 14 | requested size. This is equivalent to the option selectionType=report. 15 | To create one image per section, specify selectionType=perSection. 16 | ## API Request Examples Grouped by Object Type 17 |
    18 | Root 19 | 20 | * [Discover top level links for reportImages service (non-admin user)](#top-level-links) 21 |
    22 | 23 |
    24 | Jobs 25 | 26 | * [Create simple job, single image for the report](#create-simple-job) 27 | * [Poll for job completion, 10 second timeout](#poll-for-job-completion) 28 | * [Create job, one image per section](#create-job-per-section) 29 | * [Create job, entire section, using request parameters](#create-job-entire-section) 30 | * [Create job, entire section, all sections, render limit](#create-job-all-sections) 31 |
    32 | 33 |
    34 | SVG Images 35 | 36 | * [Getting an image](#getting-an-image) 37 |
    38 | 39 | 40 | 41 | ### Discover top level links for reportImages service (non-admin user) 42 | 43 | **Request** 44 | ``` 45 | GET http://www.example.com/reportImages/ 46 | Headers: 47 | * Accept = application/vnd.sas.api+json 48 | ``` 49 | 50 | 51 | **Response** 52 | ``` 53 | Status: 200 54 | Headers: 55 | * Content-Type = application/vnd.sas.api+json 56 | Body: 57 | { 58 | "version": 1, 59 | "links": [ 60 | { 61 | "method": "POST", 62 | "rel": "createJob", 63 | "href": "/reportImages/jobs", 64 | "uri": "/reportImages/jobs", 65 | "type": "application/vnd.sas.report.images.job.request", 66 | "responseType": "application/vnd.sas.report.images.job" 67 | }, 68 | { 69 | "method": "POST", 70 | "rel": "createJobWithParameters", 71 | "href": "/reportImages/jobs", 72 | "uri": "/reportImages/jobs", 73 | "responseType": "application/vnd.sas.report.images.job" 74 | } 75 | ] 76 | } 77 | ``` 78 | 79 | 80 | ### Create simple job, single image for the report. 81 | 82 | **Request** 83 | ``` 84 | POST http://www.example.com/reportImages/jobs 85 | Headers: 86 | * Accept = application/vnd.sas.report.images.job+json 87 | * Content-Type = application/vnd.sas.report.images.job.request+json 88 | Body: 89 | { 90 | "reportUri" : "/reports/reports/d32f...", 91 | "layoutType" : "normal", 92 | "selectionType" : "report", 93 | "size" : "400x300", 94 | "version" : 1 95 | } 96 | ``` 97 | 98 | **Response** 99 | This assumes the job completes within the timeout. (IDs have been shortened for readability.) 100 | ``` 101 | Status: 201 102 | Headers: 103 | * Content-Type = application/vnd.sas.report.images.job+json 104 | * Location = /reportImages/jobs/f820... 105 | Body: 106 | { 107 | "id": "f820...", 108 | "version": 1, 109 | "links": [ 110 | { 111 | "method": "GET", 112 | "rel": "self", 113 | "href": "/reportImages/jobs/f820...", 114 | "uri": "/reportImages/jobs/f820...", 115 | "type": "application/vnd.sas.report.images.job" 116 | }, 117 | { 118 | "method": "GET", 119 | "rel": "state", 120 | "href": "/reportImages/jobs/f820.../state", 121 | "uri": "/reportImages/jobs/f820.../state", 122 | "type": "text/plain" 123 | }, 124 | { 125 | "method": "POST", 126 | "rel": "renderAll", 127 | "href": "/reportImages/jobs?selectionType=report&size=400x300&reportUri=/reports/reports/d32f...&layoutType=normal", 128 | "uri": "/reportImages/jobs?selectionType=report&size=400x300&reportUri=/reports/reports/d32f...&layoutType=normal", 129 | "type": "application/vnd.sas.report.images.job" 130 | } 131 | ], 132 | "state": "completed", 133 | "duration": 0.114, 134 | "creationTimeStamp": "2017-07-17T17:20:42.647Z", 135 | "images": [ 136 | { 137 | "sectionIndex": 0, 138 | "sectionName": "vi6", 139 | "sectionLabel": "Page 1", 140 | "elementName": "ve40", 141 | "visualType": "pie", 142 | "size": "400x300", 143 | "state": "completed", 144 | "links": [ 145 | { 146 | "method": "GET", 147 | "rel": "image", 148 | "href": "/reportImages/images/K1380786238B1359240829.svg", 149 | "uri": "/reportImages/images/K1380786238B1359240829.svg", 150 | "type": "image/svg+xml" 151 | }, 152 | { 153 | "method": "POST", 154 | "rel": "render", 155 | "href": "/reportImages/jobs?selectionType=visualElements&size=400x300&reportUri=/reports/reports/d32f...&layoutType=normal&visualElementNames=ve40", 156 | "uri": "/reportImages/jobs?selectionType=visualElements&size=400x300&reportUri=/reports/reports/d32f...&layoutType=normal&visualElementNames=ve40", 157 | "type": "application/vnd.sas.report.images.job" 158 | }, 159 | { 160 | "method": "POST", 161 | "rel": "resize", 162 | "href": "/reportImages/jobs?selectionType=visualElements&reportUri=/reports/reports/d32f...&layoutType=normal&visualElementNames=ve40&size={size}", 163 | "uri": "/reportImages/jobs?selectionType=visualElements&reportUri=/reports/reports/d32f...&layoutType=normal&visualElementNames=ve40&size={size}", 164 | "type": "application/vnd.sas.report.images.job" 165 | } 166 | ] 167 | } 168 | ] 169 | } 170 | ``` 171 | 172 | 173 | **ALTERNATE response** 174 | This assumes the job does NOT complete within the timeout. 175 | ``` 176 | Status: 202 177 | Headers: 178 | * Content-Type = application/vnd.sas.report.images.job+json 179 | * Location = /reportImages/jobs/f196... 180 | Body: 181 | { 182 | "id": "f196...", 183 | "version": 1, 184 | "links": [ 185 | {"self"... }, 186 | {"state"... }, 187 | {"renderAll"... } 188 | ], 189 | "state": "running", 190 | "creationTimeStamp": "2017-07-17T17:24:23.779Z" 191 | } 192 | ``` 193 | 194 | ### Poll for job completion, 10 second timeout 195 | 196 | **Request** 197 | ``` 198 | GET http://www.example.com/reportImages/jobs/b593...?wait=10.0 199 | Headers: 200 | * Accept = application/vnd.sas.report.images.job+json 201 | ``` 202 | 203 | **Response** 204 | (assuming complete by now, otherwise state = "running"...) 205 | Key differences: 206 | 207 | * state==completed 208 | 209 | * each image (just 1 here) has link "image". 210 | 211 | (Output is the same as the 201 status example above, except that status = 200.) 212 | 213 | 214 | ### Create job 215 | One image per section at 200x300; delay up to 300 mSec before returning. 216 | 217 | **Request** 218 | ``` 219 | POST http://www.example.com/reportImages/jobs?wait=0.3 220 | Headers: 221 | * Accept = application/vnd.sas.report.images.job+json 222 | * Content-Type = application/vnd.sas.report.images.job.request+json 223 | Body: 224 | { 225 | "reportUri" : "/reports/reports/d32f...", 226 | "layoutType" : "thumbnail", 227 | "selectionType" : "perSection", 228 | "size" : "200x300", 229 | "version" : 1 230 | } 231 | ``` 232 | 233 | ### Entire Section 234 | Render the 1st entire section, using request parameters. Other sections could be specified using parameter `sectionIndex`. Use form taking request parameters rather than a body. 235 | 236 | **Request** 237 | ``` 238 | POST http://www.example.com/reportImages/jobs?layoutType=entireSection&selectionType=report&size=800x1200&wait=30&reportUri=/reports/reports/d32f...&wait=20 239 | Headers: 240 | * Accept = application/vnd.sas.report.images.job+json 241 | ``` 242 | 243 | ### First Section, metadata and links for other sections 244 | Similar to above, but request all sections with a render limit of 1. (This example uses the request body approach.) This request also uses the `refresh` option which bypasses all caches and forcibly generates a new image. 245 | 246 | ``` 247 | POST http://www.example.com/reportImages/jobs 248 | Headers: 249 | * Accept = application/vnd.sas.report.images.job+json 250 | * Content-Type = application/vnd.sas.report.images.job.request+json 251 | Body: 252 | { 253 | "reportUri" : "/reports/reports/d32f...", 254 | "layoutType" : "entireSection", 255 | "selectionType" : "perSection", 256 | "size" : "800x1200", 257 | "renderLimit" : 1, 258 | "sectionIndex" : 0, 259 | "refresh" : true, 260 | "version" : 1 261 | } 262 | ``` 263 | 264 | ### Getting an image 265 | **Request** 266 | 267 | The URL below comes from the `image` link in the _completed_ example above. 268 | 269 | (optionally send request header "If-None-Modified") 270 | ``` 271 | GET http://www.example.com/reportImages/images/K738605462B1380786238.svg 272 | Headers: 273 | * Accept = image/svg+xml 274 | ``` 275 | 276 | **Response** 277 | (note cache headers: "Cache-Control", "Expires" & "Pragma".) 278 | ``` 279 | Status: 200 280 | Headers: 281 | * Content-Type = image/svg+xml 282 | * ETag = "K131214052B1471096127" 283 | * Cache-Control = private, max-age=604800 284 | * Expires = Mon, 24 Apr 2017 16:30:16 GMT 285 | * Pragma = (empty string) 286 | Body: 287 | "