{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Setup" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "# Open Alteryx XML into a string \n", "import polars as pl \n", "import xml.etree.ElementTree as ET\n", "\n", "xml_file_path = \"./SimpleWorkflow/SimpleWorkflow.yxmd\"\n", "tree = ET.parse(xml_file_path)\n", "root = tree.getroot()\n", "\n", "xml_string = ET.tostring(root, encoding='unicode')\n" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "('1', 'TextInput (1)', '\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n 1\\n 4\\n \\n \\n 2\\n 5\\n \\n \\n 3\\n 6\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n ')\n", "('2', 'AlteryxSelect (2)', '\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n ')\n", "('3', 'BrowseV2 (3)', '\\n \\n \\n \\n \\n \\n C:\\\\Users\\\\casey.morter\\\\AppData\\\\Local\\\\Temp\\\\Engine_28104_a89278053b87e446bfe970eb948f1ef4_\\\\Engine_28104_9b8a61f4c39b2e4ea05f98886a386376~.yxdb\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n ')\n", "('4', 'TextInput (4)', '\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n 5\\n 8\\n z\\n a\\n \\n \\n 6\\n 9\\n b\\n d\\n \\n \\n 7\\n 10\\n c\\n c\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n ')\n", "('5', 'AlteryxSelect (5)', '\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n ')\n", "('6', 'Formula (6)', '\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n MoreCount = [Count] + 10\\n\\n \\n \\n \\n \\n \\n ')\n", "('7', 'Join (7)', '\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n ')\n", "('10', 'BrowseV2 (10)', '\\n \\n \\n \\n \\n \\n C:\\\\Users\\\\casey.morter\\\\AppData\\\\Local\\\\Temp\\\\Engine_28104_a89278053b87e446bfe970eb948f1ef4_\\\\Engine_28104_c1d268f486209c40bdc02a676a529ee0~.yxdb\\n \\n \\n \\n \\n
\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n ')\n", "('11', 'Formula (11)', '\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n Path = [Engine.TempFilePath]\\n\\n \\n \\n \\n \\n \\n ')\n", "('12', 'Sample (12)', '\\n \\n \\n \\n \\n \\n First\\n 1\\n \\n \\n \\n \\n First 1\\n \\n \\n \\n \\n \\n ')\n", "('13', 'BrowseV2 (13)', '\\n \\n \\n \\n \\n \\n C:\\\\Users\\\\casey.morter\\\\AppData\\\\Local\\\\Temp\\\\Engine_28104_a89278053b87e446bfe970eb948f1ef4_\\\\Engine_28104_4d6ee2d9de8fac4095ab55a2bceed63e~.yxdb\\n \\n \\n \\n \\n
\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n ')\n", "('14', 'DbFileOutput (14)', '\\n \\n \\n \\n \\n \\n .\\\\SimpleWorkflowOut.csv\\n \\n \\n CRLF\\n ,\\n False\\n True\\n 28591\\n True\\n \\n \\n \\n \\n \\n SimpleWorkflowOut.csv\\n \\n \\n \\n \\n \\n ')\n", "('15', 'TextInput (15)', '\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n a\\n a\\n 4\\n \\n \\n b\\n d\\n 6\\n \\n \\n c\\n z\\n 7\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n ')\n", "('16', 'HamCheeseJoin', '\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n HamCheeseJoin\\n HamCheeseJoin\\n \\n \\n \\n \\n \\n ')\n", "('17', 'BrowseV2 (17)', '\\n \\n \\n \\n \\n \\n C:\\\\Users\\\\casey.morter\\\\AppData\\\\Local\\\\Temp\\\\Engine_28104_a89278053b87e446bfe970eb948f1ef4_\\\\Engine_28104_e692dab3020ec84ebe69a5de3e6990c9~.yxdb\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n ')\n", "('18', 'BrowseV2 (18)', '\\n \\n \\n \\n \\n \\n C:\\\\Users\\\\casey.morter\\\\AppData\\\\Local\\\\Temp\\\\Engine_28104_a89278053b87e446bfe970eb948f1ef4_\\\\Engine_28104_83aac5fa43df8044b1161f8298a2a180~.yxdb\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n ')\n", "('19', 'BrowseV2 (19)', '\\n \\n \\n \\n \\n \\n C:\\\\Users\\\\casey.morter\\\\AppData\\\\Local\\\\Temp\\\\Engine_28104_a89278053b87e446bfe970eb948f1ef4_\\\\Engine_28104_c2ab20e4f5222342bc00e6424dbc38bd~.yxdb\\n \\n \\n \\n \\n
\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n ')\n" ] } ], "source": [ "# Parse out nodes (tool data) into a dict\n", "def extract_tool_id_and_contents(xml_string):\n", " root = ET.fromstring(xml_string)\n", " results = []\n", " for node in root.iter('Node'):\n", " tool_type = node.find('GuiSettings').get('Plugin').split('.')[-1]\n", " # print('tool type:',tool_type)\n", " tool_id = node.attrib.get('ToolID')\n", "\n", " tool_name = node.find('Properties/Annotation/Name').text\n", " if not tool_name:\n", " tool_name = tool_type + \" (\" + tool_id + \")\"\n", "\n", " content = ET.tostring(node, encoding='unicode')\n", " results.append((tool_id, tool_name, content))\n", " return results\n", "\n", "results = extract_tool_id_and_contents(xml_string)\n", "\n", "\n", "for tool in results:\n", " print(tool)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Tool Functions" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "def tool_select(col_spec: dict):\n", " \"\"\" Generates select tool code\"\"\"\n", " dynamic_code = \"df_output = df.with_columns(\\n\"\n", " dynamic_code_suffix = ''\n", " for old_name, (new_name, type, selected) in col_spec.items():\n", "\n", " if old_name == '*Unknown':\n", " break \n", " \n", " if new_name:\n", " alias = f\".alias('{new_name}')\"\n", " dynamic_code_suffix += f\"df_output = df_output.drop(f'{old_name}')\\n\"\n", " else:\n", " alias = ''\n", "\n", " if type is not None:\n", " if 'Int' in type:\n", " cast = f\".cast(pl.{pl.Int64})\"\n", " elif 'String' in type:\n", " cast = f\".cast(pl.{pl.String})\"\n", " else:\n", " cast = ''\n", "\n", " if selected != 'False':\n", " dynamic_code += f\"df.select(pl.col(f'{old_name}'){cast}{alias}),\\n\"\n", " else:\n", " dynamic_code_suffix += f\"df_output = df_output.drop(f'{old_name}')\\n\"\n", "\n", " dynamic_code += \")\\n\" + dynamic_code_suffix\n", " \n", " return dynamic_code" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "L: shape: (2, 4)\n", "┌──────────┬──────────┬─────┬────────┐\n", "│ Column 3 ┆ Column 4 ┆ Ham ┆ Cheese │\n", "│ --- ┆ --- ┆ --- ┆ --- │\n", "│ str ┆ str ┆ str ┆ str │\n", "╞══════════╪══════════╪═════╪════════╡\n", "│ 5 ┆ 8 ┆ z ┆ a │\n", "│ 7 ┆ 10 ┆ c ┆ c │\n", "└──────────┴──────────┴─────┴────────┘\n", "J: shape: (1, 7)\n", "┌──────────┬──────────┬─────┬────────┬───────────┬──────────────┬───────┐\n", "│ Column 3 ┆ Column 4 ┆ Ham ┆ Cheese ┆ Ham_right ┆ Cheese_right ┆ Count │\n", "│ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- │\n", "│ str ┆ str ┆ str ┆ str ┆ str ┆ str ┆ str │\n", "╞══════════╪══════════╪═════╪════════╪═══════════╪══════════════╪═══════╡\n", "│ 6 ┆ 9 ┆ b ┆ d ┆ b ┆ d ┆ 6 │\n", "└──────────┴──────────┴─────┴────────┴───────────┴──────────────┴───────┘\n", "R: shape: (2, 3)\n", "┌─────┬────────┬───────┐\n", "│ Ham ┆ Cheese ┆ Count │\n", "│ --- ┆ --- ┆ --- │\n", "│ str ┆ str ┆ str │\n", "╞═════╪════════╪═══════╡\n", "│ a ┆ a ┆ 4 │\n", "│ c ┆ z ┆ 7 │\n", "└─────┴────────┴───────┘\n" ] } ], "source": [ "def tool_join(join_spec: dict, df_L: pl.DataFrame, df_R: pl.DataFrame):\n", " \"\"\" Generates join tool code \"\"\"\n", " # dynamic_code = \"df_output = df_L.with_columns(\\n\"\n", " pass\n", "\n", " \n", "\n", "\n", "\n", "# Join spec\n", "xml_join_tool = results[6][2]\n", "join_spec = getConf_Join(xml_join_tool)\n", "\n", "# Input L: TextInput 4\n", "In_L = input_textInput(results[3][2])\n", "# Input R: TextInput 15\n", "In_R = input_textInput(results[12][2])\n", "\n", "# print(join_spec)\n", "# print(In_L, In_R)\n", "\n", "\n", "## Out L\n", "# Column 3\tColumn 4\tHam\tCheese\n", "# 7\t 10\t c\tc\n", "# 5\t 8\t z\ta\n", "\n", "## Out J\n", "# Column 3\tColumn 4\tHam\tCheese\tRight_Ham\tRight_Cheese\tCount\n", "# 6\t 9\t b\td\t b\t d\t 6\n", "\n", "## Out R\n", "# Ham\tCheese\tCount\n", "# a\t a\t 4\n", "# c\t z\t 7\n", "\n", "\n", "print(\"L:\", In_L.join(In_R, on=join_spec['joinParams'], how='anti'))\n", "\n", "print(\"J:\", In_L.join(In_R, on=join_spec['joinParams'], how='inner', coalesce=False))\n", "\n", "print(\"R:\", In_R.join(In_L, on=join_spec['joinParams'], how='anti'))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "L in: shape: (3, 3)\n", "┌─────┬─────┬─────┐\n", "│ foo ┆ bar ┆ ham │\n", "│ --- ┆ --- ┆ --- │\n", "│ i64 ┆ f64 ┆ str │\n", "╞═════╪═════╪═════╡\n", "│ 1 ┆ 6.0 ┆ a │\n", "│ 2 ┆ 7.0 ┆ b │\n", "│ 3 ┆ 8.0 ┆ c │\n", "└─────┴─────┴─────┘\n", "R in: shape: (3, 2)\n", "┌───────┬─────┐\n", "│ apple ┆ ham │\n", "│ --- ┆ --- │\n", "│ str ┆ str │\n", "╞═══════╪═════╡\n", "│ x ┆ a │\n", "│ y ┆ b │\n", "│ z ┆ d │\n", "└───────┴─────┘\n", "L: shape: (1, 3)\n", "┌─────┬─────┬─────┐\n", "│ foo ┆ bar ┆ ham │\n", "│ --- ┆ --- ┆ --- │\n", "│ i64 ┆ f64 ┆ str │\n", "╞═════╪═════╪═════╡\n", "│ 3 ┆ 8.0 ┆ c │\n", "└─────┴─────┴─────┘\n" ] } ], "source": [ "df = pl.DataFrame(\n", " {\n", " \"foo\": [1, 2, 3],\n", " \"bar\": [6.0, 7.0, 8.0],\n", " \"ham\": [\"a\", \"b\", \"c\"],\n", " }\n", ")\n", "\n", "other_df = pl.DataFrame(\n", " {\n", " \"apple\": [\"x\", \"y\", \"z\"],\n", " \"ham\": [\"a\", \"b\", \"d\"],\n", " }\n", ")\n", "\n", "print(\"L in:\", df)\n", "\n", "print(\"R in:\", other_df)\n", "\n", "print(\"L:\", df.join(other_df, left_on=\"ham\", right_on=\"ham\", how='anti'))\n", "\n", "# print(\"J: \", df.join(other_df, on=\"ham\", how='inner'))\n", "\n", "# print(\"R:\", other_df.join(df, on=\"ham\", how='anti'))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Parsing Tool Config data" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "def input_textInput(xml_string):\n", " # Get XML for a Text input tool\n", " root = ET.fromstring(xml_string)\n", " # Extract the field names\n", " fields = [field.attrib['name'] for field in root.findall(\".//Fields/Field\")]\n", " # Extract the data rows\n", " data_rows = [[c.text for c in row.findall(\"c\")] for row in root.findall(\".//Data/r\")]\n", " # Create the polars dataframe\n", " df = pl.DataFrame(data_rows, fields, orient=\"row\")\n", " # Display the dataframe\n", " return df" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "def getConf_Select(xml_string):\n", " root = ET.fromstring(xml_string)\n", " dict_SelectTool = {}\n", "\n", " for field in root.findall(\".//SelectFields/SelectField\"):\n", " field_name = field.attrib['field']\n", " field_selected = field.attrib['selected']\n", "\n", " try:\n", " field_type = field.attrib['type']\n", " except:\n", " field_type = None\n", " try:\n", " field_rename = field.attrib['rename']\n", " except:\n", " field_rename = None\n", "\n", " dict_SelectTool[field_name] = (field_rename, field_type, field_selected)\n", "\n", " return dict_SelectTool" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'joinParams': ['Ham', 'Cheese'], 'fields': {'Right_Ham': ['Right_Ham', 'Right_', None, None], 'Right_Cheese': ['Right_Cheese', 'Right_', None, None], 'Right_Column 3': ['Right_Column 3', 'Right_', 'V_String', '11'], 'Right_Column 4': ['Right_Column 4', 'Right_', 'Int64', '8']}}\n" ] } ], "source": [ "def getConf_Join(xml_string):\n", " root = ET.fromstring(xml_string)\n", " dict_JoinTool = {}\n", "\n", " # Join parameters\n", " for joinField in root.findall(\".//Configuration/JoinInfo\"):\n", " if joinField.attrib['connection'] == \"Left\":\n", " left_on = [field.attrib['field'] for field in joinField]\n", " if joinField.attrib['connection'] == \"Right\":\n", " right_on = [field.attrib['field'] for field in joinField]\n", "\n", " if left_on == right_on:\n", " dict_JoinTool['joinParams'] = (left_on)\n", " else:\n", " dict_JoinTool['joinParams'] = (left_on, right_on)\n", "\n", " \n", " # Field Parameters\n", " fieldConfig = {}\n", " for fields in root.findall(\".//SelectField\"):\n", " result = []\n", " if fields.attrib['selected'] == 'True':\n", " for field in ['rename', 'input', 'type', 'size']:\n", " try:\n", " result.append(fields.attrib[field])\n", " except KeyError:\n", " result.append(None)\n", "\n", " if fields.attrib['field'] != '*Unknown':\n", " fieldConfig[fields.attrib['field']] = result\n", "\n", " dict_JoinTool['fields'] = fieldConfig\n", "\n", " return dict_JoinTool\n", "\n", "print(getConf_Join(xml_join_tool))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Working with the XML file" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "ename": "ParseError", "evalue": "syntax error: line 1, column 0 ()", "output_type": "error", "traceback": [ "Traceback \u001b[1;36m(most recent call last)\u001b[0m:\n", "\u001b[0m File \u001b[0;32mc:\\Users\\casey.morter\\AppData\\Local\\miniconda3\\envs\\polaryx\\Lib\\site-packages\\IPython\\core\\interactiveshell.py:3577\u001b[0m in \u001b[0;35mrun_code\u001b[0m\n exec(code_obj, self.user_global_ns, self.user_ns)\u001b[0m\n", "\u001b[0m Cell \u001b[0;32mIn[11], line 6\u001b[0m\n ToolType = ET.fromstring(ToolXML).find(\".//GuiSettings\").attrib['Plugin'].split(\".\")[2]\u001b[0m\n", "\u001b[1;36m File \u001b[1;32mc:\\Users\\casey.morter\\AppData\\Local\\miniconda3\\envs\\polaryx\\Lib\\xml\\etree\\ElementTree.py:1335\u001b[1;36m in \u001b[1;35mXML\u001b[1;36m\n\u001b[1;33m parser.feed(text)\u001b[1;36m\n", "\u001b[1;36m File \u001b[1;32m\u001b[1;36m\u001b[0m\n\u001b[1;31mParseError\u001b[0m\u001b[1;31m:\u001b[0m syntax error: line 1, column 0\n" ] } ], "source": [ "# Parse all tools in tools dict\n", "for tool in results:\n", "\n", " ToolID = tool[0]\n", " ToolXML = tool[1]\n", " ToolType = ET.fromstring(ToolXML).find(\".//GuiSettings\").attrib['Plugin'].split(\".\")[2]\n", "\n", " print(ToolID, ToolType)\n", "\n", " if ToolType == 'TextInput':\n", " print(input_textInput(ToolXML))" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "############### Input dataframe (TextInput):\n", " shape: (3, 4)\n", "┌──────────┬──────────┬─────┬────────┐\n", "│ Column 3 ┆ Column 4 ┆ Ham ┆ Cheese │\n", "│ --- ┆ --- ┆ --- ┆ --- │\n", "│ str ┆ str ┆ str ┆ str │\n", "╞══════════╪══════════╪═════╪════════╡\n", "│ 5 ┆ 8 ┆ z ┆ a │\n", "│ 6 ┆ 9 ┆ b ┆ d │\n", "│ 7 ┆ 10 ┆ c ┆ c │\n", "└──────────┴──────────┴─────┴────────┘\n", "\n", "############### Generated code from Select tool: \n", " df_output = df.with_columns(\n", "df.select(pl.col(f'Column 3').alias('Col_3_renamed')),\n", ")\n", "df_output = df_output.drop(f'Column 3')\n", "df_output = df_output.drop(f'Column 4')\n", "\n", "\n", "############### Output DF: \n", "\n", " shape: (3, 3)\n", "┌─────┬────────┬───────────────┐\n", "│ Ham ┆ Cheese ┆ Col_3_renamed │\n", "│ --- ┆ --- ┆ --- │\n", "│ str ┆ str ┆ str │\n", "╞═════╪════════╪═══════════════╡\n", "│ z ┆ a ┆ 5 │\n", "│ b ┆ d ┆ 6 │\n", "│ c ┆ c ┆ 7 │\n", "└─────┴────────┴───────────────┘\n" ] } ], "source": [ "# Tool 1: TextInput\n", "xml_tool1 = results[3][2]\n", "df_in = input_textInput(xml_tool1)\n", "print(\"\\n############### Input dataframe (TextInput):\\n\", df_in)\n", "# Tool 2: Select\n", "col_spec = getConf_Select(results[4][2])\n", "# Generate code from \n", "code = tool_select(col_spec)\n", "print(\"\\n############### Generated code from Select tool: \\n\", code)\n", "# Execute and display output\n", "df = df_in\n", "exec(code)\n", "print(\"\\n############### Output DF: \\n\\n\", df_output)" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "('1', 'TextInput (1)', '\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n 1\\n 4\\n \\n \\n 2\\n 5\\n \\n \\n 3\\n 6\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n ')\n", "('2', 'AlteryxSelect (2)', '\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n ')\n", "('3', 'BrowseV2 (3)', '\\n \\n \\n \\n \\n \\n C:\\\\Users\\\\casey.morter\\\\AppData\\\\Local\\\\Temp\\\\Engine_28104_a89278053b87e446bfe970eb948f1ef4_\\\\Engine_28104_9b8a61f4c39b2e4ea05f98886a386376~.yxdb\\n \\n \\n \\n \\n
\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n ')\n", "('4', 'TextInput (4)', '\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n 5\\n 8\\n z\\n a\\n \\n \\n 6\\n 9\\n b\\n d\\n \\n \\n 7\\n 10\\n c\\n c\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n ')\n", "('5', 'AlteryxSelect (5)', '\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n ')\n", "('6', 'Formula (6)', '\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n MoreCount = [Count] + 10\\n\\n \\n \\n \\n \\n \\n ')\n", "('7', 'Join (7)', '\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n ')\n", "('10', 'BrowseV2 (10)', '\\n \\n \\n \\n \\n \\n C:\\\\Users\\\\casey.morter\\\\AppData\\\\Local\\\\Temp\\\\Engine_28104_a89278053b87e446bfe970eb948f1ef4_\\\\Engine_28104_c1d268f486209c40bdc02a676a529ee0~.yxdb\\n \\n \\n \\n \\n
\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n ')\n", "('11', 'Formula (11)', '\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n Path = [Engine.TempFilePath]\\n\\n \\n \\n \\n \\n \\n ')\n", "('12', 'Sample (12)', '\\n \\n \\n \\n \\n \\n First\\n 1\\n \\n \\n \\n \\n First 1\\n \\n \\n \\n \\n \\n ')\n", "('13', 'BrowseV2 (13)', '\\n \\n \\n \\n \\n \\n C:\\\\Users\\\\casey.morter\\\\AppData\\\\Local\\\\Temp\\\\Engine_28104_a89278053b87e446bfe970eb948f1ef4_\\\\Engine_28104_4d6ee2d9de8fac4095ab55a2bceed63e~.yxdb\\n \\n \\n \\n \\n
\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n ')\n", "('14', 'DbFileOutput (14)', '\\n \\n \\n \\n \\n \\n .\\\\SimpleWorkflowOut.csv\\n \\n \\n CRLF\\n ,\\n False\\n True\\n 28591\\n True\\n \\n \\n \\n \\n \\n SimpleWorkflowOut.csv\\n \\n \\n \\n \\n \\n ')\n", "('15', 'TextInput (15)', '\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n a\\n a\\n 4\\n \\n \\n b\\n d\\n 6\\n \\n \\n c\\n z\\n 7\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n ')\n", "('16', 'HamCheeseJoin', '\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n HamCheeseJoin\\n HamCheeseJoin\\n \\n \\n \\n \\n \\n ')\n", "('17', 'BrowseV2 (17)', '\\n \\n \\n \\n \\n \\n C:\\\\Users\\\\casey.morter\\\\AppData\\\\Local\\\\Temp\\\\Engine_28104_a89278053b87e446bfe970eb948f1ef4_\\\\Engine_28104_e692dab3020ec84ebe69a5de3e6990c9~.yxdb\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n ')\n", "('18', 'BrowseV2 (18)', '\\n \\n \\n \\n \\n \\n C:\\\\Users\\\\casey.morter\\\\AppData\\\\Local\\\\Temp\\\\Engine_28104_a89278053b87e446bfe970eb948f1ef4_\\\\Engine_28104_83aac5fa43df8044b1161f8298a2a180~.yxdb\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n ')\n", "('19', 'BrowseV2 (19)', '\\n \\n \\n \\n \\n \\n C:\\\\Users\\\\casey.morter\\\\AppData\\\\Local\\\\Temp\\\\Engine_28104_a89278053b87e446bfe970eb948f1ef4_\\\\Engine_28104_c2ab20e4f5222342bc00e6424dbc38bd~.yxdb\\n \\n \\n \\n \\n
\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n ')\n" ] } ], "source": [ "for tool in results:\n", " print(tool)" ] }, { "cell_type": "markdown", "metadata": { "vscode": { "languageId": "latex" } }, "source": [ "# DAG Analysis" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Requirement already satisfied: networkx in c:\\users\\casey.morter\\appdata\\local\\miniconda3\\lib\\site-packages (2.8.8)\n", "Requirement already satisfied: matplotlib in c:\\users\\casey.morter\\appdata\\local\\miniconda3\\lib\\site-packages (3.7.1)\n", "Requirement already satisfied: pyparsing>=2.3.1 in c:\\users\\casey.morter\\appdata\\local\\miniconda3\\lib\\site-packages (from matplotlib) (3.0.9)\n", "Requirement already satisfied: numpy>=1.20 in c:\\users\\casey.morter\\appdata\\local\\miniconda3\\lib\\site-packages (from matplotlib) (1.24.2)\n", "Requirement already satisfied: python-dateutil>=2.7 in c:\\users\\casey.morter\\appdata\\local\\miniconda3\\lib\\site-packages (from matplotlib) (2.8.2)\n", "Requirement already satisfied: cycler>=0.10 in c:\\users\\casey.morter\\appdata\\local\\miniconda3\\lib\\site-packages (from matplotlib) (0.11.0)\n", "Requirement already satisfied: pillow>=6.2.0 in c:\\users\\casey.morter\\appdata\\local\\miniconda3\\lib\\site-packages (from matplotlib) (9.4.0)\n", "Requirement already satisfied: kiwisolver>=1.0.1 in c:\\users\\casey.morter\\appdata\\local\\miniconda3\\lib\\site-packages (from matplotlib) (1.4.4)\n", "Requirement already satisfied: contourpy>=1.0.1 in c:\\users\\casey.morter\\appdata\\local\\miniconda3\\lib\\site-packages (from matplotlib) (1.0.7)\n", "Requirement already satisfied: packaging>=20.0 in c:\\users\\casey.morter\\appdata\\local\\miniconda3\\lib\\site-packages (from matplotlib) (24.0)\n", "Requirement already satisfied: fonttools>=4.22.0 in c:\\users\\casey.morter\\appdata\\local\\miniconda3\\lib\\site-packages (from matplotlib) (4.39.0)\n", "Requirement already satisfied: six>=1.5 in c:\\users\\casey.morter\\appdata\\local\\miniconda3\\lib\\site-packages (from python-dateutil>=2.7->matplotlib) (1.16.0)\n", "Note: you may need to restart the kernel to use updated packages.\n" ] } ], "source": [ "%pip install networkx matplotlib" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAABKUAAAMWCAYAAAAgRDUeAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAVVElEQVR4nO3YMQEAIAzAMMC/5+GiHCQKenfPzCwAAAAACJ3XAQAAAAD8x5QCAAAAIGdKAQAAAJAzpQAAAADImVIAAAAA5EwpAAAAAHKmFAAAAAA5UwoAAACAnCkFAAAAQM6UAgAAACBnSgEAAACQM6UAAAAAyJlSAAAAAORMKQAAAAByphQAAAAAOVMKAAAAgJwpBQAAAEDOlAIAAAAgZ0oBAAAAkDOlAAAAAMiZUgAAAADkTCkAAAAAcqYUAAAAADlTCgAAAICcKQUAAABAzpQCAAAAIGdKAQAAAJAzpQAAAADImVIAAAAA5EwpAAAAAHKmFAAAAAA5UwoAAACAnCkFAAAAQM6UAgAAACBnSgEAAACQM6UAAAAAyJlSAAAAAORMKQAAAAByphQAAAAAOVMKAAAAgJwpBQAAAEDOlAIAAAAgZ0oBAAAAkDOlAAAAAMiZUgAAAADkTCkAAAAAcqYUAAAAADlTCgAAAICcKQUAAABAzpQCAAAAIGdKAQAAAJAzpQAAAADImVIAAAAA5EwpAAAAAHKmFAAAAAA5UwoAAACAnCkFAAAAQM6UAgAAACBnSgEAAACQM6UAAAAAyJlSAAAAAORMKQAAAAByphQAAAAAOVMKAAAAgJwpBQAAAEDOlAIAAAAgZ0oBAAAAkDOlAAAAAMiZUgAAAADkTCkAAAAAcqYUAAAAADlTCgAAAICcKQUAAABAzpQCAAAAIGdKAQAAAJAzpQAAAADImVIAAAAA5EwpAAAAAHKmFAAAAAA5UwoAAACAnCkFAAAAQM6UAgAAACBnSgEAAACQM6UAAAAAyJlSAAAAAORMKQAAAAByphQAAAAAOVMKAAAAgJwpBQAAAEDOlAIAAAAgZ0oBAAAAkDOlAAAAAMiZUgAAAADkTCkAAAAAcqYUAAAAADlTCgAAAICcKQUAAABAzpQCAAAAIGdKAQAAAJAzpQAAAADImVIAAAAA5EwpAAAAAHKmFAAAAAA5UwoAAACAnCkFAAAAQM6UAgAAACBnSgEAAACQM6UAAAAAyJlSAAAAAORMKQAAAAByphQAAAAAOVMKAAAAgJwpBQAAAEDOlAIAAAAgZ0oBAAAAkDOlAAAAAMiZUgAAAADkTCkAAAAAcqYUAAAAADlTCgAAAICcKQUAAABAzpQCAAAAIGdKAQAAAJAzpQAAAADImVIAAAAA5EwpAAAAAHKmFAAAAAA5UwoAAACAnCkFAAAAQM6UAgAAACBnSgEAAACQM6UAAAAAyJlSAAAAAORMKQAAAAByphQAAAAAOVMKAAAAgJwpBQAAAEDOlAIAAAAgZ0oBAAAAkDOlAAAAAMiZUgAAAADkTCkAAAAAcqYUAAAAADlTCgAAAICcKQUAAABAzpQCAAAAIGdKAQAAAJAzpQAAAADImVIAAAAA5EwpAAAAAHKmFAAAAAA5UwoAAACAnCkFAAAAQM6UAgAAACBnSgEAAACQM6UAAAAAyJlSAAAAAORMKQAAAAByphQAAAAAOVMKAAAAgJwpBQAAAEDOlAIAAAAgZ0oBAAAAkDOlAAAAAMiZUgAAAADkTCkAAAAAcqYUAAAAADlTCgAAAICcKQUAAABAzpQCAAAAIGdKAQAAAJAzpQAAAADImVIAAAAA5EwpAAAAAHKmFAAAAAA5UwoAAACAnCkFAAAAQM6UAgAAACBnSgEAAACQM6UAAAAAyJlSAAAAAORMKQAAAAByphQAAAAAOVMKAAAAgJwpBQAAAEDOlAIAAAAgZ0oBAAAAkDOlAAAAAMiZUgAAAADkTCkAAAAAcqYUAAAAADlTCgAAAICcKQUAAABAzpQCAAAAIGdKAQAAAJAzpQAAAADImVIAAAAA5EwpAAAAAHKmFAAAAAA5UwoAAACAnCkFAAAAQM6UAgAAACBnSgEAAACQM6UAAAAAyJlSAAAAAORMKQAAAAByphQAAAAAOVMKAAAAgJwpBQAAAEDOlAIAAAAgZ0oBAAAAkDOlAAAAAMiZUgAAAADkTCkAAAAAcqYUAAAAADlTCgAAAICcKQUAAABAzpQCAAAAIGdKAQAAAJAzpQAAAADImVIAAAAA5EwpAAAAAHKmFAAAAAA5UwoAAACAnCkFAAAAQM6UAgAAACBnSgEAAACQM6UAAAAAyJlSAAAAAORMKQAAAAByphQAAAAAOVMKAAAAgJwpBQAAAEDOlAIAAAAgZ0oBAAAAkDOlAAAAAMiZUgAAAADkTCkAAAAAcqYUAAAAADlTCgAAAICcKQUAAABAzpQCAAAAIGdKAQAAAJAzpQAAAADImVIAAAAA5EwpAAAAAHKmFAAAAAA5UwoAAACAnCkFAAAAQM6UAgAAACBnSgEAAACQM6UAAAAAyJlSAAAAAORMKQAAAAByphQAAAAAOVMKAAAAgJwpBQAAAEDOlAIAAAAgZ0oBAAAAkDOlAAAAAMiZUgAAAADkTCkAAAAAcqYUAAAAADlTCgAAAICcKQUAAABAzpQCAAAAIGdKAQAAAJAzpQAAAADImVIAAAAA5EwpAAAAAHKmFAAAAAA5UwoAAACAnCkFAAAAQM6UAgAAACBnSgEAAACQM6UAAAAAyJlSAAAAAORMKQAAAAByphQAAAAAOVMKAAAAgJwpBQAAAEDOlAIAAAAgZ0oBAAAAkDOlAAAAAMiZUgAAAADkTCkAAAAAcqYUAAAAADlTCgAAAICcKQUAAABAzpQCAAAAIGdKAQAAAJAzpQAAAADImVIAAAAA5EwpAAAAAHKmFAAAAAA5UwoAAACAnCkFAAAAQM6UAgAAACBnSgEAAACQM6UAAAAAyJlSAAAAAORMKQAAAAByphQAAAAAOVMKAAAAgJwpBQAAAEDOlAIAAAAgZ0oBAAAAkDOlAAAAAMiZUgAAAADkTCkAAAAAcqYUAAAAADlTCgAAAICcKQUAAABAzpQCAAAAIGdKAQAAAJAzpQAAAADImVIAAAAA5EwpAAAAAHKmFAAAAAA5UwoAAACAnCkFAAAAQM6UAgAAACBnSgEAAACQM6UAAAAAyJlSAAAAAORMKQAAAAByphQAAAAAOVMKAAAAgJwpBQAAAEDOlAIAAAAgZ0oBAAAAkDOlAAAAAMiZUgAAAADkTCkAAAAAcqYUAAAAADlTCgAAAICcKQUAAABAzpQCAAAAIGdKAQAAAJAzpQAAAADImVIAAAAA5EwpAAAAAHKmFAAAAAA5UwoAAACAnCkFAAAAQM6UAgAAACBnSgEAAACQM6UAAAAAyJlSAAAAAORMKQAAAAByphQAAAAAOVMKAAAAgJwpBQAAAEDOlAIAAAAgZ0oBAAAAkDOlAAAAAMiZUgAAAADkTCkAAAAAcqYUAAAAADlTCgAAAICcKQUAAABAzpQCAAAAIGdKAQAAAJAzpQAAAADImVIAAAAA5EwpAAAAAHKmFAAAAAA5UwoAAACAnCkFAAAAQM6UAgAAACBnSgEAAACQM6UAAAAAyJlSAAAAAORMKQAAAAByphQAAAAAOVMKAAAAgJwpBQAAAEDOlAIAAAAgZ0oBAAAAkDOlAAAAAMiZUgAAAADkTCkAAAAAcqYUAAAAADlTCgAAAICcKQUAAABAzpQCAAAAIGdKAQAAAJAzpQAAAADImVIAAAAA5EwpAAAAAHKmFAAAAAA5UwoAAACAnCkFAAAAQM6UAgAAACBnSgEAAACQM6UAAAAAyJlSAAAAAORMKQAAAAByphQAAAAAOVMKAAAAgJwpBQAAAEDOlAIAAAAgZ0oBAAAAkDOlAAAAAMiZUgAAAADkTCkAAAAAcqYUAAAAADlTCgAAAICcKQUAAABAzpQCAAAAIGdKAQAAAJAzpQAAAADImVIAAAAA5EwpAAAAAHKmFAAAAAA5UwoAAACAnCkFAAAAQM6UAgAAACBnSgEAAACQM6UAAAAAyJlSAAAAAORMKQAAAAByphQAAAAAOVMKAAAAgJwpBQAAAEDOlAIAAAAgZ0oBAAAAkDOlAAAAAMiZUgAAAADkTCkAAAAAcqYUAAAAADlTCgAAAICcKQUAAABAzpQCAAAAIGdKAQAAAJAzpQAAAADImVIAAAAA5EwpAAAAAHKmFAAAAAA5UwoAAACAnCkFAAAAQM6UAgAAACBnSgEAAACQM6UAAAAAyJlSAAAAAORMKQAAAAByphQAAAAAOVMKAAAAgJwpBQAAAEDOlAIAAAAgZ0oBAAAAkDOlAAAAAMiZUgAAAADkTCkAAAAAcqYUAAAAADlTCgAAAICcKQUAAABAzpQCAAAAIGdKAQAAAJAzpQAAAADImVIAAAAA5EwpAAAAAHKmFAAAAAA5UwoAAACAnCkFAAAAQM6UAgAAACBnSgEAAACQM6UAAAAAyJlSAAAAAORMKQAAAAByphQAAAAAOVMKAAAAgJwpBQAAAEDOlAIAAAAgZ0oBAAAAkDOlAAAAAMiZUgAAAADkTCkAAAAAcqYUAAAAADlTCgAAAICcKQUAAABAzpQCAAAAIGdKAQAAAJAzpQAAAADImVIAAAAA5EwpAAAAAHKmFAAAAAA5UwoAAACAnCkFAAAAQM6UAgAAACBnSgEAAACQM6UAAAAAyJlSAAAAAORMKQAAAAByphQAAAAAOVMKAAAAgJwpBQAAAEDOlAIAAAAgZ0oBAAAAkDOlAAAAAMiZUgAAAADkTCkAAAAAcqYUAAAAADlTCgAAAICcKQUAAABAzpQCAAAAIGdKAQAAAJAzpQAAAADImVIAAAAA5EwpAAAAAHKmFAAAAAA5UwoAAACAnCkFAAAAQM6UAgAAACBnSgEAAACQM6UAAAAAyJlSAAAAAORMKQAAAAByphQAAAAAOVMKAAAAgJwpBQAAAEDOlAIAAAAgZ0oBAAAAkDOlAAAAAMiZUgAAAADkTCkAAAAAcqYUAAAAADlTCgAAAICcKQUAAABAzpQCAAAAIGdKAQAAAJAzpQAAAADImVIAAAAA5EwpAAAAAHKmFAAAAAA5UwoAAACAnCkFAAAAQM6UAgAAACBnSgEAAACQM6UAAAAAyJlSAAAAAORMKQAAAAByphQAAAAAOVMKAAAAgJwpBQAAAEDOlAIAAAAgZ0oBAAAAkDOlAAAAAMiZUgAAAADkTCkAAAAAcqYUAAAAADlTCgAAAICcKQUAAABAzpQCAAAAIGdKAQAAAJAzpQAAAADImVIAAAAA5EwpAAAAAHKmFAAAAAA5UwoAAACAnCkFAAAAQM6UAgAAACBnSgEAAACQM6UAAAAAyJlSAAAAAORMKQAAAAByphQAAAAAOVMKAAAAgJwpBQAAAEDOlAIAAAAgZ0oBAAAAkDOlAAAAAMiZUgAAAADkTCkAAAAAcqYUAAAAADlTCgAAAICcKQUAAABAzpQCAAAAIGdKAQAAAJAzpQAAAADImVIAAAAA5EwpAAAAAHKmFAAAAAA5UwoAAACAnCkFAAAAQM6UAgAAACBnSgEAAACQM6UAAAAAyJlSAAAAAORMKQAAAAByphQAAAAAOVMKAAAAgJwpBQAAAEDOlAIAAAAgZ0oBAAAAkDOlAAAAAMiZUgAAAADkTCkAAAAAcqYUAAAAADlTCgAAAICcKQUAAABAzpQCAAAAIGdKAQAAAJAzpQAAAADImVIAAAAA5EwpAAAAAHKmFAAAAAA5UwoAAACAnCkFAAAAQM6UAgAAACBnSgEAAACQM6UAAAAAyJlSAAAAAORMKQAAAAByphQAAAAAOVMKAAAAgJwpBQAAAEDOlAIAAAAgZ0oBAAAAkDOlAAAAAMiZUgAAAADkTCkAAAAAcqYUAAAAADlTCgAAAICcKQUAAABAzpQCAAAAIGdKAQAAAJAzpQAAAADImVIAAAAA5EwpAAAAAHKmFAAAAAA5UwoAAACAnCkFAAAAQM6UAgAAACBnSgEAAACQM6UAAAAAyJlSAAAAAORMKQAAAAByphQAAAAAOVMKAAAAgJwpBQAAAEDOlAIAAAAgZ0oBAAAAkDOlAAAAAMiZUgAAAADkTCkAAAAAcqYUAAAAADlTCgAAAICcKQUAAABAzpQCAAAAIGdKAQAAAJAzpQAAAADImVIAAAAA5EwpAAAAAHKmFAAAAAA5UwoAAACAnCkFAAAAQM6UAgAAACBnSgEAAACQM6UAAAAAyJlSAAAAAORMKQAAAAByphQAAAAAOVMKAAAAgJwpBQAAAEDOlAIAAAAgZ0oBAAAAkDOlAAAAAMiZUgAAAADkTCkAAAAAcqYUAAAAADlTCgAAAICcKQUAAABAzpQCAAAAIGdKAQAAAJAzpQAAAADImVIAAAAA5EwpAAAAAHKmFAAAAAA5UwoAAACAnCkFAAAAQM6UAgAAACBnSgEAAACQM6UAAAAAyJlSAAAAAORMKQAAAAByphQAAAAAOVMKAAAAgJwpBQAAAEDOlAIAAAAgZ0oBAAAAkDOlAAAAAMiZUgAAAADkTCkAAAAAcqYUAAAAADlTCgAAAICcKQUAAABAzpQCAAAAIGdKAQAAAJAzpQAAAADImVIAAAAA5EwpAAAAAHKmFAAAAAA5UwoAAACAnCkFAAAAQM6UAgAAACBnSgEAAACQM6UAAAAAyJlSAAAAAORMKQAAAAByphQAAAAAOVMKAAAAgJwpBQAAAEDOlAIAAAAgZ0oBAAAAkDOlAAAAAMiZUgAAAADkTCkAAAAAcqYUAAAAADlTCgAAAICcKQUAAABAzpQCAAAAIGdKAQAAAJAzpQAAAADImVIAAAAA5EwpAAAAAHKmFAAAAAA5UwoAAACAnCkFAAAAQM6UAgAAACBnSgEAAACQM6UAAAAAyJlSAAAAAORMKQAAAAByphQAAAAAOVMKAAAAgJwpBQAAAEDOlAIAAAAgZ0oBAAAAkDOlAAAAAMiZUgAAAADkTCkAAAAAcqYUAAAAADlTCgAAAICcKQUAAABAzpQCAAAAIGdKAQAAAJAzpQAAAADImVIAAAAA5EwpAAAAAHKmFAAAAAA5UwoAAACAnCkFAAAAQM6UAgAAACBnSgEAAACQM6UAAAAAyJlSAAAAAORMKQAAAAByphQAAAAAOVMKAAAAgJwpBQAAAEDOlAIAAAAgZ0oBAAAAkDOlAAAAAMiZUgAAAADkTCkAAAAAcqYUAAAAADlTCgAAAICcKQUAAABAzpQCAAAAIGdKAQAAAJAzpQAAAADImVIAAAAA5EwpAAAAAHKmFAAAAAA5UwoAAACAnCkFAAAAQM6UAgAAACBnSgEAAACQM6UAAAAAyJlSAAAAAORMKQAAAAByphQAAAAAOVMKAAAAgJwpBQAAAEDOlAIAAAAgZ0oBAAAAkDOlAAAAAMiZUgAAAADkLuKFCigweeOTAAAAAElFTkSuQmCC", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import xml.etree.ElementTree as ET\n", "import networkx as nx\n", "import matplotlib.pyplot as plt\n", "\n", "def visualize_dag(xml_string):\n", " # Parse the XML string\n", " root = ET.fromstring(xml_string)\n", "\n", " # Create a directed graph\n", " G = nx.DiGraph()\n", "\n", " # Add edges to the graph\n", " for conn in root.findall('Connection'):\n", " origin = conn.find('Origin')\n", " destination = conn.find('Destination')\n", " \n", " origin_id = origin.get('ToolID')\n", " dest_id = destination.get('ToolID')\n", " origin_conn = origin.get('Connection')\n", " dest_conn = destination.get('Connection')\n", " \n", " G.add_edge(origin_id, dest_id)\n", " G.edges[origin_id, dest_id]['origin_conn'] = origin_conn\n", " G.edges[origin_id, dest_id]['dest_conn'] = dest_conn\n", "\n", " # Set up the plot\n", " plt.figure(figsize=(12, 8))\n", " pos = nx.spring_layout(G)\n", "\n", " # Draw nodes\n", " nx.draw_networkx_nodes(G, pos, node_size=2000, node_color='lightblue')\n", " nx.draw_networkx_labels(G, pos, labels={node: f\"Tool ID: {node}\" for node in G.nodes()})\n", "\n", " # Draw edges\n", " nx.draw_networkx_edges(G, pos, edge_color='gray', arrows=True, arrowsize=20)\n", "\n", " # Add edge labels\n", " edge_labels = {(u, v): f\"{d['origin_conn']} -> {d['dest_conn']}\" for u, v, d in G.edges(data=True)}\n", " nx.draw_networkx_edge_labels(G, pos, edge_labels=edge_labels, font_size=8)\n", "\n", " # Remove axis\n", " plt.axis('off')\n", "\n", " # Show the plot\n", " plt.tight_layout()\n", " plt.show()\n", "\n", "# Example usage:\n", "xml_string = \"\"\"\n", "\n", " \n", "\n", "\"\"\"\n", "visualize_dag(xml_string)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.9" } }, "nbformat": 4, "nbformat_minor": 2 }