From 947f30e5e448a96199c86789b50bec98b7c3dde2 Mon Sep 17 00:00:00 2001 From: Aleksandar Aytov Date: Thu, 11 Jul 2024 09:51:16 +0300 Subject: [PATCH] Add Transform Data Example (#106) Co-authored-by: Aleksandar Aytov --- README.md | 7 + transform-data/README.md | 71 +++++++ transform-data/catalog.json | 411 ++++++++++++++++++++++++++++++++++++ 3 files changed, 489 insertions(+) create mode 100644 transform-data/README.md create mode 100644 transform-data/catalog.json diff --git a/README.md b/README.md index b45b37e..23aed34 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ Table of Contents * [Neo](#neo) * [Scripting](#scripting) * [Automation Pilot](#automation-pilot) + * [Utility Commands](#utility-commands) * [Resources](#resources) * [Known Issues](#known-issues) * [How to obtain support](#how-to-obtain-support) @@ -117,6 +118,12 @@ After importing, you'll see a new catalog tile - **Automation Pilot Examples**. |---------|-------------| | [Backup Catalog to GitHub](backup-catalog) | Backup catalog's content to GitHub | +### Utility Commands + +| Example | Description | +|---------|-------------| +| [Transform Data](transform-data) | Transform Data between different formats - JSON, XML, YAML, and CSV | + ## Resources Check out the following resources if you want to get familiar with Automation Pilot: diff --git a/transform-data/README.md b/transform-data/README.md new file mode 100644 index 0000000..c03170d --- /dev/null +++ b/transform-data/README.md @@ -0,0 +1,71 @@ +# Transform Data + +Table of Contents + +* [Description](#description) +* [Requirements](#requirements) +* [How to use](#how-to-use) +* [Expected result](#expected-result) + +## Description + +The commands attempts to transform data from the source data type to the target data type. +Currently this commands transforming data from and to: +* JSON +* XML +* YAML +* CSV + +## Requirements + +There are no requirements to use this command. + +## How to use + +Enter the required input keys: +* data +* sourceFormat +* targetFormat + +## Expected result + +The expected result is to received the output data in the target format. + +### Examples + +* Transforming XML to JSON +Input: +``` +Hello +``` +Output: +``` +{ + "xml": { + "@name": "John", + "@age": 25, + "$": "Hello" + } +} +``` + +* Transforming JSON to CSV +Input: +``` +[ + { + "name": "John", + "age": 25 + }, + { + "name": "Monica", + "age": 23 + } +] +``` +Output: +``` +name,age +John,25 +Monica,23 +``` \ No newline at end of file diff --git a/transform-data/catalog.json b/transform-data/catalog.json new file mode 100644 index 0000000..c67aa37 --- /dev/null +++ b/transform-data/catalog.json @@ -0,0 +1,411 @@ +{ + "id": "examples-<<>>", + "technicalName": "examples", + "name": "Automation Pilot Examples", + "description": "Source: https://github.com/SAP-samples/automation-pilot-examples", + "owner": "<<>>", + "inputs": [], + "commands": [ + { + "configuration": { + "values": [], + "output": { + "output": "$(if .toXml.executed then .toXml.output.output | join(\"\\n\") elif .fromXmltoXml.executed then .fromXmltoXml.output.message elif .toYaml.executed then .toYaml.output.message elif .toCsv.executed then .toCsv.output.message elif .execution.input.targetFormat == \"JSON\" then .inputAsJson.output.message else .toXml.output.output | join(\"\\n\") end)" + }, + "executors": [ + { + "execute": "utils-sapcp:Void:1", + "input": { + "message": "$(if .execution.input.data | toObject != null then .execution.input.data else .execution.input.data | toArray end)" + }, + "alias": "toJsonFromJson", + "description": null, + "progressMessage": null, + "initialDelay": null, + "pause": null, + "when": { + "semantic": "OR", + "conditions": [ + { + "semantic": "AND", + "cases": [ + { + "expression": "$(.execution.input.sourceFormat)", + "operator": "EQUALS", + "semantic": "OR", + "values": [ + "JSON" + ] + } + ] + } + ] + }, + "validate": null, + "autoRetry": null, + "repeat": null, + "errorMessages": [], + "dryRun": null + }, + { + "execute": "utils-sapcp:Void:1", + "input": { + "message": "$(.execution.input.data | fromXml)" + }, + "alias": "toJsonFromXml", + "description": null, + "progressMessage": null, + "initialDelay": null, + "pause": null, + "when": { + "semantic": "OR", + "conditions": [ + { + "semantic": "OR", + "cases": [ + { + "expression": "$(.execution.input.sourceFormat)", + "operator": "EQUALS", + "semantic": "OR", + "values": [ + "XML" + ] + } + ] + } + ] + }, + "validate": null, + "autoRetry": null, + "repeat": null, + "errorMessages": [], + "dryRun": null + }, + { + "execute": "utils-sapcp:Void:1", + "input": { + "message": "$(.execution.input.data | fromYaml)" + }, + "alias": "toJsonFromYaml", + "description": null, + "progressMessage": null, + "initialDelay": null, + "pause": null, + "when": { + "semantic": "OR", + "conditions": [ + { + "semantic": "OR", + "cases": [ + { + "expression": "$(.execution.input.sourceFormat)", + "operator": "EQUALS", + "semantic": "OR", + "values": [ + "YAML" + ] + } + ] + } + ] + }, + "validate": null, + "autoRetry": null, + "repeat": null, + "errorMessages": [], + "dryRun": null + }, + { + "execute": "scripts-sapcp:ExecutePythonScript:1", + "input": { + "stdin": "$(.execution.input.data)", + "script": "import csv\nimport json\nimport sys\n\n# create a list\ndata = []\n\n# read from standard input\nreader = csv.DictReader(sys.stdin)\n\n# for each row in the CSV, add it to the list\nfor row in reader:\n data.append(row)\n\n# write to standard output\njson.dump(data, sys.stdout, indent=2)" + }, + "alias": "toJsonFromCSV", + "description": null, + "progressMessage": null, + "initialDelay": null, + "pause": null, + "when": { + "semantic": "OR", + "conditions": [ + { + "semantic": "OR", + "cases": [ + { + "expression": "$(.execution.input.sourceFormat)", + "operator": "EQUALS", + "semantic": "OR", + "values": [ + "CSV" + ] + } + ] + } + ] + }, + "validate": null, + "autoRetry": null, + "repeat": null, + "errorMessages": [], + "dryRun": null + }, + { + "execute": "utils-sapcp:Void:1", + "input": { + "message": "$(if .toJsonFromJson.executed then .toJsonFromJson.output.message elif .toJsonFromXml.executed then .toJsonFromXml.output.message elif .toJsonFromYaml.executed then .toJsonFromYaml.output.message elif .toJsonFromYaml.executed then .toJsonFromYaml.output.message else .toJsonFromCSV.output.result | join(\"\\n\") | toArray end)" + }, + "alias": "inputAsJson", + "description": null, + "progressMessage": null, + "initialDelay": null, + "pause": null, + "when": null, + "validate": null, + "autoRetry": null, + "repeat": null, + "errorMessages": [], + "dryRun": null + }, + { + "execute": "scripts-sapcp:ExecuteScript:2", + "input": { + "stdin": "$(.inputAsJson.output.message)", + "script": "jq -r '\n def toxml:\n . as $in |\n if type == \"object\" then\n $in | to_entries | map(\"<\\(.key)>\" + (.value | toxml) + \"\") | join(\"\")\n elif type == \"array\" then\n map(\"\" + (toxml) + \"\") | join(\"\")\n else\n tostring\n end;\n\n if type == \"array\" then\n \"\" + (map(toxml) | join(\"\")) + \"\"\n else\n toxml\n end\n'" + }, + "alias": "toXml", + "description": null, + "progressMessage": null, + "initialDelay": null, + "pause": null, + "when": { + "semantic": "OR", + "conditions": [ + { + "semantic": "AND", + "cases": [ + { + "expression": "$(.execution.input.targetFormat)", + "operator": "EQUALS", + "semantic": "OR", + "values": [ + "XML" + ] + }, + { + "expression": "$(.inputAsJson.output.message | length)", + "operator": "GREATER_THAN", + "semantic": "OR", + "values": [ + "0" + ] + }, + { + "expression": "$(.execution.input.sourceFormat)", + "operator": "NOT_EQUALS", + "semantic": "OR", + "values": [ + "XML" + ] + } + ] + } + ] + }, + "validate": null, + "autoRetry": null, + "repeat": null, + "errorMessages": [], + "dryRun": null + }, + { + "execute": "utils-sapcp:Void:1", + "input": { + "message": "$(if .execution.input.data | fromXml != null then .execution.input.data else null end)" + }, + "alias": "fromXmltoXml", + "description": null, + "progressMessage": null, + "initialDelay": null, + "pause": null, + "when": { + "semantic": "OR", + "conditions": [ + { + "semantic": "AND", + "cases": [ + { + "expression": "$(.execution.input.targetFormat)", + "operator": "EQUALS", + "semantic": "OR", + "values": [ + "XML" + ] + }, + { + "expression": "$(.execution.input.sourceFormat)", + "operator": "EQUALS", + "semantic": "OR", + "values": [ + "XML" + ] + } + ] + } + ] + }, + "validate": null, + "autoRetry": null, + "repeat": null, + "errorMessages": [], + "dryRun": null + }, + { + "execute": "utils-sapcp:Void:1", + "input": { + "message": "$(.inputAsJson.output.message | if . | toObject then . | toObject else . | toArray end | toYaml)" + }, + "alias": "toYaml", + "description": null, + "progressMessage": null, + "initialDelay": null, + "pause": null, + "when": { + "semantic": "OR", + "conditions": [ + { + "semantic": "OR", + "cases": [ + { + "expression": "$(.execution.input.targetFormat)", + "operator": "EQUALS", + "semantic": "OR", + "values": [ + "YAML" + ] + } + ] + } + ] + }, + "validate": null, + "autoRetry": null, + "repeat": null, + "errorMessages": [], + "dryRun": null + }, + { + "execute": "utils-sapcp:Void:1", + "input": { + "message": "$(.inputAsJson.output.message | toArray | [.[0] | [to_entries[].key] | join(\",\")] + (. | map(. | [to_entries[].value] | join(\",\")))| join(\"\\n\"))" + }, + "alias": "toCsv", + "description": null, + "progressMessage": null, + "initialDelay": null, + "pause": null, + "when": { + "semantic": "OR", + "conditions": [ + { + "semantic": "OR", + "cases": [ + { + "expression": "$(.execution.input.targetFormat)", + "operator": "EQUALS", + "semantic": "OR", + "values": [ + "CSV" + ] + } + ] + } + ] + }, + "validate": null, + "autoRetry": null, + "repeat": null, + "errorMessages": [], + "dryRun": null + } + ], + "listeners": [] + }, + "id": "examples-<<>>:TransformData:1", + "name": "TransformData", + "description": "Transforms data between different formats", + "catalog": "examples-<<>>", + "version": 1, + "inputKeys": { + "data": { + "type": "string", + "sensitive": false, + "required": true, + "minSize": null, + "maxSize": null, + "minValue": null, + "maxValue": null, + "allowedValues": null, + "allowedValuesFromInputKeys": null, + "suggestedValues": null, + "suggestedValuesFromInputKeys": null, + "defaultValue": null, + "defaultValueFromInput": null, + "description": null + }, + "targetFormat": { + "type": "string", + "sensitive": false, + "required": true, + "minSize": null, + "maxSize": null, + "minValue": null, + "maxValue": null, + "allowedValues": [ + "JSON", + "XML", + "YAML", + "CSV" + ], + "allowedValuesFromInputKeys": null, + "suggestedValues": null, + "suggestedValuesFromInputKeys": null, + "defaultValue": null, + "defaultValueFromInput": null, + "description": null + }, + "sourceFormat": { + "type": "string", + "sensitive": false, + "required": true, + "minSize": null, + "maxSize": null, + "minValue": null, + "maxValue": null, + "allowedValues": [ + "JSON", + "XML", + "YAML", + "CSV" + ], + "allowedValuesFromInputKeys": null, + "suggestedValues": null, + "suggestedValuesFromInputKeys": null, + "defaultValue": null, + "defaultValueFromInput": null, + "description": null + } + }, + "outputKeys": { + "output": { + "type": "string", + "sensitive": false, + "description": null + } + }, + "tags": { + "feature:priority": "medium" + } + } + ] +} \ No newline at end of file