From dd53d34ff566d6f66640f09077dd0c076ef2bcb2 Mon Sep 17 00:00:00 2001 From: David Weik Date: Thu, 20 Mar 2025 14:48:49 +0100 Subject: [PATCH] BF for Flow Mode --- .../CAS - Submit Python and R Code.step | 2 +- CAS - Submit Python and R Code/README.md | 13 +++++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/CAS - Submit Python and R Code/CAS - Submit Python and R Code.step b/CAS - Submit Python and R Code/CAS - Submit Python and R Code.step index b51ce02b..bcd06088 100644 --- a/CAS - Submit Python and R Code/CAS - Submit Python and R Code.step +++ b/CAS - Submit Python and R Code/CAS - Submit Python and R Code.step @@ -1 +1 @@ -{"creationTimeStamp":"2023-11-19T14:31:30.968Z","modifiedTimeStamp":"2023-12-15T16:15:58.466Z","createdBy":"gerdaw","modifiedBy":"gerdaw","name":"CAS - Submit Python and R Code.step","displayName":"CAS - Submit Python and R Code.step","localDisplayName":"CAS - Submit Python and R Code.step","description":"Submit Python and R Code to CAS","localDescription":"Submit Python and R Code to CAS","properties":{},"links":[{"method":"GET","rel":"self","href":"/dataFlows/steps/7992b298-793a-4ed4-8089-70183c6817bd","uri":"/dataFlows/steps/7992b298-793a-4ed4-8089-70183c6817bd","type":"application/vnd.sas.data.flow.step"},{"method":"GET","rel":"alternate","href":"/dataFlows/steps/7992b298-793a-4ed4-8089-70183c6817bd","uri":"/dataFlows/steps/7992b298-793a-4ed4-8089-70183c6817bd","type":"application/vnd.sas.data.flow.step.summary"},{"method":"GET","rel":"up","href":"/dataFlows/steps","uri":"/dataFlows/steps","type":"application/vnd.sas.collection","itemType":"application/vnd.sas.data.flow.step.summary"},{"method":"PUT","rel":"update","href":"/dataFlows/steps/7992b298-793a-4ed4-8089-70183c6817bd","uri":"/dataFlows/steps/7992b298-793a-4ed4-8089-70183c6817bd","type":"application/vnd.sas.data.flow.step","responseType":"application/vnd.sas.data.flow.step"},{"method":"DELETE","rel":"delete","href":"/dataFlows/steps/7992b298-793a-4ed4-8089-70183c6817bd","uri":"/dataFlows/steps/7992b298-793a-4ed4-8089-70183c6817bd"},{"method":"GET","rel":"transferExport","href":"/dataFlows/steps/7992b298-793a-4ed4-8089-70183c6817bd","uri":"/dataFlows/steps/7992b298-793a-4ed4-8089-70183c6817bd","responseType":"application/vnd.sas.transfer.object"},{"method":"PUT","rel":"transferImportUpdate","href":"/dataFlows/steps/7992b298-793a-4ed4-8089-70183c6817bd","uri":"/dataFlows/steps/7992b298-793a-4ed4-8089-70183c6817bd","type":"application/vnd.sas.transfer.object","responseType":"application/vnd.sas.summary"}],"metadataVersion":0.0,"version":2,"type":"code","flowMetadata":{"inputPorts":[{"name":"inputtable1","displayName":"inputtable1","localDisplayName":"inputtable1","minEntries":0,"maxEntries":1,"defaultEntries":0,"type":"table"},{"name":"inputtable2","displayName":"inputtable2","localDisplayName":"inputtable2","minEntries":0,"maxEntries":1,"defaultEntries":0,"type":"table"},{"name":"inputtable3","displayName":"inputtable3","localDisplayName":"inputtable3","minEntries":0,"maxEntries":1,"defaultEntries":0,"type":"table"},{"name":"inputtable4","displayName":"inputtable4","localDisplayName":"inputtable4","minEntries":0,"maxEntries":1,"defaultEntries":0,"type":"table"},{"name":"inputtable5","displayName":"inputtable5","localDisplayName":"inputtable5","minEntries":0,"maxEntries":1,"defaultEntries":0,"type":"table"},{"name":"inputtable6","displayName":"inputtable6","localDisplayName":"inputtable6","minEntries":0,"maxEntries":1,"defaultEntries":0,"type":"table"},{"name":"inputtable7","displayName":"inputtable7","localDisplayName":"inputtable7","minEntries":0,"maxEntries":1,"defaultEntries":0,"type":"table"},{"name":"inputtable8","displayName":"inputtable8","localDisplayName":"inputtable8","minEntries":0,"maxEntries":1,"defaultEntries":0,"type":"table"},{"name":"inputtable9","displayName":"inputtable9","localDisplayName":"inputtable9","minEntries":0,"maxEntries":1,"defaultEntries":0,"type":"table"},{"name":"inputtable10","displayName":"inputtable10","localDisplayName":"inputtable10","minEntries":0,"maxEntries":1,"defaultEntries":0,"type":"table"}],"outputPorts":[{"name":"outputtable1","displayName":"outputtable1","localDisplayName":"outputtable1","minEntries":0,"maxEntries":1,"defaultEntries":0,"type":"table","supportsView":false,"requiresStructure":false},{"name":"outputtable2","displayName":"outputtable2","localDisplayName":"outputtable2","minEntries":0,"maxEntries":1,"defaultEntries":0,"type":"table","supportsView":false,"requiresStructure":false},{"name":"outputtable3","displayName":"outputtable3","localDisplayName":"outputtable3","minEntries":0,"maxEntries":1,"defaultEntries":0,"type":"table","supportsView":false,"requiresStructure":false},{"name":"outputtable4","displayName":"outputtable4","localDisplayName":"outputtable4","minEntries":0,"maxEntries":1,"defaultEntries":0,"type":"table","supportsView":false,"requiresStructure":false},{"name":"outputtable5","displayName":"outputtable5","localDisplayName":"outputtable5","minEntries":0,"maxEntries":1,"defaultEntries":0,"type":"table","supportsView":false,"requiresStructure":false},{"name":"outputtable6","displayName":"outputtable6","localDisplayName":"outputtable6","minEntries":0,"maxEntries":1,"defaultEntries":0,"type":"table","supportsView":false,"requiresStructure":false},{"name":"outputtable7","displayName":"outputtable7","localDisplayName":"outputtable7","minEntries":0,"maxEntries":1,"defaultEntries":0,"type":"table","supportsView":false,"requiresStructure":false},{"name":"outputtable8","displayName":"outputtable8","localDisplayName":"outputtable8","minEntries":0,"maxEntries":1,"defaultEntries":0,"type":"table","supportsView":false,"requiresStructure":false},{"name":"outputtable9","displayName":"outputtable9","localDisplayName":"outputtable9","minEntries":0,"maxEntries":1,"defaultEntries":0,"type":"table","supportsView":false,"requiresStructure":false},{"name":"outputtable10","displayName":"outputtable10","localDisplayName":"outputtable10","minEntries":0,"maxEntries":1,"defaultEntries":0,"type":"table","supportsView":false,"requiresStructure":false}]},"ui":"{\n\t\"showPageContentOnly\": true,\n\t\"pages\": [\n\t\t{\n\t\t\t\"id\": \"pageDefinition\",\n\t\t\t\"type\": \"page\",\n\t\t\t\"label\": \"Definition\",\n\t\t\t\"children\": [\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"infoText\",\n\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\"text\": \"Select a Python or R script, connect the required in- and output tables for that script and then click run.\",\n\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"scriptInfoText\",\n\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\"text\": \"The Python and R scripts can be stored both in SAS Content and on the SAS Server, but please ensure that Python scripts end in .py and R scripts end in .R.\",\n\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"scriptFileSelector\",\n\t\t\t\t\t\"type\": \"path\",\n\t\t\t\t\t\"label\": \"Select Python or R script:\",\n\t\t\t\t\t\"pathtype\": \"file\",\n\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\"required\": true,\n\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"definitionInputTableSection\",\n\t\t\t\t\t\"type\": \"section\",\n\t\t\t\t\t\"label\": \"Input table(s)\",\n\t\t\t\t\t\"open\": true,\n\t\t\t\t\t\"visible\": \"\",\n\t\t\t\t\t\"children\": [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"infoTextInputTables\",\n\t\t\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\t\t\"text\": \"Connect required input tables, up to a maximum of 10 tables. Input tables will be passed to the open-source program as part of the gateway arguments list (gateway.args for Python, gw$args for R) as inputtable1-10. These arguments can be used inside the gateway.read_table or other methods. The inputTableCounter can go from 0 to 10 and can be used to keep track of how many input tables are connected.\\n\\nPython example: \\ndf = gateway.read_table(gateway.args['inputtable1'])\\nR example:\\ntbl <- read_table(gw$args[['inputtable1']])\",\n\t\t\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"inputtable1\",\n\t\t\t\t\t\t\t\"type\": \"inputtable\",\n\t\t\t\t\t\t\t\"label\": \"First input table:\",\n\t\t\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"inputtable2\",\n\t\t\t\t\t\t\t\"type\": \"inputtable\",\n\t\t\t\t\t\t\t\"label\": \"Second input table:\",\n\t\t\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\t\t\"visible\": \"$inputtable1\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"inputtable3\",\n\t\t\t\t\t\t\t\"type\": \"inputtable\",\n\t\t\t\t\t\t\t\"label\": \"Third input table:\",\n\t\t\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\t\t\"visible\": \"$inputtable2\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"inputtable4\",\n\t\t\t\t\t\t\t\"type\": \"inputtable\",\n\t\t\t\t\t\t\t\"label\": \"Fourth input table:\",\n\t\t\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\t\t\"visible\": \"$inputtable3\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"inputtable5\",\n\t\t\t\t\t\t\t\"type\": \"inputtable\",\n\t\t\t\t\t\t\t\"label\": \"Fifth input table:\",\n\t\t\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\t\t\"visible\": \"$inputtable4\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"inputtable6\",\n\t\t\t\t\t\t\t\"type\": \"inputtable\",\n\t\t\t\t\t\t\t\"label\": \"Sixth input table:\",\n\t\t\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\t\t\"visible\": \"$inputtable5\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"inputtable7\",\n\t\t\t\t\t\t\t\"type\": \"inputtable\",\n\t\t\t\t\t\t\t\"label\": \"Seventh input table:\",\n\t\t\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\t\t\"visible\": \"$inputtable6\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"inputtable8\",\n\t\t\t\t\t\t\t\"type\": \"inputtable\",\n\t\t\t\t\t\t\t\"label\": \"Eight input table:\",\n\t\t\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\t\t\"visible\": \"$inputtable7\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"inputtable9\",\n\t\t\t\t\t\t\t\"type\": \"inputtable\",\n\t\t\t\t\t\t\t\"label\": \"Ninth input table:\",\n\t\t\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\t\t\"visible\": \"$inputtable8\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"inputtable10\",\n\t\t\t\t\t\t\t\"type\": \"inputtable\",\n\t\t\t\t\t\t\t\"label\": \"Tenth input table:\",\n\t\t\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\t\t\"visible\": \"$inputtable9\"\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"definitionOutputTableSection\",\n\t\t\t\t\t\"type\": \"section\",\n\t\t\t\t\t\"label\": \"Output table(s)\",\n\t\t\t\t\t\"open\": true,\n\t\t\t\t\t\"visible\": \"\",\n\t\t\t\t\t\"children\": [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"text1\",\n\t\t\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\t\t\"text\": \"Connect required output tables, up to a maximum of 10 tables. Output table names will be passed to the open-source program as part of the gateway arguments list (gateway.args for Python, gw$args for R) as outputtable1-10. These arguments can be used inside the gateway.write_table or other methods. The outputTableCounter can go from 0 to 10 and can be used to keep track of how many input tables are connected.\\n\\nPython example: \\ngateway.write_table(df, (gateway.args['outputtable1'])\\nR example:\\ntbl <- write_table(gw$args[['outputtable1']])\",\n\t\t\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"outputtable1\",\n\t\t\t\t\t\t\t\"type\": \"outputtable\",\n\t\t\t\t\t\t\t\"label\": \"First output table:\",\n\t\t\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"outputtable2\",\n\t\t\t\t\t\t\t\"type\": \"outputtable\",\n\t\t\t\t\t\t\t\"label\": \"Second output table:\",\n\t\t\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\t\t\"visible\": \"$outputtable1\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"outputtable3\",\n\t\t\t\t\t\t\t\"type\": \"outputtable\",\n\t\t\t\t\t\t\t\"label\": \"Third output table:\",\n\t\t\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\t\t\"visible\": \"$outputtable2\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"outputtable4\",\n\t\t\t\t\t\t\t\"type\": \"outputtable\",\n\t\t\t\t\t\t\t\"label\": \"Fourth output table:\",\n\t\t\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\t\t\"visible\": \"$outputtable3\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"outputtable5\",\n\t\t\t\t\t\t\t\"type\": \"outputtable\",\n\t\t\t\t\t\t\t\"label\": \"Fifth output table:\",\n\t\t\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\t\t\"visible\": \"$outputtable4\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"outputtable6\",\n\t\t\t\t\t\t\t\"type\": \"outputtable\",\n\t\t\t\t\t\t\t\"label\": \"Sixth output table:\",\n\t\t\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\t\t\"visible\": \"$outputtable5\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"outputtable7\",\n\t\t\t\t\t\t\t\"type\": \"outputtable\",\n\t\t\t\t\t\t\t\"label\": \"Seventh output table:\",\n\t\t\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\t\t\"visible\": \"$outputtable6\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"outputtable8\",\n\t\t\t\t\t\t\t\"type\": \"outputtable\",\n\t\t\t\t\t\t\t\"label\": \"Eigth output table:\",\n\t\t\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\t\t\"visible\": \"$outputtable7\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"outputtable9\",\n\t\t\t\t\t\t\t\"type\": \"outputtable\",\n\t\t\t\t\t\t\t\"label\": \"Ninth output table:\",\n\t\t\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\t\t\"visible\": \"$outputtable8\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"outputtable10\",\n\t\t\t\t\t\t\t\"type\": \"outputtable\",\n\t\t\t\t\t\t\t\"label\": \"Tenth output table:\",\n\t\t\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\t\t\"visible\": \"$outputtable9\"\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"id\": \"pageOptions\",\n\t\t\t\"type\": \"page\",\n\t\t\t\"label\": \"Options\",\n\t\t\t\"children\": [\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"optionExplainer\",\n\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\"text\": \"Specify additional run-time attributes which help code execution or debugging in the event of any errors or warnings.\",\n\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"runSingleThread\",\n\t\t\t\t\t\"type\": \"checkbox\",\n\t\t\t\t\t\"label\": \"Restrict the code to a single session in a single thread\",\n\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"explainerNumThreads\",\n\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\"text\": \"Specifies the number of threads that are used to run the program. For distributed servers, this value specifies number of threads on each worker to use for running the program. The default of 0 indicates to use all available threads.\",\n\t\t\t\t\t\"visible\": \"!$runSingleThread\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"nthreads\",\n\t\t\t\t\t\"type\": \"numberfield\",\n\t\t\t\t\t\"label\": \"Number of threads:\",\n\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\"max\": null,\n\t\t\t\t\t\"min\": null,\n\t\t\t\t\t\"visible\": \"!$runSingleThread\",\n\t\t\t\t\t\"integer\": true\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"logLevel\",\n\t\t\t\t\t\"type\": \"dropdown\",\n\t\t\t\t\t\"label\": \"Select the log level:\",\n\t\t\t\t\t\"items\": [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"value\": \"INFO\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"value\": \"DEBUG\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"value\": \"ERROR\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"value\": \"FATAL\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"value\": \"NOTSET\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"value\": \"WARN\"\n\t\t\t\t\t\t}\n\t\t\t\t\t],\n\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"explainerTimeout\",\n\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\"text\": \"Maximum idle time required to wait for the external language code to be executed prior to timing out.\",\n\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"timeoutMillis\",\n\t\t\t\t\t\"type\": \"numstepper\",\n\t\t\t\t\t\"label\": \"Specify maximum timeout in milliseconds:\",\n\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\"integer\": true,\n\t\t\t\t\t\"min\": 1,\n\t\t\t\t\t\"max\": null,\n\t\t\t\t\t\"stepsize\": 1\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"explainerJitter\",\n\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\"text\": \"Maximum variance between thread synchronization, higher values are recommended when one thread or session has more work than another. Set -1 for for no synchronization time out.\",\n\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"jitterTimeoutMillis\",\n\t\t\t\t\t\"type\": \"numstepper\",\n\t\t\t\t\t\"label\": \"Specify jitter timeout in milliseconds:\",\n\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\"integer\": true,\n\t\t\t\t\t\"min\": -1,\n\t\t\t\t\t\"max\": null,\n\t\t\t\t\t\"stepsize\": 1\n\t\t\t\t}\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"id\": \"pageAbout\",\n\t\t\t\"type\": \"page\",\n\t\t\t\"label\": \"About\",\n\t\t\t\"children\": [\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"textAbout\",\n\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\"text\": \"CAS - Submit Python and R Code\\n==========\\n\\nThe \\\"CAS - Submit Python and R Code\\\" provides a wrapping for the CAS action gateway.runLang.\\n\\nUse this custom step to execute open-source programs, taking advantage of parallelization, multiple threads and fast data exchange mechanisms (backed by the Apache Arrow in-memory data format).\\n\\nThe following is supported: \\n * Select a Python or R script\\n * Pass in up to 10 input tables\\n * Return up to 10 output tables\\n\",\n\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"sectionPrereqs\",\n\t\t\t\t\t\"type\": \"section\",\n\t\t\t\t\t\"label\": \"Pre-requisites\",\n\t\t\t\t\t\"open\": false,\n\t\t\t\t\t\"visible\": \"\",\n\t\t\t\t\t\"children\": [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"textPrereqs\",\n\t\t\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\t\t\"text\": \"Pre-requisites: \\n- Tested on Viya version Stable 2023.11\\n- Python and/or R need to be installed (making use of GW_PYPATH/GW_RPATH - check the examples/sas-open-source-config in the deployment resources) and the required packages need to be available (see documentation link)\",\n\t\t\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"sectionDocumentation\",\n\t\t\t\t\t\"type\": \"section\",\n\t\t\t\t\t\"label\": \"Documentation\",\n\t\t\t\t\t\"open\": false,\n\t\t\t\t\t\"visible\": \"\",\n\t\t\t\t\t\"children\": [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"textDocumentation\",\n\t\t\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\t\t\"text\": \"* runLang action in the SAS Viya Platform Programming Documentation (https://go.documentation.sas.com/doc/en/pgmsascdc/default/caspg/cas-gateway-runlang.htm)\",\n\t\t\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"sectionChangelog\",\n\t\t\t\t\t\"type\": \"section\",\n\t\t\t\t\t\"label\": \"Changelog\",\n\t\t\t\t\t\"open\": true,\n\t\t\t\t\t\"visible\": \"\",\n\t\t\t\t\t\"children\": [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"textChangelog\",\n\t\t\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\t\t\"text\": \"* Version: 1.0 (19NOV2023)\\n - Initial version\",\n\t\t\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t]\n\t\t}\n\t],\n\t\"syntaxversion\": \"1.3.0\",\n\t\"values\": {\n\t\t\"scriptFileSelector\": \"\",\n\t\t\"inputtable1\": {\n\t\t\t\"library\": \"\",\n\t\t\t\"table\": \"\"\n\t\t},\n\t\t\"inputtable2\": {\n\t\t\t\"library\": \"\",\n\t\t\t\"table\": \"\"\n\t\t},\n\t\t\"inputtable3\": {\n\t\t\t\"library\": \"\",\n\t\t\t\"table\": \"\"\n\t\t},\n\t\t\"outputtable1\": {\n\t\t\t\"library\": \"\",\n\t\t\t\"table\": \"\"\n\t\t},\n\t\t\"outputtable2\": {\n\t\t\t\"library\": \"\",\n\t\t\t\"table\": \"\"\n\t\t},\n\t\t\"runSingleThread\": false,\n\t\t\"nthreads\": 0,\n\t\t\"logLevel\": {\n\t\t\t\"value\": \"INFO\"\n\t\t},\n\t\t\"timeoutMillis\": 60000,\n\t\t\"jitterTimeoutMillis\": 60000\n\t}\n}","templates":{"SAS":"* sprc is short for submit Python and R code;\n* Macro to check if the connected tables are in CAS;\n%macro _sprc_check_for_engine(_sprc_current_table_engine, _sprc_current_table, _sprc_cfe_rc, _sprc_expected_engine=CAS);\n\t%local _sprc_current_table_engine\n\t\t_sprc_current_table\n\t\t_sprc_expected_engine\n\t\t_sprc_cfe_rc;\n\n\t%if &_sprc_current_table_engine. NE &_sprc_expected_engine. %then %do;\n\t\t%let &_sprc_cfe_rc. = 0;\n\n\t\tdata _null_;\n\t\t\tputlog \"ERROR: The table &_sprc_current_table. is not a &_sprc_expected_engine. table.\";\n\t\t\tputlog \"ERROR: In order for this step to run your data needs to be loaded in &_sprc_expected_engine.\";\n\t\t\tabort 42;\n\t\trun;\n\t%end;\n%mend _sprc_check_for_engine;\n\n* Macro to get the caslib name of the libname;\n%macro _sprc_get_caslib_name(_sprc_libref, _sprc_caslib_variable);\n\t%local _sprc_libref\n\t\t_sprc_caslib_variable;\n\t\n\tproc sql noprint;\n\t\tselect sysvalue into :&_sprc_caslib_variable. trimmed from dictionary.libnames\n\t\twhere libname = upcase(\"&_sprc_libref.\") and upcase(sysname)=\"CASLIB\";\n\tquit;\n%mend _sprc_get_caslib_name;\n\n\n%macro _sprc_check();\n\t%local _sprc_ERROR_CODE\n\t\t_sprcFile\n\t\t_sprcIsContent\n\t\t_sprcFirstArg;\n\n\t* Detector for the script language based on the scripts file extension;\n\t* Counter for the number of in and output tables;\n\t%global _sprcLang\n\t\t_sprcInCounter\n\t\t_sprcOutCounter;\n\n\t%let _sprc_ERROR_CODE = 1;\n\t%let _sprcIsContent = 0;\n\t%let _sprcFirstArg = 1;\n\t%let _sprcInCounter = 0;\n\t%let _sprcOutCounter = 0;\n\n\t* Iterate overall then input and output table;\n\t* First step is checking if the variable contains anything;\n\t* If a table was connected engine check for CAS is done and the acutal CASLIB name is retrieved;\n\t* Then the table is turned into an argument for the gateway.runLang action;\n\t%do _sprc_i = 1 %to 10;\n\t\t* Check all 10 potential input tables;\n\t\t%if &&inputtable&_sprc_i. eq %then %do;\n\t\t\t%if &_sprc_i. eq 1 %then %do;\n\t\t\t\t%put NOTE: No input table connected.;\n\t\t\t%end;\n\t\t\t%let inputtable&_sprc_i. =;\n\t\t%end;\n\t\t%else %do;\n\t\t\t%_sprc_check_for_engine(&&inputtable&_sprc_i._engine., &&inputtable&_sprc_i., _sprc_ERROR_CODE);\n\t\t\t%_sprc_get_caslib_name(&&inputtable&_sprc_i._lib., &&inputtable&_sprc_i._lib.);\n\n\t\t\t%let _sprcInCounter = %eval(&_sprcInCounter. + 1);\n\t\t\t%if &_sprcFirstArg. %then %do;\n\t\t\t\t%let inputtable&_sprc_i. = inputtable&_sprc_i. = {name = \"&&inputtable&_sprc_i._name\", caslib=\"&&inputtable&_sprc_i._lib\"};\n\t\t\t\t%let _sprcFirstArg = 0;\n\t\t\t%end;\n\t\t\t%else %do;\n\t\t\t\t%let inputtable&_sprc_i. = ,inputtable&_sprc_i. = {name = \"&&inputtable&_sprc_i._name\", caslib=\"&&inputtable&_sprc_i._lib\"};\n\t\t\t%end;\n\t\t%end;\n\n\t\t* Check all 10 potential output tables;\n\t\t%if &&outputtable&_sprc_i. eq %then %do;\n\t\t\t%if &_sprc_i. eq 1 %then %do;\n\t\t\t\t%put NOTE: No output table connected.;\n\t\t\t%end;\n\t\t\t%let outputtable&_sprc_i. =;\n\t\t%end;\n\t\t%else %do;\n\t\t\t%_sprc_check_for_engine(&&outputtable&_sprc_i._engine., &&outputtable&_sprc_i., _sprc_ERROR_CODE);\n\t\t\t%_sprc_get_caslib_name(&&outputtable&_sprc_i._lib., &&outputtable&_sprc_i._lib.);\n\n\t\t\t%let _sprcOutCounter = %eval(&_sprcOutCounter. + 1);\n\t\t\t%if &_sprcFirstArg. %then %do;\n\t\t\t\t%let outputtable&_sprc_i. = outputtable&_sprc_i. = {name = \"&&outputtable&_sprc_i._name\", caslib=\"&&outputtable&_sprc_i._lib\"};\n\t\t\t\t%let _sprcFirstArg = 0;\n\t\t\t%end;\n\t\t\t%else %do;\n\t\t\t\t%let outputtable&_sprc_i. = ,outputtable&_sprc_i. = {name = \"&&outputtable&_sprc_i._name\", caslib=\"&&outputtable&_sprc_i._lib\"};\n\t\t\t%end;\n\t\t%end;\n\t%end;\n\n\t%if &_sprcFirstArg. eq 0 %then %do;\n\t\t%let outputtable10 = &outputtable10., inputTableCounter = &_sprcInCounter., outputTableCounter = &_sprcOutCounter.;\n\t%end;\n\t%else %do;\n\t\t%let outputtable10 = inputTableCounter = &_sprcInCounter., outputTableCounter = &_sprcOutCounter.;\n\t%end;\n\n\t%if &_sprc_ERROR_CODE. %then %do;\n\t\t* Extract the script language and create the filename statement for the script;\n\t\tdata _null_;\n\t\t\tjustFileName = scan(\"&scriptFileSelector.\", -1, '/', 'MO');\n\t\t\tfolderPath1 = scan(\"&scriptFileSelector.\", 2, ':', 'MO');\n\t\t\tfolderPath2 = substr(folderPath1, 1, length(folderPath1) - length(justFileName) - 1);\n\t\t\tmode = scan(\"&scriptFileSelector.\", 1, ':', 'MO');\n\t\t\t\n\t\t\t* Handle the different required filename for SAS Content and SAS Server;\n\t\t\tif mode = 'sascontent' then do;\n\t\t\t\tcall symput('_sprcIsContent', 1);\n\t\t\t\tcall symput('_sprcFile', \"filename sprcTMP filesrvc folderPath='\" || strip(folderPath2) || \"' filename='\" || strip(justFileName) || \"'\");\n\t\t\tend;\n\t\t\telse do;\n\t\t\t\tcall symput('_sprcFile', \"filename sprcScpt '\" || strip(folderPath1) || \"'\");\n\t\t\tend;\n\t\t\n\t\t\t* Check the file extension and set the code parameter accordingly;\n\t\t\tlang = reverse(scan(reverse(\"&scriptFileSelector.\"), 1, '.'));\n\t\t\tif lowcase(lang) = 'py' then do;\n\t\t\t\tcall symput('_sprcLang', 'PYTHON');\n\t\t\tend;\n\t\t\telse if lowcase(lang) = 'r' then do;\n\t\t\t\tcall symput('_sprcLang', 'R');\n\t\t\tend;\n\t\t\telse do;\n\t\t\t\tputlog 'ERROR: Unsupported file extension detected - Execution aborted';\n\t\t\t\tabort 42;\n\t\t\tend;\n\t\trun;\n\n\t\t* SAS Content file needs to be copied to a temp file;\n\t\t%if &_sprcIsContent. %then %do;\n\t\t\t&_sprcFile.;\n\t\t\tfilename sprcScpt temp;\n\n\t\t\tdata _null_;\n\t\t\t\tinfile sprcTMP;\n\t\t\t\tfile sprcScpt;\n\t\t\t\tinput;\n\t\t\t\n\t\t\t\tput _infile_;\n\t\t\trun;\n\n\t\t\tfilename sprcTMP clear;\n\t\t%end;\n\t\t%else %do;\n\t\t\t&_sprcFile.;\n\t\t%end;\n\t%end;\n%mend _sprc_check;\n\n%_sprc_check();\n\n* Run the actual code - as it uses submit/endsubmit it needs to be outside of a macro;\nproc cas;\n\tcode = readfile('sprcScpt');\n\n\tgateway.runLang / args={&inputtable1. &outputtable1. &inputtable2. &outputtable2. &inputtable3. &outputtable3. &inputtable4. &outputtable4. &inputtable5. &outputtable5. &inputtable6. &outputtable6. &inputtable7. &outputtable7. &inputtable8. &outputtable8. &inputtable9. &outputtable9. &inputtable10. &outputtable10.},\n\t\tcode = code,\n\t\tjitter_timeout_millis = &jitterTimeoutMillis.,\n\t\tlang = \"&_sprcLang.\",\n\t\tlog_level = \"&logLevel.\",\n\t\t%if &nthreads. ne 0 %then %do; %put nthreads = &nthreads.,; %end;\n\t\tsingle = %if &runSingleThread. %then %do; true %end; %else %do; false %end;,\n\t\ttimeout_millis = &timeoutMillis.;\nrun; quit;\n\nfilename sprcScpt clear;\n%symdel _sprcLang _sprcInCounter _sprcOutCounter;\n%sysmacdelete _sprc_check_for_engine;\n%sysmacdelete _sprc_get_caslib_name;\n%sysmacdelete _sprc_check;"}} \ No newline at end of file +{"creationTimeStamp":"2025-03-20T09:12:29.880Z","modifiedTimeStamp":"2025-03-20T13:44:44.728Z","createdBy":"gerdaw","modifiedBy":"gerdaw","name":"CAS - Submit Python and R Code.step","displayName":"CAS - Submit Python and R Code.step","localDisplayName":"CAS - Submit Python and R Code.step","description":"Submit Python and R Code to CAS","localDescription":"Submit Python and R Code to CAS","properties":{},"links":[{"method":"GET","rel":"self","href":"/dataFlows/steps/7f5f42fc-ede4-454a-8373-c54c8811e1df","uri":"/dataFlows/steps/7f5f42fc-ede4-454a-8373-c54c8811e1df","type":"application/vnd.sas.data.flow.step"},{"method":"GET","rel":"alternate","href":"/dataFlows/steps/7f5f42fc-ede4-454a-8373-c54c8811e1df","uri":"/dataFlows/steps/7f5f42fc-ede4-454a-8373-c54c8811e1df","type":"application/vnd.sas.data.flow.step.summary"},{"method":"GET","rel":"up","href":"/dataFlows/steps","uri":"/dataFlows/steps","type":"application/vnd.sas.collection","itemType":"application/vnd.sas.data.flow.step.summary"},{"method":"PUT","rel":"update","href":"/dataFlows/steps/7f5f42fc-ede4-454a-8373-c54c8811e1df","uri":"/dataFlows/steps/7f5f42fc-ede4-454a-8373-c54c8811e1df","type":"application/vnd.sas.data.flow.step","responseType":"application/vnd.sas.data.flow.step"},{"method":"DELETE","rel":"delete","href":"/dataFlows/steps/7f5f42fc-ede4-454a-8373-c54c8811e1df","uri":"/dataFlows/steps/7f5f42fc-ede4-454a-8373-c54c8811e1df"},{"method":"POST","rel":"copy","href":"/dataFlows/steps/7f5f42fc-ede4-454a-8373-c54c8811e1df/copy","uri":"/dataFlows/steps/7f5f42fc-ede4-454a-8373-c54c8811e1df/copy","responseType":"application/vnd.sas.data.flow.step"},{"method":"GET","rel":"transferExport","href":"/dataFlows/steps/7f5f42fc-ede4-454a-8373-c54c8811e1df","uri":"/dataFlows/steps/7f5f42fc-ede4-454a-8373-c54c8811e1df","responseType":"application/vnd.sas.transfer.object"},{"method":"PUT","rel":"transferImportUpdate","href":"/dataFlows/steps/7f5f42fc-ede4-454a-8373-c54c8811e1df","uri":"/dataFlows/steps/7f5f42fc-ede4-454a-8373-c54c8811e1df","type":"application/vnd.sas.transfer.object","responseType":"application/vnd.sas.summary"}],"metadataVersion":0.0,"version":2,"type":"code","flowMetadata":{"inputPorts":[{"name":"inputtable1","displayName":"inputtable1","localDisplayName":"inputtable1","minEntries":0,"maxEntries":1,"defaultEntries":0,"type":"table"},{"name":"inputtable2","displayName":"inputtable2","localDisplayName":"inputtable2","minEntries":0,"maxEntries":1,"defaultEntries":0,"type":"table"},{"name":"inputtable3","displayName":"inputtable3","localDisplayName":"inputtable3","minEntries":0,"maxEntries":1,"defaultEntries":0,"type":"table"},{"name":"inputtable4","displayName":"inputtable4","localDisplayName":"inputtable4","minEntries":0,"maxEntries":1,"defaultEntries":0,"type":"table"},{"name":"inputtable5","displayName":"inputtable5","localDisplayName":"inputtable5","minEntries":0,"maxEntries":1,"defaultEntries":0,"type":"table"},{"name":"inputtable6","displayName":"inputtable6","localDisplayName":"inputtable6","minEntries":0,"maxEntries":1,"defaultEntries":0,"type":"table"},{"name":"inputtable7","displayName":"inputtable7","localDisplayName":"inputtable7","minEntries":0,"maxEntries":1,"defaultEntries":0,"type":"table"},{"name":"inputtable8","displayName":"inputtable8","localDisplayName":"inputtable8","minEntries":0,"maxEntries":1,"defaultEntries":0,"type":"table"},{"name":"inputtable9","displayName":"inputtable9","localDisplayName":"inputtable9","minEntries":0,"maxEntries":1,"defaultEntries":0,"type":"table"},{"name":"inputtable10","displayName":"inputtable10","localDisplayName":"inputtable10","minEntries":0,"maxEntries":1,"defaultEntries":0,"type":"table"}],"outputPorts":[{"name":"outputtable1","displayName":"outputtable1","localDisplayName":"outputtable1","minEntries":0,"maxEntries":1,"defaultEntries":0,"type":"table","supportsView":false,"requiresStructure":false},{"name":"outputtable2","displayName":"outputtable2","localDisplayName":"outputtable2","minEntries":0,"maxEntries":1,"defaultEntries":0,"type":"table","supportsView":false,"requiresStructure":false},{"name":"outputtable3","displayName":"outputtable3","localDisplayName":"outputtable3","minEntries":0,"maxEntries":1,"defaultEntries":0,"type":"table","supportsView":false,"requiresStructure":false},{"name":"outputtable4","displayName":"outputtable4","localDisplayName":"outputtable4","minEntries":0,"maxEntries":1,"defaultEntries":0,"type":"table","supportsView":false,"requiresStructure":false},{"name":"outputtable5","displayName":"outputtable5","localDisplayName":"outputtable5","minEntries":0,"maxEntries":1,"defaultEntries":0,"type":"table","supportsView":false,"requiresStructure":false},{"name":"outputtable6","displayName":"outputtable6","localDisplayName":"outputtable6","minEntries":0,"maxEntries":1,"defaultEntries":0,"type":"table","supportsView":false,"requiresStructure":false},{"name":"outputtable7","displayName":"outputtable7","localDisplayName":"outputtable7","minEntries":0,"maxEntries":1,"defaultEntries":0,"type":"table","supportsView":false,"requiresStructure":false},{"name":"outputtable8","displayName":"outputtable8","localDisplayName":"outputtable8","minEntries":0,"maxEntries":1,"defaultEntries":0,"type":"table","supportsView":false,"requiresStructure":false},{"name":"outputtable9","displayName":"outputtable9","localDisplayName":"outputtable9","minEntries":0,"maxEntries":1,"defaultEntries":0,"type":"table","supportsView":false,"requiresStructure":false},{"name":"outputtable10","displayName":"outputtable10","localDisplayName":"outputtable10","minEntries":0,"maxEntries":1,"defaultEntries":0,"type":"table","supportsView":false,"requiresStructure":false}]},"ui":"{\n\t\"showPageContentOnly\": true,\n\t\"pages\": [\n\t\t{\n\t\t\t\"id\": \"pageDefinition\",\n\t\t\t\"type\": \"page\",\n\t\t\t\"label\": \"Definition\",\n\t\t\t\"children\": [\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"infoText\",\n\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\"text\": \"Select a Python or R script, connect the required in- and output tables for that script and then click run.\",\n\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"scriptInfoText\",\n\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\"text\": \"The Python and R scripts can be stored both in SAS Content and on the SAS Server, but please ensure that Python scripts end in .py and R scripts end in .R.\",\n\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"scriptFileSelector\",\n\t\t\t\t\t\"type\": \"path\",\n\t\t\t\t\t\"label\": \"Select Python or R script:\",\n\t\t\t\t\t\"pathtype\": \"file\",\n\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\"required\": true,\n\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"definitionInputTableSection\",\n\t\t\t\t\t\"type\": \"section\",\n\t\t\t\t\t\"label\": \"Input table(s)\",\n\t\t\t\t\t\"open\": true,\n\t\t\t\t\t\"visible\": \"\",\n\t\t\t\t\t\"children\": [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"infoTextInputTables\",\n\t\t\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\t\t\"text\": \"Connect required input tables, up to a maximum of 10 tables. Input tables will be passed to the open-source program as part of the gateway arguments list (gateway.args for Python, gw$args for R) as inputtable1-10. These arguments can be used inside the gateway.read_table or other methods. The inputTableCounter can go from 0 to 10 and can be used to keep track of how many input tables are connected.\\n\\nPython example: \\ndf = gateway.read_table(gateway.args['inputtable1'])\\nR example:\\ntbl <- read_table(gw$args[['inputtable1']])\",\n\t\t\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"inputtable1\",\n\t\t\t\t\t\t\t\"type\": \"inputtable\",\n\t\t\t\t\t\t\t\"label\": \"First input table:\",\n\t\t\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"inputtable2\",\n\t\t\t\t\t\t\t\"type\": \"inputtable\",\n\t\t\t\t\t\t\t\"label\": \"Second input table:\",\n\t\t\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\t\t\"visible\": \"$inputtable1\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"inputtable3\",\n\t\t\t\t\t\t\t\"type\": \"inputtable\",\n\t\t\t\t\t\t\t\"label\": \"Third input table:\",\n\t\t\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\t\t\"visible\": \"$inputtable2\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"inputtable4\",\n\t\t\t\t\t\t\t\"type\": \"inputtable\",\n\t\t\t\t\t\t\t\"label\": \"Fourth input table:\",\n\t\t\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\t\t\"visible\": \"$inputtable3\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"inputtable5\",\n\t\t\t\t\t\t\t\"type\": \"inputtable\",\n\t\t\t\t\t\t\t\"label\": \"Fifth input table:\",\n\t\t\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\t\t\"visible\": \"$inputtable4\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"inputtable6\",\n\t\t\t\t\t\t\t\"type\": \"inputtable\",\n\t\t\t\t\t\t\t\"label\": \"Sixth input table:\",\n\t\t\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\t\t\"visible\": \"$inputtable5\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"inputtable7\",\n\t\t\t\t\t\t\t\"type\": \"inputtable\",\n\t\t\t\t\t\t\t\"label\": \"Seventh input table:\",\n\t\t\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\t\t\"visible\": \"$inputtable6\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"inputtable8\",\n\t\t\t\t\t\t\t\"type\": \"inputtable\",\n\t\t\t\t\t\t\t\"label\": \"Eight input table:\",\n\t\t\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\t\t\"visible\": \"$inputtable7\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"inputtable9\",\n\t\t\t\t\t\t\t\"type\": \"inputtable\",\n\t\t\t\t\t\t\t\"label\": \"Ninth input table:\",\n\t\t\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\t\t\"visible\": \"$inputtable8\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"inputtable10\",\n\t\t\t\t\t\t\t\"type\": \"inputtable\",\n\t\t\t\t\t\t\t\"label\": \"Tenth input table:\",\n\t\t\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\t\t\"visible\": \"$inputtable9\"\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"definitionOutputTableSection\",\n\t\t\t\t\t\"type\": \"section\",\n\t\t\t\t\t\"label\": \"Output table(s)\",\n\t\t\t\t\t\"open\": true,\n\t\t\t\t\t\"visible\": \"\",\n\t\t\t\t\t\"children\": [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"text1\",\n\t\t\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\t\t\"text\": \"Connect required output tables, up to a maximum of 10 tables. Output table names will be passed to the open-source program as part of the gateway arguments list (gateway.args for Python, gw$args for R) as outputtable1-10. These arguments can be used inside the gateway.write_table or other methods. The outputTableCounter can go from 0 to 10 and can be used to keep track of how many input tables are connected.\\n\\nPython example: \\ngateway.write_table(df, (gateway.args['outputtable1'])\\nR example:\\nwrite_table(tbl, gw$args[['outputtable1']])\",\n\t\t\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"outputtable1\",\n\t\t\t\t\t\t\t\"type\": \"outputtable\",\n\t\t\t\t\t\t\t\"label\": \"First output table:\",\n\t\t\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"outputtable2\",\n\t\t\t\t\t\t\t\"type\": \"outputtable\",\n\t\t\t\t\t\t\t\"label\": \"Second output table:\",\n\t\t\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\t\t\"visible\": \"$outputtable1\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"outputtable3\",\n\t\t\t\t\t\t\t\"type\": \"outputtable\",\n\t\t\t\t\t\t\t\"label\": \"Third output table:\",\n\t\t\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\t\t\"visible\": \"$outputtable2\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"outputtable4\",\n\t\t\t\t\t\t\t\"type\": \"outputtable\",\n\t\t\t\t\t\t\t\"label\": \"Fourth output table:\",\n\t\t\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\t\t\"visible\": \"$outputtable3\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"outputtable5\",\n\t\t\t\t\t\t\t\"type\": \"outputtable\",\n\t\t\t\t\t\t\t\"label\": \"Fifth output table:\",\n\t\t\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\t\t\"visible\": \"$outputtable4\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"outputtable6\",\n\t\t\t\t\t\t\t\"type\": \"outputtable\",\n\t\t\t\t\t\t\t\"label\": \"Sixth output table:\",\n\t\t\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\t\t\"visible\": \"$outputtable5\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"outputtable7\",\n\t\t\t\t\t\t\t\"type\": \"outputtable\",\n\t\t\t\t\t\t\t\"label\": \"Seventh output table:\",\n\t\t\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\t\t\"visible\": \"$outputtable6\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"outputtable8\",\n\t\t\t\t\t\t\t\"type\": \"outputtable\",\n\t\t\t\t\t\t\t\"label\": \"Eigth output table:\",\n\t\t\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\t\t\"visible\": \"$outputtable7\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"outputtable9\",\n\t\t\t\t\t\t\t\"type\": \"outputtable\",\n\t\t\t\t\t\t\t\"label\": \"Ninth output table:\",\n\t\t\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\t\t\"visible\": \"$outputtable8\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"outputtable10\",\n\t\t\t\t\t\t\t\"type\": \"outputtable\",\n\t\t\t\t\t\t\t\"label\": \"Tenth output table:\",\n\t\t\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\t\t\"visible\": \"$outputtable9\"\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"id\": \"pageOptions\",\n\t\t\t\"type\": \"page\",\n\t\t\t\"label\": \"Options\",\n\t\t\t\"children\": [\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"optionExplainer\",\n\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\"text\": \"Specify additional run-time attributes which help code execution or debugging in the event of any errors or warnings.\",\n\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"runSingleThread\",\n\t\t\t\t\t\"type\": \"checkbox\",\n\t\t\t\t\t\"label\": \"Restrict the code to a single session in a single thread\",\n\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"explainerNumThreads\",\n\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\"text\": \"Specifies the number of threads that are used to run the program. For distributed servers, this value specifies number of threads on each worker to use for running the program. The default of 0 indicates to use all available threads.\",\n\t\t\t\t\t\"visible\": \"!$runSingleThread\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"nthreads\",\n\t\t\t\t\t\"type\": \"numberfield\",\n\t\t\t\t\t\"label\": \"Number of threads:\",\n\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\"max\": null,\n\t\t\t\t\t\"min\": null,\n\t\t\t\t\t\"visible\": \"!$runSingleThread\",\n\t\t\t\t\t\"integer\": true\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"logLevel\",\n\t\t\t\t\t\"type\": \"dropdown\",\n\t\t\t\t\t\"label\": \"Select the log level:\",\n\t\t\t\t\t\"items\": [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"value\": \"INFO\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"value\": \"DEBUG\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"value\": \"ERROR\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"value\": \"FATAL\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"value\": \"NOTSET\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"value\": \"WARN\"\n\t\t\t\t\t\t}\n\t\t\t\t\t],\n\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"explainerTimeout\",\n\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\"text\": \"Maximum idle time required to wait for the external language code to be executed prior to timing out.\",\n\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"timeoutMillis\",\n\t\t\t\t\t\"type\": \"numstepper\",\n\t\t\t\t\t\"label\": \"Specify maximum timeout in milliseconds:\",\n\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\"integer\": true,\n\t\t\t\t\t\"min\": 1,\n\t\t\t\t\t\"max\": null,\n\t\t\t\t\t\"stepsize\": 1\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"explainerJitter\",\n\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\"text\": \"Maximum variance between thread synchronization, higher values are recommended when one thread or session has more work than another. Set -1 for for no synchronization time out.\",\n\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"jitterTimeoutMillis\",\n\t\t\t\t\t\"type\": \"numstepper\",\n\t\t\t\t\t\"label\": \"Specify jitter timeout in milliseconds:\",\n\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\"integer\": true,\n\t\t\t\t\t\"min\": -1,\n\t\t\t\t\t\"max\": null,\n\t\t\t\t\t\"stepsize\": 1\n\t\t\t\t}\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"id\": \"pageAbout\",\n\t\t\t\"type\": \"page\",\n\t\t\t\"label\": \"About\",\n\t\t\t\"children\": [\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"textAbout\",\n\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\"text\": \"CAS - Submit Python and R Code\\n==========\\n\\nThe \\\"CAS - Submit Python and R Code\\\" provides a wrapping for the CAS action gateway.runLang.\\n\\nUse this custom step to execute open-source programs, taking advantage of parallelization, multiple threads and fast data exchange mechanisms (backed by the Apache Arrow in-memory data format).\\n\\nThe following is supported: \\n * Select a Python or R script\\n * Pass in up to 10 input tables\\n * Return up to 10 output tables\\n\",\n\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"sectionPrereqs\",\n\t\t\t\t\t\"type\": \"section\",\n\t\t\t\t\t\"label\": \"Pre-requisites\",\n\t\t\t\t\t\"open\": false,\n\t\t\t\t\t\"visible\": \"\",\n\t\t\t\t\t\"children\": [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"textPrereqs\",\n\t\t\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\t\t\"text\": \"Pre-requisites: \\n- Tested on Viya version Stable 2023.11\\n- Python and/or R need to be installed (making use of GW_PYPATH/GW_RPATH - check the examples/sas-open-source-config in the deployment resources) and the required packages need to be available (see documentation link)\",\n\t\t\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"sectionDocumentation\",\n\t\t\t\t\t\"type\": \"section\",\n\t\t\t\t\t\"label\": \"Documentation\",\n\t\t\t\t\t\"open\": false,\n\t\t\t\t\t\"visible\": \"\",\n\t\t\t\t\t\"children\": [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"textDocumentation\",\n\t\t\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\t\t\"text\": \"* runLang action in the SAS Viya Platform Programming Documentation (https://go.documentation.sas.com/doc/en/pgmsascdc/default/caspg/cas-gateway-runlang.htm)\",\n\t\t\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"sectionChangelog\",\n\t\t\t\t\t\"type\": \"section\",\n\t\t\t\t\t\"label\": \"Changelog\",\n\t\t\t\t\t\"open\": true,\n\t\t\t\t\t\"visible\": \"\",\n\t\t\t\t\t\"children\": [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"textChangelog\",\n\t\t\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\t\t\"text\": \"* Version: 1.1 (20MAR2025)\\n - Fix Bug in from Flow Mode execution\\n* Version: 1.0 (19NOV2023)\\n - Initial version\",\n\t\t\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t]\n\t\t}\n\t],\n\t\"syntaxversion\": \"1.3.0\",\n\t\"values\": {\n\t\t\"scriptFileSelector\": \"\",\n\t\t\"inputtable1\": {\n\t\t\t\"library\": \"\",\n\t\t\t\"table\": \"\"\n\t\t},\n\t\t\"inputtable2\": {\n\t\t\t\"library\": \"\",\n\t\t\t\"table\": \"\"\n\t\t},\n\t\t\"inputtable3\": {\n\t\t\t\"library\": \"\",\n\t\t\t\"table\": \"\"\n\t\t},\n\t\t\"outputtable1\": {\n\t\t\t\"library\": \"\",\n\t\t\t\"table\": \"\"\n\t\t},\n\t\t\"outputtable2\": {\n\t\t\t\"library\": \"\",\n\t\t\t\"table\": \"\"\n\t\t},\n\t\t\"runSingleThread\": false,\n\t\t\"nthreads\": 0,\n\t\t\"logLevel\": {\n\t\t\t\"value\": \"INFO\"\n\t\t},\n\t\t\"timeoutMillis\": 60000,\n\t\t\"jitterTimeoutMillis\": 60000\n\t}\n}","templates":{"SAS":"* sprc is short for submit Python and R code;\n* Macro to check if the connected tables are in CAS;\n%macro _sprc_check_for_engine(_sprc_current_table_engine, _sprc_current_table, _sprc_cfe_rc, _sprc_expected_engine=CAS);\n %local _sprc_current_table_engine\n _sprc_current_table\n _sprc_expected_engine\n _sprc_cfe_rc;\n\n %if &_sprc_current_table_engine. NE &_sprc_expected_engine. %then %do;\n %let &_sprc_cfe_rc. = 0;\n\n data _null_;\n putlog \"ERROR: The table &_sprc_current_table. is not a &_sprc_expected_engine. table.\";\n putlog \"ERROR: In order for this step to run your data needs to be loaded in &_sprc_expected_engine.\";\n abort 42;\n run;\n %end;\n%mend _sprc_check_for_engine;\n\n* Macro to get the caslib name of the libname;\n%macro _sprc_get_caslib_name(_sprc_libref, _sprc_caslib_variable);\n %local _sprc_libref\n _sprc_caslib_variable;\n \n proc sql noprint;\n select sysvalue into :&_sprc_caslib_variable. trimmed from dictionary.libnames\n where libname = upcase(\"&_sprc_libref.\") and upcase(sysname)=\"CASLIB\";\n quit;\n%mend _sprc_get_caslib_name;\n\n\n%macro _sprc_check();\n %local _sprc_ERROR_CODE\n _sprcFile\n _sprcIsContent\n _sprcFirstArg\n _sprc_i;\n\n * Detector for the script language based on the scripts file extension;\n * Counter for the number of in and output tables;\n %global _sprcLang\n _sprcInCounter\n _sprcOutCounter;\n\n %let _sprc_ERROR_CODE = 1;\n %let _sprcIsContent = 0;\n %let _sprcFirstArg = 1;\n %let _sprcInCounter = 0;\n %let _sprcOutCounter = 0;\n\n * Iterate overall then input and output table;\n * First step is checking if the variable contains anything;\n * If a table was connected engine check for CAS is done and the acutal CASLIB name is retrieved;\n * Then the table is turned into an argument for the gateway.runLang action;\n %do _sprc_i = 1 %to 10;\n * Check all 10 potential input tables;\n %if %symexist(inputtable&_sprc_i.) %then %do;\n %if &&inputtable&_sprc_i. eq %then %do;\n %if &_sprc_i. eq 1 %then %do;\n %put NOTE: No input table connected.;\n %end;\n %let inputtable&_sprc_i. =;\n %end;\n %else %do;\n %_sprc_check_for_engine(&&inputtable&_sprc_i._engine., &&inputtable&_sprc_i., _sprc_ERROR_CODE);\n %_sprc_get_caslib_name(&&inputtable&_sprc_i._lib., &&inputtable&_sprc_i._lib.);\n\n %let _sprcInCounter = %eval(&_sprcInCounter. + 1);\n %if &_sprcFirstArg. %then %do;\n %let inputtable&_sprc_i. = inputtable&_sprc_i. = {name = \"&&inputtable&_sprc_i._name\", caslib=\"&&inputtable&_sprc_i._lib\"};\n %let _sprcFirstArg = 0;\n %end;\n %else %do;\n %let inputtable&_sprc_i. = ,inputtable&_sprc_i. = {name = \"&&inputtable&_sprc_i._name\", caslib=\"&&inputtable&_sprc_i._lib\"};\n %end;\n %end;\n %end;\n %else %do;\n %global inputtable&_sprc_i.;\n %let inputtable&_sprc_i. =;\n %end;\n\n * Check all 10 potential output tables;\n %if %symexist(outputtable&_sprc_i) %then %do;\n %if &&outputtable&_sprc_i. eq %then %do;\n %if &_sprc_i. eq 1 %then %do;\n %put NOTE: No output table connected.;\n %end;\n %let outputtable&_sprc_i. =;\n %end;\n %else %do;\n %_sprc_check_for_engine(&&outputtable&_sprc_i._engine., &&outputtable&_sprc_i., _sprc_ERROR_CODE);\n %_sprc_get_caslib_name(&&outputtable&_sprc_i._lib., &&outputtable&_sprc_i._lib.);\n\n %let _sprcOutCounter = %eval(&_sprcOutCounter. + 1);\n %if &_sprcFirstArg. %then %do;\n %let outputtable&_sprc_i. = outputtable&_sprc_i. = {name = \"&&outputtable&_sprc_i._name\", caslib=\"&&outputtable&_sprc_i._lib\"};\n %let _sprcFirstArg = 0;\n %end;\n %else %do;\n %let outputtable&_sprc_i. = ,outputtable&_sprc_i. = {name = \"&&outputtable&_sprc_i._name\", caslib=\"&&outputtable&_sprc_i._lib\"};\n %end;\n %end;\n %end;\n %else %do;\n %global outputtable&_sprc_i.;\n %let outputtable&_sprc_i. =;\n %end;\n %end;\n\n %if &_sprcFirstArg. eq 0 %then %do;\n %let outputtable10 = &outputtable10., inputTableCounter = &_sprcInCounter., outputTableCounter = &_sprcOutCounter.;\n %end;\n %else %do;\n %let outputtable10 = inputTableCounter = &_sprcInCounter., outputTableCounter = &_sprcOutCounter.;\n %end;\n\n %if &_sprc_ERROR_CODE. %then %do;\n * Extract the script language and create the filename statement for the script;\n data _null_;\n justFileName = scan(\"&scriptFileSelector.\", -1, '/', 'MO');\n folderPath1 = scan(\"&scriptFileSelector.\", 2, ':', 'MO');\n folderPath2 = substr(folderPath1, 1, length(folderPath1) - length(justFileName) - 1);\n mode = scan(\"&scriptFileSelector.\", 1, ':', 'MO');\n \n * Handle the different required filename for SAS Content and SAS Server;\n if mode = 'sascontent' then do;\n call symput('_sprcIsContent', 1);\n call symput('_sprcFile', \"filename sprcTMP filesrvc folderPath='\" || strip(folderPath2) || \"' filename='\" || strip(justFileName) || \"'\");\n end;\n else do;\n call symput('_sprcFile', \"filename sprcScpt '\" || strip(folderPath1) || \"'\");\n end;\n \n * Check the file extension and set the code parameter accordingly;\n lang = reverse(scan(reverse(\"&scriptFileSelector.\"), 1, '.'));\n if lowcase(lang) = 'py' then do;\n call symput('_sprcLang', 'PYTHON');\n end;\n else if lowcase(lang) = 'r' then do;\n call symput('_sprcLang', 'R');\n end;\n else do;\n putlog 'ERROR: Unsupported file extension detected - Execution aborted';\n abort 42;\n end;\n run;\n\n * SAS Content file needs to be copied to a temp file;\n %if &_sprcIsContent. %then %do;\n &_sprcFile.;\n filename sprcScpt temp;\n\n data _null_;\n infile sprcTMP;\n file sprcScpt;\n input;\n \n put _infile_;\n run;\n\n filename sprcTMP clear;\n %end;\n %else %do;\n &_sprcFile.;\n %end;\n %end;\n%mend _sprc_check;\n\n%_sprc_check();\n\n* Run the actual code - as it uses submit/endsubmit it needs to be outside of a macro;\nproc cas;\n code = readfile('sprcScpt');\n\n gateway.runLang / args={&inputtable1. &outputtable1. &inputtable2. &outputtable2. &inputtable3. &outputtable3. &inputtable4. &outputtable4. &inputtable5. &outputtable5. &inputtable6. &outputtable6. &inputtable7. &outputtable7. &inputtable8. &outputtable8. &inputtable9. &outputtable9. &inputtable10. &outputtable10.},\n code = code,\n jitter_timeout_millis = &jitterTimeoutMillis.,\n lang = \"&_sprcLang.\",\n log_level = \"&logLevel.\",\n %if &nthreads. ne 0 %then %do; %put nthreads = &nthreads.,; %end;\n single = %if &runSingleThread. %then %do; true %end; %else %do; false %end;,\n timeout_millis = &timeoutMillis.;\nrun; quit;\n\n* Remove all macro in- and outputtable variables as they could be created by this step;\n%macro _sprc_var_clean_up();\n %local _sprc_i;\n \n %do _sprc_i = 1 %to 10;\n %symdel inputtable&_sprc_i. outputtable&_sprc_i.;\n %end;\n%mend _sprc_var_clean_up;\n\n%_sprc_var_clean_up();\n\nfilename sprcScpt clear;\n%symdel _sprcLang _sprcInCounter _sprcOutCounter;\n%sysmacdelete _sprc_check_for_engine;\n%sysmacdelete _sprc_get_caslib_name;\n%sysmacdelete _sprc_check;\n%sysmacdelete _sprc_var_clean_up;"}} \ No newline at end of file diff --git a/CAS - Submit Python and R Code/README.md b/CAS - Submit Python and R Code/README.md index 301739f6..826950b3 100644 --- a/CAS - Submit Python and R Code/README.md +++ b/CAS - Submit Python and R Code/README.md @@ -15,15 +15,15 @@ df = gateway.read_table(gateway.args['inputtable1']) # Write to output table1 gateway.write_table(df, (gateway.args['outputtable1']) - ``` - +``` + **R example:** ```r # Read from input table 1 tbl <- read_table(gw$args[['inputtable1']]) # Write to output table1 -tbl <- write_table(gw$args[['outputtable1']]) +write_table(tbl, gw$args[['outputtable1']]) ``` @@ -51,8 +51,13 @@ Find a demonstration of this step in this YouTube video: [CAS - Submit Python an ## Change Log +* Version 1.1 (20MAR2025) + * Fix Bug in from Flow Mode execution + + * Update readme + * Version 1.01 (11JAN2024) * Updated readme - + * Version 1.0 (19NOV2023) * Initial version