{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "from seeq import spy\n",
    "import pandas as pd\n",
    "\n",
    "# Set the compatibility option so that you maximize the chance that SPy will remain compatible with your notebook/script\n",
    "spy.options.compatibility = 193"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div style=\"background-color: #EEFFEE;color:black; text-align: left;\">Logged in to <strong>http://localhost:34216</strong> as <strong>agent_api_key</strong>.<br>Seeq Server Version: <strong>R66.0.0-SNAPSHOT</strong><br>Seeq SDK Module Version: <strong>66.0.0</strong> @ C:\\git\\crab\\sdk\\pypi\\seeq\\sdk<br>Seeq SPy Module Version: <strong>193.0</strong> @ C:\\git\\crab\\sdk\\pypi\\seeq\\spy</div>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Log into Seeq Server if you're not using Seeq Data Lab:\n",
    "spy.login(url='http://localhost:34216', credentials_file='../credentials.key', force=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# spy.swap\n",
    "\n",
    "Performs \"asset swapping\" functionality equivalent to what you can achieve in Seeq Workbench by the \"Swap in this asset...\" button for an Asset found in the Data tab.\n",
    "\n",
    "When you create a calculated item (Signal, Condition, Scalar, Threshold Metric) that is based on stored signals that are part of an asset tree, Seeq allows you to \"swap\" the original asset that you used for a different asset that also has all of the constituent signals (named identically).\n",
    "\n",
    "You can then pull the data for the \"swapped\" calculation just like you would pull data for any other calculated item.\n",
    "\n",
    "Let's walk through an example."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Example\n",
    "\n",
    "First we will query for some signals to use in our calculation and then push a calculation based on those signals."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div style=\"background-color: #EEFFEE;color:black; text-align: left;\">Pushed successfully to datasource <strong>Seeq Data Lab [Datasource ID: Seeq Data Lab]</strong> and scoped to workbook ID <strong>0EF5BF17-09A9-66C0-869E-364B7AAAD204</strong><br>Click the following link to see what you pushed in Seeq:<br><a href=\"http://localhost:34216/0EF5BE2D-2738-FFA0-81E0-D2B058859C4D/workbook/0EF5BF17-09A9-66C0-869E-364B7AAAD204/worksheet/0EF5BF17-0A19-FBA0-AE66-FB4A92EC60AF\" target=\"_blank\">http://localhost:34216/0EF5BE2D-2738-FFA0-81E0-D2B058859C4D/workbook/0EF5BF17-09A9-66C0-869E-364B7AAAD204/worksheet/0EF5BF17-0A19-FBA0-AE66-FB4A92EC60AF</a></div>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Name</th>\n",
       "      <th>Formula</th>\n",
       "      <th>Formula Parameters</th>\n",
       "      <th>Type</th>\n",
       "      <th>Scoped To</th>\n",
       "      <th>Datasource Class</th>\n",
       "      <th>Datasource ID</th>\n",
       "      <th>Data ID</th>\n",
       "      <th>ID</th>\n",
       "      <th>Push Result</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Added</td>\n",
       "      <td>$t + 10</td>\n",
       "      <td>[t=0EF58FC2-7F42-77D0-86AC-96C7027C1771]</td>\n",
       "      <td>CalculatedSignal</td>\n",
       "      <td>0EF5BF17-09A9-66C0-869E-364B7AAAD204</td>\n",
       "      <td>Seeq Data Lab</td>\n",
       "      <td>Seeq Data Lab</td>\n",
       "      <td>[0EF5BF17-09A9-66C0-869E-364B7AAAD204] {Signal...</td>\n",
       "      <td>0EF5BF17-0F4E-FBC0-BAEB-A22BA14E8CF5</td>\n",
       "      <td>Success</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Hot</td>\n",
       "      <td>$t &gt; 80</td>\n",
       "      <td>[t=0EF58FC2-7F42-77D0-86AC-96C7027C1771]</td>\n",
       "      <td>CalculatedCondition</td>\n",
       "      <td>0EF5BF17-09A9-66C0-869E-364B7AAAD204</td>\n",
       "      <td>Seeq Data Lab</td>\n",
       "      <td>Seeq Data Lab</td>\n",
       "      <td>[0EF5BF17-09A9-66C0-869E-364B7AAAD204] {Condit...</td>\n",
       "      <td>0EF5BF17-0FB0-6640-B2EE-D23F5182D47A</td>\n",
       "      <td>Success</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>Average on One Day in 2016</td>\n",
       "      <td>$t.average(capsule('2016-12-18'))</td>\n",
       "      <td>[t=0EF58FC2-7F42-77D0-86AC-96C7027C1771]</td>\n",
       "      <td>CalculatedScalar</td>\n",
       "      <td>0EF5BF17-09A9-66C0-869E-364B7AAAD204</td>\n",
       "      <td>Seeq Data Lab</td>\n",
       "      <td>Seeq Data Lab</td>\n",
       "      <td>[0EF5BF17-09A9-66C0-869E-364B7AAAD204] {Scalar...</td>\n",
       "      <td>0EF5BF17-0F82-6010-A07C-700678029168</td>\n",
       "      <td>Success</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                         Name                            Formula  \\\n",
       "0                       Added                            $t + 10   \n",
       "1                         Hot                            $t > 80   \n",
       "2  Average on One Day in 2016  $t.average(capsule('2016-12-18'))   \n",
       "\n",
       "                         Formula Parameters                 Type  \\\n",
       "0  [t=0EF58FC2-7F42-77D0-86AC-96C7027C1771]     CalculatedSignal   \n",
       "1  [t=0EF58FC2-7F42-77D0-86AC-96C7027C1771]  CalculatedCondition   \n",
       "2  [t=0EF58FC2-7F42-77D0-86AC-96C7027C1771]     CalculatedScalar   \n",
       "\n",
       "                              Scoped To Datasource Class  Datasource ID  \\\n",
       "0  0EF5BF17-09A9-66C0-869E-364B7AAAD204    Seeq Data Lab  Seeq Data Lab   \n",
       "1  0EF5BF17-09A9-66C0-869E-364B7AAAD204    Seeq Data Lab  Seeq Data Lab   \n",
       "2  0EF5BF17-09A9-66C0-869E-364B7AAAD204    Seeq Data Lab  Seeq Data Lab   \n",
       "\n",
       "                                             Data ID  \\\n",
       "0  [0EF5BF17-09A9-66C0-869E-364B7AAAD204] {Signal...   \n",
       "1  [0EF5BF17-09A9-66C0-869E-364B7AAAD204] {Condit...   \n",
       "2  [0EF5BF17-09A9-66C0-869E-364B7AAAD204] {Scalar...   \n",
       "\n",
       "                                     ID Push Result  \n",
       "0  0EF5BF17-0F4E-FBC0-BAEB-A22BA14E8CF5     Success  \n",
       "1  0EF5BF17-0FB0-6640-B2EE-D23F5182D47A     Success  \n",
       "2  0EF5BF17-0F82-6010-A07C-700678029168     Success  "
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "area_a_df = spy.search({\n",
    "    'Path': 'Example >> Cooling Tower 1',\n",
    "    'Asset': 'Area A',\n",
    "    'Name': 'Temperature'\n",
    "})\n",
    "\n",
    "pushed_items_df = spy.push(metadata=pd.DataFrame([{\n",
    "            'Name': f'Added',\n",
    "            'Formula': '$t + 10',\n",
    "            'Formula Parameters': {'$t': area_a_df.iloc[0]}\n",
    "        }, {\n",
    "            'Name': f'Hot',\n",
    "            'Formula': '$t > 80',\n",
    "            'Formula Parameters': {'$t': area_a_df.iloc[0]}\n",
    "        }, {\n",
    "            'Name': f'Average on One Day in 2016',\n",
    "            'Formula': \"$t.average(capsule('2016-12-18'))\",\n",
    "            'Formula Parameters': {'$t': area_a_df.iloc[0]}\n",
    "        }]), workbook='SPy Documentation Examples >> spy.swap')\n",
    "\n",
    "pushed_items_df"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now we'll query for the assets to swap in for the original Area A asset that we built the calculation for:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div style=\"background-color: #EEFFEE;color:black; text-align: left;\">Query successful</div><table class=\"tex2jax_ignore\" style=\"color:black;\"><tr><td style=\"background-color: #EEFFEE;\"></td><td style=\"background-color: #EEFFEE; text-align: left;\">Path</td><td style=\"background-color: #EEFFEE; text-align: left;\">Name</td><td style=\"background-color: #EEFFEE; text-align: left;\">Type</td><td style=\"background-color: #EEFFEE; text-align: right;\">Time</td><td style=\"background-color: #EEFFEE; text-align: right;\">Count</td><td style=\"background-color: #EEFFEE; text-align: right;\">Pages</td><td style=\"background-color: #EEFFEE; text-align: left;\">Result</td></tr><tr style=\"background-color: #EEFFEE;\"><td style=\"vertical-align: top;\">0</td><td style=\"text-align: left; vertical-align: top;\">Example >> Cooling Tower 2</td><td style=\"text-align: left; vertical-align: top;\">/Area [DEF]/</td><td style=\"text-align: left; vertical-align: top;\">Asset</td><td style=\"vertical-align: top;\">00:00:00.05</td><td style=\"text-align: right; vertical-align: top;\">3</td><td style=\"text-align: right; vertical-align: top;\">1</td><td style=\"text-align: left; vertical-align: top;\">Success</td></tr></table>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>ID</th>\n",
       "      <th>Path</th>\n",
       "      <th>Asset</th>\n",
       "      <th>Name</th>\n",
       "      <th>Description</th>\n",
       "      <th>Type</th>\n",
       "      <th>Value Unit Of Measure</th>\n",
       "      <th>Datasource Name</th>\n",
       "      <th>Archived</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0EF58FC2-90AA-60E0-BEE7-242FC3F918D2</td>\n",
       "      <td>Example &gt;&gt; Cooling Tower 2</td>\n",
       "      <td>Area D</td>\n",
       "      <td>Area D</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Asset</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Example Data</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0EF58FC2-90AC-77F0-8FD2-9F21B57B5B16</td>\n",
       "      <td>Example &gt;&gt; Cooling Tower 2</td>\n",
       "      <td>Area E</td>\n",
       "      <td>Area E</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Asset</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Example Data</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0EF58FC2-90AC-77F0-9C25-FE38E1BE65AC</td>\n",
       "      <td>Example &gt;&gt; Cooling Tower 2</td>\n",
       "      <td>Area F</td>\n",
       "      <td>Area F</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Asset</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Example Data</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                     ID                        Path   Asset  \\\n",
       "0  0EF58FC2-90AA-60E0-BEE7-242FC3F918D2  Example >> Cooling Tower 2  Area D   \n",
       "1  0EF58FC2-90AC-77F0-8FD2-9F21B57B5B16  Example >> Cooling Tower 2  Area E   \n",
       "2  0EF58FC2-90AC-77F0-9C25-FE38E1BE65AC  Example >> Cooling Tower 2  Area F   \n",
       "\n",
       "     Name  Description   Type  Value Unit Of Measure Datasource Name  Archived  \n",
       "0  Area D          NaN  Asset                    NaN    Example Data     False  \n",
       "1  Area E          NaN  Asset                    NaN    Example Data     False  \n",
       "2  Area F          NaN  Asset                    NaN    Example Data     False  "
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "areas_def_df = spy.search({\n",
    "    'Path': 'Example >> Cooling Tower 2',\n",
    "    'Name': '/Area [DEF]/',\n",
    "    'Type': 'Asset'\n",
    "}, old_asset_format=False)\n",
    "\n",
    "areas_def_df"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now all we have to do is execute the `spy.swap()` command to swap in these assets and get a bunch of new IDs we can use in `spy.pull()`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div style=\"background-color: #FFEEEE;color:black; text-align: left;\">Returned 6 swapped item(s). 3 item(s) had errors, see \"Result\" column.</div><table class=\"tex2jax_ignore\" style=\"color:black;\"><tr><td style=\"background-color: #FFEEEE;\"></td><td style=\"background-color: #FFEEEE; text-align: left;\">Original ID</td><td style=\"background-color: #FFEEEE; text-align: left;\">ID</td><td style=\"background-color: #FFEEEE; text-align: left;\">Type</td><td style=\"background-color: #FFEEEE; text-align: left;\">Name</td><td style=\"background-color: #FFEEEE; text-align: left;\">Result</td><td style=\"background-color: #FFEEEE; text-align: left;\">Swap Performed</td><td style=\"background-color: #FFEEEE; text-align: left;\">Header</td></tr><tr style=\"background-color: #FFEEEE;\"><td style=\"vertical-align: top;\">0</td><td style=\"text-align: left; vertical-align: top;\">0EF5BF17-0F4E-FBC0-BAEB-A22BA14E8CF5</td><td style=\"text-align: left; vertical-align: top;\">0EF5BF17-16D0-71F0-BA8E-619B40296EEF</td><td style=\"text-align: left; vertical-align: top;\">CalculatedSignal</td><td style=\"text-align: left; vertical-align: top;\">Added</td><td style=\"text-align: left; vertical-align: top;\">Success</td><td style=\"text-align: left; vertical-align: top;\">Example >> Cooling Tower 1 >> Area A --> Example >> Cooling Tower 2 >> Area D</td><td style=\"text-align: left; vertical-align: top;\">Cooling Tower 2 >> Area D >> Added</td></tr><tr style=\"background-color: #FFEEEE;\"><td style=\"vertical-align: top;\">1</td><td style=\"text-align: left; vertical-align: top;\">0EF5BF17-0FB0-6640-B2EE-D23F5182D47A</td><td style=\"text-align: left; vertical-align: top;\">0EF5BF17-16D9-EE30-8188-87B17F1FF75A</td><td style=\"text-align: left; vertical-align: top;\">CalculatedCondition</td><td style=\"text-align: left; vertical-align: top;\">Hot</td><td style=\"text-align: left; vertical-align: top;\">Success</td><td style=\"text-align: left; vertical-align: top;\">Example >> Cooling Tower 1 >> Area A --> Example >> Cooling Tower 2 >> Area D</td><td style=\"text-align: left; vertical-align: top;\">Cooling Tower 2 >> Area D >> Hot</td></tr><tr style=\"background-color: #FFEEEE;\"><td style=\"vertical-align: top;\">2</td><td style=\"text-align: left; vertical-align: top;\">0EF5BF17-0F82-6010-A07C-700678029168</td><td style=\"text-align: left; vertical-align: top;\">0EF5BF17-16D7-7720-9BDB-043D016E338C</td><td style=\"text-align: left; vertical-align: top;\">CalculatedScalar</td><td style=\"text-align: left; vertical-align: top;\">Average on One Day in 2016</td><td style=\"text-align: left; vertical-align: top;\">Success</td><td style=\"text-align: left; vertical-align: top;\">Example >> Cooling Tower 1 >> Area A --> Example >> Cooling Tower 2 >> Area D</td><td style=\"text-align: left; vertical-align: top;\">Cooling Tower 2 >> Area D >> Average on One Day in 2016</td></tr><tr style=\"background-color: #FFEEEE;\"><td style=\"vertical-align: top;\">3</td><td style=\"text-align: left; vertical-align: top;\">0EF5BF17-0F4E-FBC0-BAEB-A22BA14E8CF5</td><td style=\"text-align: left; vertical-align: top;\">0EF5BF17-170D-6280-9BF4-1FB99CD99A66</td><td style=\"text-align: left; vertical-align: top;\">CalculatedSignal</td><td style=\"text-align: left; vertical-align: top;\">Added</td><td style=\"text-align: left; vertical-align: top;\">Success</td><td style=\"text-align: left; vertical-align: top;\">Example >> Cooling Tower 1 >> Area A --> Example >> Cooling Tower 2 >> Area E</td><td style=\"text-align: left; vertical-align: top;\">Cooling Tower 2 >> Area E >> Added</td></tr><tr style=\"background-color: #FFEEEE;\"><td style=\"vertical-align: top;\">4</td><td style=\"text-align: left; vertical-align: top;\">0EF5BF17-0FB0-6640-B2EE-D23F5182D47A</td><td style=\"text-align: left; vertical-align: top;\">0EF5BF17-170F-F990-9DEC-60E95E721628</td><td style=\"text-align: left; vertical-align: top;\">CalculatedCondition</td><td style=\"text-align: left; vertical-align: top;\">Hot</td><td style=\"text-align: left; vertical-align: top;\">Success</td><td style=\"text-align: left; vertical-align: top;\">Example >> Cooling Tower 1 >> Area A --> Example >> Cooling Tower 2 >> Area E</td><td style=\"text-align: left; vertical-align: top;\">Cooling Tower 2 >> Area E >> Hot</td></tr><tr style=\"background-color: #FFEEEE;\"><td style=\"vertical-align: top;\">5</td><td style=\"text-align: left; vertical-align: top;\">0EF5BF17-0F82-6010-A07C-700678029168</td><td style=\"text-align: left; vertical-align: top;\">0EF5BF17-1731-EC70-9DFE-C220A083CD0B</td><td style=\"text-align: left; vertical-align: top;\">CalculatedScalar</td><td style=\"text-align: left; vertical-align: top;\">Average on One Day in 2016</td><td style=\"text-align: left; vertical-align: top;\">Success</td><td style=\"text-align: left; vertical-align: top;\">Example >> Cooling Tower 1 >> Area A --> Example >> Cooling Tower 2 >> Area E</td><td style=\"text-align: left; vertical-align: top;\">Cooling Tower 2 >> Area E >> Average on One Day in 2016</td></tr><tr style=\"background-color: #FFEEEE;\"><td style=\"vertical-align: top;\">6</td><td style=\"text-align: left; vertical-align: top;\">0EF5BF17-0F4E-FBC0-BAEB-A22BA14E8CF5</td><td style=\"text-align: right; vertical-align: top;\">nan</td><td style=\"text-align: left; vertical-align: top;\">CalculatedSignal</td><td style=\"text-align: left; vertical-align: top;\">Added</td><td style=\"text-align: left; vertical-align: top;\">[SPyRuntimeError] Error finding swap for item \"Added\" (0EF5BF17-0F4E-FBC0-BAEB-A22BA14E8CF5):<br>(400) Bad Request - Temperature not swapped, unable to swap out Area A and swap in Area F</td><td style=\"text-align: right; vertical-align: top;\">nan</td><td style=\"text-align: right; vertical-align: top;\">nan</td></tr><tr style=\"background-color: #FFEEEE;\"><td style=\"vertical-align: top;\">7</td><td style=\"text-align: left; vertical-align: top;\">0EF5BF17-0FB0-6640-B2EE-D23F5182D47A</td><td style=\"text-align: right; vertical-align: top;\">nan</td><td style=\"text-align: left; vertical-align: top;\">CalculatedCondition</td><td style=\"text-align: left; vertical-align: top;\">Hot</td><td style=\"text-align: left; vertical-align: top;\">[SPyRuntimeError] Error finding swap for item \"Hot\" (0EF5BF17-0FB0-6640-B2EE-D23F5182D47A):<br>(400) Bad Request - Temperature not swapped, unable to swap out Area A and swap in Area F</td><td style=\"text-align: right; vertical-align: top;\">nan</td><td style=\"text-align: right; vertical-align: top;\">nan</td></tr><tr style=\"background-color: #FFEEEE;\"><td style=\"vertical-align: top;\">8</td><td style=\"text-align: left; vertical-align: top;\">0EF5BF17-0F82-6010-A07C-700678029168</td><td style=\"text-align: right; vertical-align: top;\">nan</td><td style=\"text-align: left; vertical-align: top;\">CalculatedScalar</td><td style=\"text-align: left; vertical-align: top;\">Average on One Day in 2016</td><td style=\"text-align: left; vertical-align: top;\">[SPyRuntimeError] Error finding swap for item \"Average on One Day in 2016\" (0EF5BF17-0F82-6010-A07C-700678029168):<br>(400) Bad Request - Temperature not swapped, unable to swap out Area A and swap in Area F</td><td style=\"text-align: right; vertical-align: top;\">nan</td><td style=\"text-align: right; vertical-align: top;\">nan</td></tr></table>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "swapped_df = spy.swap(pushed_items_df, areas_def_df, errors='catalog')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You'll notice a few things about the returned DataFrame:\n",
    "\n",
    "- The `Original ID` column corresponds to the calculated item for which we're swapping assets. The values are repeated three times because we're swapping three assets across three items (a signal, condition and scalar). That's why there's nine rows total.\n",
    "- Some of the rows don't have an `ID` field because there were errors, which can be seen in the `Result` column.\n",
    "- The `Swap Performed` column includes precise details about what was swapped. The format is `Swapped Out Asset --> Swapped In Asset`.\n",
    "\n",
    "In order to get a better look at the `Result` and `Swap Performed` columns, let's remove some of the other columns:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>ID</th>\n",
       "      <th>Name</th>\n",
       "      <th>Result</th>\n",
       "      <th>Swap Performed</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0EF5BF17-16D0-71F0-BA8E-619B40296EEF</td>\n",
       "      <td>Added</td>\n",
       "      <td>Success</td>\n",
       "      <td>Example &gt;&gt; Cooling Tower 1 &gt;&gt; Area A --&gt; Example &gt;&gt; Cooling Tower 2 &gt;&gt; Area D</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0EF5BF17-16D9-EE30-8188-87B17F1FF75A</td>\n",
       "      <td>Hot</td>\n",
       "      <td>Success</td>\n",
       "      <td>Example &gt;&gt; Cooling Tower 1 &gt;&gt; Area A --&gt; Example &gt;&gt; Cooling Tower 2 &gt;&gt; Area D</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0EF5BF17-16D7-7720-9BDB-043D016E338C</td>\n",
       "      <td>Average on One Day in 2016</td>\n",
       "      <td>Success</td>\n",
       "      <td>Example &gt;&gt; Cooling Tower 1 &gt;&gt; Area A --&gt; Example &gt;&gt; Cooling Tower 2 &gt;&gt; Area D</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0EF5BF17-170D-6280-9BF4-1FB99CD99A66</td>\n",
       "      <td>Added</td>\n",
       "      <td>Success</td>\n",
       "      <td>Example &gt;&gt; Cooling Tower 1 &gt;&gt; Area A --&gt; Example &gt;&gt; Cooling Tower 2 &gt;&gt; Area E</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0EF5BF17-170F-F990-9DEC-60E95E721628</td>\n",
       "      <td>Hot</td>\n",
       "      <td>Success</td>\n",
       "      <td>Example &gt;&gt; Cooling Tower 1 &gt;&gt; Area A --&gt; Example &gt;&gt; Cooling Tower 2 &gt;&gt; Area E</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>0EF5BF17-1731-EC70-9DFE-C220A083CD0B</td>\n",
       "      <td>Average on One Day in 2016</td>\n",
       "      <td>Success</td>\n",
       "      <td>Example &gt;&gt; Cooling Tower 1 &gt;&gt; Area A --&gt; Example &gt;&gt; Cooling Tower 2 &gt;&gt; Area E</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>NaN</td>\n",
       "      <td>Added</td>\n",
       "      <td>[SPyRuntimeError] Error finding swap for item \"Added\" (0EF5BF17-0F4E-FBC0-BAEB-A22BA14E8CF5):\\n(400) Bad Request - Temperature not swapped, unable to swap out Area A and swap in Area F</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>NaN</td>\n",
       "      <td>Hot</td>\n",
       "      <td>[SPyRuntimeError] Error finding swap for item \"Hot\" (0EF5BF17-0FB0-6640-B2EE-D23F5182D47A):\\n(400) Bad Request - Temperature not swapped, unable to swap out Area A and swap in Area F</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>NaN</td>\n",
       "      <td>Average on One Day in 2016</td>\n",
       "      <td>[SPyRuntimeError] Error finding swap for item \"Average on One Day in 2016\" (0EF5BF17-0F82-6010-A07C-700678029168):\\n(400) Bad Request - Temperature not swapped, unable to swap out Area A and swap in Area F</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                     ID                        Name  \\\n",
       "0  0EF5BF17-16D0-71F0-BA8E-619B40296EEF                       Added   \n",
       "1  0EF5BF17-16D9-EE30-8188-87B17F1FF75A                         Hot   \n",
       "2  0EF5BF17-16D7-7720-9BDB-043D016E338C  Average on One Day in 2016   \n",
       "3  0EF5BF17-170D-6280-9BF4-1FB99CD99A66                       Added   \n",
       "4  0EF5BF17-170F-F990-9DEC-60E95E721628                         Hot   \n",
       "5  0EF5BF17-1731-EC70-9DFE-C220A083CD0B  Average on One Day in 2016   \n",
       "6                                   NaN                       Added   \n",
       "7                                   NaN                         Hot   \n",
       "8                                   NaN  Average on One Day in 2016   \n",
       "\n",
       "                                                                                                                                                                                                          Result  \\\n",
       "0                                                                                                                                                                                                        Success   \n",
       "1                                                                                                                                                                                                        Success   \n",
       "2                                                                                                                                                                                                        Success   \n",
       "3                                                                                                                                                                                                        Success   \n",
       "4                                                                                                                                                                                                        Success   \n",
       "5                                                                                                                                                                                                        Success   \n",
       "6                       [SPyRuntimeError] Error finding swap for item \"Added\" (0EF5BF17-0F4E-FBC0-BAEB-A22BA14E8CF5):\\n(400) Bad Request - Temperature not swapped, unable to swap out Area A and swap in Area F   \n",
       "7                         [SPyRuntimeError] Error finding swap for item \"Hot\" (0EF5BF17-0FB0-6640-B2EE-D23F5182D47A):\\n(400) Bad Request - Temperature not swapped, unable to swap out Area A and swap in Area F   \n",
       "8  [SPyRuntimeError] Error finding swap for item \"Average on One Day in 2016\" (0EF5BF17-0F82-6010-A07C-700678029168):\\n(400) Bad Request - Temperature not swapped, unable to swap out Area A and swap in Area F   \n",
       "\n",
       "                                                                  Swap Performed  \n",
       "0  Example >> Cooling Tower 1 >> Area A --> Example >> Cooling Tower 2 >> Area D  \n",
       "1  Example >> Cooling Tower 1 >> Area A --> Example >> Cooling Tower 2 >> Area D  \n",
       "2  Example >> Cooling Tower 1 >> Area A --> Example >> Cooling Tower 2 >> Area D  \n",
       "3  Example >> Cooling Tower 1 >> Area A --> Example >> Cooling Tower 2 >> Area E  \n",
       "4  Example >> Cooling Tower 1 >> Area A --> Example >> Cooling Tower 2 >> Area E  \n",
       "5  Example >> Cooling Tower 1 >> Area A --> Example >> Cooling Tower 2 >> Area E  \n",
       "6                                                                            NaN  \n",
       "7                                                                            NaN  \n",
       "8                                                                            NaN  "
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.set_option('display.max_colwidth', None)\n",
    "swapped_df[['ID', 'Name', 'Result', 'Swap Performed']]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In Seeq's Example data, Area F does not include a `Temperature` signal, so `spy.swap()` could not create a swapped calculation for that particular asset.\n",
    "\n",
    "For the swaps that succeeded, you can now pull the data for these swapped items like so:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div style=\"background-color: #EEFFEE;color:black; text-align: left;\">Pull successful from <strong>2021-01-01 00:00:00+00:00</strong> to <strong>2021-01-02 00:00:00+00:00</strong></div><table class=\"tex2jax_ignore\" style=\"color:black;\"><tr><td style=\"background-color: #EEFFEE;\"></td><td style=\"background-color: #EEFFEE; text-align: left;\">ID</td><td style=\"background-color: #EEFFEE; text-align: left;\">Type</td><td style=\"background-color: #EEFFEE; text-align: left;\">Name</td><td style=\"background-color: #EEFFEE; text-align: left;\">Header</td><td style=\"background-color: #EEFFEE; text-align: right;\">Time</td><td style=\"background-color: #EEFFEE; text-align: right;\">Count</td><td style=\"background-color: #EEFFEE; text-align: right;\">Pages</td><td style=\"background-color: #EEFFEE; text-align: left;\">Data Processed</td><td style=\"background-color: #EEFFEE; text-align: left;\">Result</td></tr><tr style=\"background-color: #EEFFEE;\"><td style=\"vertical-align: top;\">0</td><td style=\"text-align: left; vertical-align: top;\">0EF5BF17-16D0-71F0-BA8E-619B40296EEF</td><td style=\"text-align: left; vertical-align: top;\">CalculatedSignal</td><td style=\"text-align: left; vertical-align: top;\">Added</td><td style=\"text-align: left; vertical-align: top;\">Cooling Tower 2 >> Area D >> Added</td><td style=\"vertical-align: top;\">00:00:00.20</td><td style=\"text-align: right; vertical-align: top;\">97</td><td style=\"text-align: right; vertical-align: top;\">1</td><td style=\"text-align: right; vertical-align: top;\">11 KB</td><td style=\"text-align: left; vertical-align: top;\">Success</td></tr><tr style=\"background-color: #EEFFEE;\"><td style=\"vertical-align: top;\">1</td><td style=\"text-align: left; vertical-align: top;\">0EF5BF17-16D9-EE30-8188-87B17F1FF75A</td><td style=\"text-align: left; vertical-align: top;\">CalculatedCondition</td><td style=\"text-align: left; vertical-align: top;\">Hot</td><td style=\"text-align: left; vertical-align: top;\">Cooling Tower 2 >> Area D >> Hot</td><td style=\"vertical-align: top;\">00:00:00.08</td><td style=\"text-align: right; vertical-align: top;\">2</td><td style=\"text-align: right; vertical-align: top;\">1</td><td style=\"text-align: right; vertical-align: top;\">11 KB</td><td style=\"text-align: left; vertical-align: top;\">Success</td></tr><tr style=\"background-color: #EEFFEE;\"><td style=\"vertical-align: top;\">2</td><td style=\"text-align: left; vertical-align: top;\">0EF5BF17-16D7-7720-9BDB-043D016E338C</td><td style=\"text-align: left; vertical-align: top;\">CalculatedScalar</td><td style=\"text-align: left; vertical-align: top;\">Average on One Day in 2016</td><td style=\"text-align: left; vertical-align: top;\">Cooling Tower 2 >> Area D >> Average on One Day in 2016</td><td style=\"vertical-align: top;\">00:00:00.26</td><td style=\"text-align: right; vertical-align: top;\">1</td><td style=\"text-align: right; vertical-align: top;\">0</td><td style=\"text-align: right; vertical-align: top;\">11 KB</td><td style=\"text-align: left; vertical-align: top;\">Success</td></tr><tr style=\"background-color: #EEFFEE;\"><td style=\"vertical-align: top;\">3</td><td style=\"text-align: left; vertical-align: top;\">0EF5BF17-170D-6280-9BF4-1FB99CD99A66</td><td style=\"text-align: left; vertical-align: top;\">CalculatedSignal</td><td style=\"text-align: left; vertical-align: top;\">Added</td><td style=\"text-align: left; vertical-align: top;\">Cooling Tower 2 >> Area E >> Added</td><td style=\"vertical-align: top;\">00:00:00.20</td><td style=\"text-align: right; vertical-align: top;\">97</td><td style=\"text-align: right; vertical-align: top;\">1</td><td style=\"text-align: right; vertical-align: top;\">11 KB</td><td style=\"text-align: left; vertical-align: top;\">Success</td></tr><tr style=\"background-color: #EEFFEE;\"><td style=\"vertical-align: top;\">4</td><td style=\"text-align: left; vertical-align: top;\">0EF5BF17-170F-F990-9DEC-60E95E721628</td><td style=\"text-align: left; vertical-align: top;\">CalculatedCondition</td><td style=\"text-align: left; vertical-align: top;\">Hot</td><td style=\"text-align: left; vertical-align: top;\">Cooling Tower 2 >> Area E >> Hot</td><td style=\"vertical-align: top;\">00:00:00.08</td><td style=\"text-align: right; vertical-align: top;\">2</td><td style=\"text-align: right; vertical-align: top;\">1</td><td style=\"text-align: right; vertical-align: top;\">11 KB</td><td style=\"text-align: left; vertical-align: top;\">Success</td></tr><tr style=\"background-color: #EEFFEE;\"><td style=\"vertical-align: top;\">5</td><td style=\"text-align: left; vertical-align: top;\">0EF5BF17-1731-EC70-9DFE-C220A083CD0B</td><td style=\"text-align: left; vertical-align: top;\">CalculatedScalar</td><td style=\"text-align: left; vertical-align: top;\">Average on One Day in 2016</td><td style=\"text-align: left; vertical-align: top;\">Cooling Tower 2 >> Area E >> Average on One Day in 2016</td><td style=\"vertical-align: top;\">00:00:00.26</td><td style=\"text-align: right; vertical-align: top;\">1</td><td style=\"text-align: right; vertical-align: top;\">0</td><td style=\"text-align: right; vertical-align: top;\">11 KB</td><td style=\"text-align: left; vertical-align: top;\">Success</td></tr></table>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Cooling Tower 2 &gt;&gt; Area D &gt;&gt; Added</th>\n",
       "      <th>Cooling Tower 2 &gt;&gt; Area D &gt;&gt; Hot</th>\n",
       "      <th>Cooling Tower 2 &gt;&gt; Area D &gt;&gt; Average on One Day in 2016</th>\n",
       "      <th>Cooling Tower 2 &gt;&gt; Area E &gt;&gt; Added</th>\n",
       "      <th>Cooling Tower 2 &gt;&gt; Area E &gt;&gt; Hot</th>\n",
       "      <th>Cooling Tower 2 &gt;&gt; Area E &gt;&gt; Average on One Day in 2016</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2021-01-01 00:00:00+00:00</th>\n",
       "      <td>96.583716</td>\n",
       "      <td>1.0</td>\n",
       "      <td>75.860678</td>\n",
       "      <td>101.209415</td>\n",
       "      <td>1.0</td>\n",
       "      <td>81.768867</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2021-01-01 00:15:00+00:00</th>\n",
       "      <td>96.990286</td>\n",
       "      <td>1.0</td>\n",
       "      <td>75.860678</td>\n",
       "      <td>100.564875</td>\n",
       "      <td>1.0</td>\n",
       "      <td>81.768867</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2021-01-01 00:30:00+00:00</th>\n",
       "      <td>97.396855</td>\n",
       "      <td>1.0</td>\n",
       "      <td>75.860678</td>\n",
       "      <td>101.359711</td>\n",
       "      <td>1.0</td>\n",
       "      <td>81.768867</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2021-01-01 00:45:00+00:00</th>\n",
       "      <td>97.803424</td>\n",
       "      <td>1.0</td>\n",
       "      <td>75.860678</td>\n",
       "      <td>101.776450</td>\n",
       "      <td>1.0</td>\n",
       "      <td>81.768867</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2021-01-01 01:00:00+00:00</th>\n",
       "      <td>98.209993</td>\n",
       "      <td>1.0</td>\n",
       "      <td>75.860678</td>\n",
       "      <td>101.785881</td>\n",
       "      <td>1.0</td>\n",
       "      <td>81.768867</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2021-01-01 23:00:00+00:00</th>\n",
       "      <td>95.488781</td>\n",
       "      <td>1.0</td>\n",
       "      <td>75.860678</td>\n",
       "      <td>101.164443</td>\n",
       "      <td>1.0</td>\n",
       "      <td>81.768867</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2021-01-01 23:15:00+00:00</th>\n",
       "      <td>95.957709</td>\n",
       "      <td>1.0</td>\n",
       "      <td>75.860678</td>\n",
       "      <td>102.506365</td>\n",
       "      <td>1.0</td>\n",
       "      <td>81.768867</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2021-01-01 23:30:00+00:00</th>\n",
       "      <td>96.318568</td>\n",
       "      <td>1.0</td>\n",
       "      <td>75.860678</td>\n",
       "      <td>103.861894</td>\n",
       "      <td>1.0</td>\n",
       "      <td>81.768867</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2021-01-01 23:45:00+00:00</th>\n",
       "      <td>97.208800</td>\n",
       "      <td>1.0</td>\n",
       "      <td>75.860678</td>\n",
       "      <td>104.494810</td>\n",
       "      <td>1.0</td>\n",
       "      <td>81.768867</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2021-01-02 00:00:00+00:00</th>\n",
       "      <td>98.798541</td>\n",
       "      <td>1.0</td>\n",
       "      <td>75.860678</td>\n",
       "      <td>105.203626</td>\n",
       "      <td>1.0</td>\n",
       "      <td>81.768867</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>97 rows × 6 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "                           Cooling Tower 2 >> Area D >> Added  \\\n",
       "2021-01-01 00:00:00+00:00                           96.583716   \n",
       "2021-01-01 00:15:00+00:00                           96.990286   \n",
       "2021-01-01 00:30:00+00:00                           97.396855   \n",
       "2021-01-01 00:45:00+00:00                           97.803424   \n",
       "2021-01-01 01:00:00+00:00                           98.209993   \n",
       "...                                                       ...   \n",
       "2021-01-01 23:00:00+00:00                           95.488781   \n",
       "2021-01-01 23:15:00+00:00                           95.957709   \n",
       "2021-01-01 23:30:00+00:00                           96.318568   \n",
       "2021-01-01 23:45:00+00:00                           97.208800   \n",
       "2021-01-02 00:00:00+00:00                           98.798541   \n",
       "\n",
       "                           Cooling Tower 2 >> Area D >> Hot  \\\n",
       "2021-01-01 00:00:00+00:00                               1.0   \n",
       "2021-01-01 00:15:00+00:00                               1.0   \n",
       "2021-01-01 00:30:00+00:00                               1.0   \n",
       "2021-01-01 00:45:00+00:00                               1.0   \n",
       "2021-01-01 01:00:00+00:00                               1.0   \n",
       "...                                                     ...   \n",
       "2021-01-01 23:00:00+00:00                               1.0   \n",
       "2021-01-01 23:15:00+00:00                               1.0   \n",
       "2021-01-01 23:30:00+00:00                               1.0   \n",
       "2021-01-01 23:45:00+00:00                               1.0   \n",
       "2021-01-02 00:00:00+00:00                               1.0   \n",
       "\n",
       "                           Cooling Tower 2 >> Area D >> Average on One Day in 2016  \\\n",
       "2021-01-01 00:00:00+00:00                                                75.860678   \n",
       "2021-01-01 00:15:00+00:00                                                75.860678   \n",
       "2021-01-01 00:30:00+00:00                                                75.860678   \n",
       "2021-01-01 00:45:00+00:00                                                75.860678   \n",
       "2021-01-01 01:00:00+00:00                                                75.860678   \n",
       "...                                                                            ...   \n",
       "2021-01-01 23:00:00+00:00                                                75.860678   \n",
       "2021-01-01 23:15:00+00:00                                                75.860678   \n",
       "2021-01-01 23:30:00+00:00                                                75.860678   \n",
       "2021-01-01 23:45:00+00:00                                                75.860678   \n",
       "2021-01-02 00:00:00+00:00                                                75.860678   \n",
       "\n",
       "                           Cooling Tower 2 >> Area E >> Added  \\\n",
       "2021-01-01 00:00:00+00:00                          101.209415   \n",
       "2021-01-01 00:15:00+00:00                          100.564875   \n",
       "2021-01-01 00:30:00+00:00                          101.359711   \n",
       "2021-01-01 00:45:00+00:00                          101.776450   \n",
       "2021-01-01 01:00:00+00:00                          101.785881   \n",
       "...                                                       ...   \n",
       "2021-01-01 23:00:00+00:00                          101.164443   \n",
       "2021-01-01 23:15:00+00:00                          102.506365   \n",
       "2021-01-01 23:30:00+00:00                          103.861894   \n",
       "2021-01-01 23:45:00+00:00                          104.494810   \n",
       "2021-01-02 00:00:00+00:00                          105.203626   \n",
       "\n",
       "                           Cooling Tower 2 >> Area E >> Hot  \\\n",
       "2021-01-01 00:00:00+00:00                               1.0   \n",
       "2021-01-01 00:15:00+00:00                               1.0   \n",
       "2021-01-01 00:30:00+00:00                               1.0   \n",
       "2021-01-01 00:45:00+00:00                               1.0   \n",
       "2021-01-01 01:00:00+00:00                               1.0   \n",
       "...                                                     ...   \n",
       "2021-01-01 23:00:00+00:00                               1.0   \n",
       "2021-01-01 23:15:00+00:00                               1.0   \n",
       "2021-01-01 23:30:00+00:00                               1.0   \n",
       "2021-01-01 23:45:00+00:00                               1.0   \n",
       "2021-01-02 00:00:00+00:00                               1.0   \n",
       "\n",
       "                           Cooling Tower 2 >> Area E >> Average on One Day in 2016  \n",
       "2021-01-01 00:00:00+00:00                                                81.768867  \n",
       "2021-01-01 00:15:00+00:00                                                81.768867  \n",
       "2021-01-01 00:30:00+00:00                                                81.768867  \n",
       "2021-01-01 00:45:00+00:00                                                81.768867  \n",
       "2021-01-01 01:00:00+00:00                                                81.768867  \n",
       "...                                                                            ...  \n",
       "2021-01-01 23:00:00+00:00                                                81.768867  \n",
       "2021-01-01 23:15:00+00:00                                                81.768867  \n",
       "2021-01-01 23:30:00+00:00                                                81.768867  \n",
       "2021-01-01 23:45:00+00:00                                                81.768867  \n",
       "2021-01-02 00:00:00+00:00                                                81.768867  \n",
       "\n",
       "[97 rows x 6 columns]"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# First we'll drop the rows that had errors.\n",
    "successful_swaps_df = swapped_df[swapped_df['Result'] == 'Success']\n",
    "\n",
    "spy.pull(successful_swaps_df, start='2021-01-01', end='2021-01-02')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Multi-asset Swaps\n",
    "\n",
    "Calculations can be based on more than one asset. That means swapping is more complex, because you must specify a pairing for each swappable asset. You accomplish this using \"Swap Groups\".\n",
    "\n",
    "In the following example, we'll push a calculation that is a summation of `Compressor Power` for Area A and Area B. Then we'll swap out those assets for Areas D & E and then again for Areas D & F."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div style=\"background-color: #EEFFEE;color:black; text-align: left;\">Query successful</div><table class=\"tex2jax_ignore\" style=\"color:black;\"><tr><td style=\"background-color: #EEFFEE;\"></td><td style=\"background-color: #EEFFEE; text-align: left;\">Name</td><td style=\"background-color: #EEFFEE; text-align: right;\">Time</td><td style=\"background-color: #EEFFEE; text-align: right;\">Count</td><td style=\"background-color: #EEFFEE; text-align: right;\">Pages</td><td style=\"background-color: #EEFFEE; text-align: left;\">Result</td></tr><tr style=\"background-color: #EEFFEE;\"><td style=\"vertical-align: top;\">0</td><td style=\"text-align: left; vertical-align: top;\">Added Together</td><td style=\"vertical-align: top;\">00:00:00.01</td><td style=\"text-align: right; vertical-align: top;\">1</td><td style=\"text-align: right; vertical-align: top;\">1</td><td style=\"text-align: left; vertical-align: top;\">Success</td></tr></table>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>ID</th>\n",
       "      <th>Name</th>\n",
       "      <th>Description</th>\n",
       "      <th>Type</th>\n",
       "      <th>Value Unit Of Measure</th>\n",
       "      <th>Datasource Name</th>\n",
       "      <th>Archived</th>\n",
       "      <th>Swappable Assets</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0EF5BF17-25A2-7110-8D07-FF485DDCEDB7</td>\n",
       "      <td>Added Together</td>\n",
       "      <td>NaN</td>\n",
       "      <td>CalculatedSignal</td>\n",
       "      <td>kW</td>\n",
       "      <td>Seeq Data Lab</td>\n",
       "      <td>False</td>\n",
       "      <td>ID   Type                        Path  \\\n",
       "0  0EF58FC2-90AC-77F0-85F2-91128B10372A  Asset  Example &gt;&gt; Cooling Tower 1   \n",
       "1  0EF58FC2-90AA-60E0-94F7-29D4E89DC2F9  Asset  Example &gt;&gt; Cooling Tower 1   \n",
       "\n",
       "    Asset  \n",
       "0  Area A  \n",
       "1  Area B</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                     ID            Name  Description  \\\n",
       "0  0EF5BF17-25A2-7110-8D07-FF485DDCEDB7  Added Together          NaN   \n",
       "\n",
       "               Type Value Unit Of Measure Datasource Name  Archived  \\\n",
       "0  CalculatedSignal                    kW   Seeq Data Lab     False   \n",
       "\n",
       "                                                                                                                                                                                                                                                                 Swappable Assets  \n",
       "0                                       ID   Type                        Path  \\\n",
       "0  0EF58FC2-90AC-77F0-85F2-91128B10372A  Asset  Example >> Cooling Tower 1   \n",
       "1  0EF58FC2-90AA-60E0-94F7-29D4E89DC2F9  Asset  Example >> Cooling Tower 1   \n",
       "\n",
       "    Asset  \n",
       "0  Area A  \n",
       "1  Area B    "
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "areas_df = spy.search({\n",
    "    'Path': 'Example >> Cooling Tower 1',\n",
    "    'Asset': '/Area [AB]/',\n",
    "    'Name': 'Compressor Power'\n",
    "})\n",
    "\n",
    "added_together_df = spy.push(metadata=pd.DataFrame([{\n",
    "    'Name': 'Added Together',\n",
    "    'Formula': '$a + $b',\n",
    "    'Formula Parameters': {\n",
    "        '$a': areas_df[areas_df['Asset'] == 'Area A'],\n",
    "        '$b': areas_df[areas_df['Asset'] == 'Area B']\n",
    "    }\n",
    "}]), workbook='SPy Documentation Examples >> spy.swap')\n",
    "\n",
    "added_together_df = spy.search({\n",
    "    'Name': 'Added Together'\n",
    "}, include_swappable_assets=True, workbook='SPy Documentation Examples >> spy.swap')\n",
    "\n",
    "added_together_df"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Notice that we used the `spy.search(include_swappable_assets=True)` flag, which means that the `added_together_df` DataFrame includes a `Swappable Assets` column where each cell is an embedded DataFrame detailing the assets upon which the calculation is based:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>ID</th>\n",
       "      <th>Type</th>\n",
       "      <th>Path</th>\n",
       "      <th>Asset</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0EF58FC2-90AC-77F0-85F2-91128B10372A</td>\n",
       "      <td>Asset</td>\n",
       "      <td>Example &gt;&gt; Cooling Tower 1</td>\n",
       "      <td>Area A</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0EF58FC2-90AA-60E0-94F7-29D4E89DC2F9</td>\n",
       "      <td>Asset</td>\n",
       "      <td>Example &gt;&gt; Cooling Tower 1</td>\n",
       "      <td>Area B</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                     ID   Type                        Path  \\\n",
       "0  0EF58FC2-90AC-77F0-85F2-91128B10372A  Asset  Example >> Cooling Tower 1   \n",
       "1  0EF58FC2-90AA-60E0-94F7-29D4E89DC2F9  Asset  Example >> Cooling Tower 1   \n",
       "\n",
       "    Asset  \n",
       "0  Area A  \n",
       "1  Area B  "
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "swappable_assets_df = added_together_df.iloc[0]['Swappable Assets']\n",
    "swappable_assets_df"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "That's what we need in order to specify our \"swap groups\". Now we have to create a DataFrame of assets with a `Swap Group` and `Swap Out` columns to achieve the pairing we talk about above:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div style=\"background-color: #EEFFEE;color:black; text-align: left;\">Query successful</div><table class=\"tex2jax_ignore\" style=\"color:black;\"><tr><td style=\"background-color: #EEFFEE;\"></td><td style=\"background-color: #EEFFEE; text-align: left;\">Path</td><td style=\"background-color: #EEFFEE; text-align: left;\">Type</td><td style=\"background-color: #EEFFEE; text-align: right;\">Time</td><td style=\"background-color: #EEFFEE; text-align: right;\">Count</td><td style=\"background-color: #EEFFEE; text-align: right;\">Pages</td><td style=\"background-color: #EEFFEE; text-align: left;\">Result</td></tr><tr style=\"background-color: #EEFFEE;\"><td style=\"vertical-align: top;\">0</td><td style=\"text-align: left; vertical-align: top;\">Example >> Cooling Tower 2</td><td style=\"text-align: left; vertical-align: top;\">Asset</td><td style=\"vertical-align: top;\">00:00:00.05</td><td style=\"text-align: right; vertical-align: top;\">3</td><td style=\"text-align: right; vertical-align: top;\">1</td><td style=\"text-align: left; vertical-align: top;\">Success</td></tr></table>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>ID</th>\n",
       "      <th>Path</th>\n",
       "      <th>Asset</th>\n",
       "      <th>Name</th>\n",
       "      <th>Description</th>\n",
       "      <th>Type</th>\n",
       "      <th>Value Unit Of Measure</th>\n",
       "      <th>Datasource Name</th>\n",
       "      <th>Archived</th>\n",
       "      <th>Swap Group</th>\n",
       "      <th>Swap Out</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0EF58FC2-90AA-60E0-BEE7-242FC3F918D2</td>\n",
       "      <td>Example &gt;&gt; Cooling Tower 2</td>\n",
       "      <td>Area D</td>\n",
       "      <td>Area D</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Asset</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Example Data</td>\n",
       "      <td>False</td>\n",
       "      <td>1</td>\n",
       "      <td>ID       0EF58FC2-90AC-77F0-85F2-91128B10372A\n",
       "Type                                    Asset\n",
       "Path               Example &gt;&gt; Cooling Tower 1\n",
       "Asset                                  Area A\n",
       "Name: 0, dtype: object</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0EF58FC2-90AC-77F0-8FD2-9F21B57B5B16</td>\n",
       "      <td>Example &gt;&gt; Cooling Tower 2</td>\n",
       "      <td>Area E</td>\n",
       "      <td>Area E</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Asset</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Example Data</td>\n",
       "      <td>False</td>\n",
       "      <td>1</td>\n",
       "      <td>ID       0EF58FC2-90AA-60E0-94F7-29D4E89DC2F9\n",
       "Type                                    Asset\n",
       "Path               Example &gt;&gt; Cooling Tower 1\n",
       "Asset                                  Area B\n",
       "Name: 1, dtype: object</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0EF58FC2-90AA-60E0-BEE7-242FC3F918D2</td>\n",
       "      <td>Example &gt;&gt; Cooling Tower 2</td>\n",
       "      <td>Area D</td>\n",
       "      <td>Area D</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Asset</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Example Data</td>\n",
       "      <td>False</td>\n",
       "      <td>2</td>\n",
       "      <td>ID       0EF58FC2-90AC-77F0-85F2-91128B10372A\n",
       "Type                                    Asset\n",
       "Path               Example &gt;&gt; Cooling Tower 1\n",
       "Asset                                  Area A\n",
       "Name: 0, dtype: object</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0EF58FC2-90AC-77F0-9C25-FE38E1BE65AC</td>\n",
       "      <td>Example &gt;&gt; Cooling Tower 2</td>\n",
       "      <td>Area F</td>\n",
       "      <td>Area F</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Asset</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Example Data</td>\n",
       "      <td>False</td>\n",
       "      <td>2</td>\n",
       "      <td>ID       0EF58FC2-90AA-60E0-94F7-29D4E89DC2F9\n",
       "Type                                    Asset\n",
       "Path               Example &gt;&gt; Cooling Tower 1\n",
       "Asset                                  Area B\n",
       "Name: 1, dtype: object</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                     ID                        Path   Asset  \\\n",
       "0  0EF58FC2-90AA-60E0-BEE7-242FC3F918D2  Example >> Cooling Tower 2  Area D   \n",
       "1  0EF58FC2-90AC-77F0-8FD2-9F21B57B5B16  Example >> Cooling Tower 2  Area E   \n",
       "0  0EF58FC2-90AA-60E0-BEE7-242FC3F918D2  Example >> Cooling Tower 2  Area D   \n",
       "2  0EF58FC2-90AC-77F0-9C25-FE38E1BE65AC  Example >> Cooling Tower 2  Area F   \n",
       "\n",
       "     Name  Description   Type  Value Unit Of Measure Datasource Name  \\\n",
       "0  Area D          NaN  Asset                    NaN    Example Data   \n",
       "1  Area E          NaN  Asset                    NaN    Example Data   \n",
       "0  Area D          NaN  Asset                    NaN    Example Data   \n",
       "2  Area F          NaN  Asset                    NaN    Example Data   \n",
       "\n",
       "   Archived  Swap Group  \\\n",
       "0     False           1   \n",
       "1     False           1   \n",
       "0     False           2   \n",
       "2     False           2   \n",
       "\n",
       "                                                                                                                                                                                                         Swap Out  \n",
       "0  ID       0EF58FC2-90AC-77F0-85F2-91128B10372A\n",
       "Type                                    Asset\n",
       "Path               Example >> Cooling Tower 1\n",
       "Asset                                  Area A\n",
       "Name: 0, dtype: object  \n",
       "1  ID       0EF58FC2-90AA-60E0-94F7-29D4E89DC2F9\n",
       "Type                                    Asset\n",
       "Path               Example >> Cooling Tower 1\n",
       "Asset                                  Area B\n",
       "Name: 1, dtype: object  \n",
       "0  ID       0EF58FC2-90AC-77F0-85F2-91128B10372A\n",
       "Type                                    Asset\n",
       "Path               Example >> Cooling Tower 1\n",
       "Asset                                  Area A\n",
       "Name: 0, dtype: object  \n",
       "2  ID       0EF58FC2-90AA-60E0-94F7-29D4E89DC2F9\n",
       "Type                                    Asset\n",
       "Path               Example >> Cooling Tower 1\n",
       "Asset                                  Area B\n",
       "Name: 1, dtype: object  "
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Grab a DataFrame that contains Areas D, E and F\n",
    "cooling_tower_2_df = spy.search({\n",
    "    'Path': 'Example >> Cooling Tower 2',\n",
    "    'Type': 'Asset'\n",
    "}, old_asset_format=False).sort_values(by='Name')\n",
    "\n",
    "# Create a DataFrame that includes the combination of areas:\n",
    "swap_groups_df = pd.DataFrame([\n",
    "    cooling_tower_2_df.iloc[0],  # Area D\n",
    "    cooling_tower_2_df.iloc[1],  # Area E\n",
    "\n",
    "    cooling_tower_2_df.iloc[0],  # Area D\n",
    "    cooling_tower_2_df.iloc[2]]) # Area F\n",
    "    \n",
    "# Now we'll specify our \"Swap Group\" and \"Swap Out\" columns. The Swap Group column can be any signifier you wish to use\n",
    "# to group the swaps together. Any rows with the same value for the Swap Group will be grouped together for swapping\n",
    "# purposes.\n",
    "swap_groups_df['Swap Group'] = [1, 1, 2, 2]\n",
    "\n",
    "# The \"Swap Out\" column can be an asset ID string, the latter part of an asset's path, or a DataFrame row for an asset.\n",
    "# It must be for an asset that is part of the \"Swappable Assets\" found above.\n",
    "swap_groups_df['Swap Out'] = [\n",
    "    swappable_assets_df.iloc[0],  # Area A\n",
    "    swappable_assets_df.iloc[1],  # Area B\n",
    "\n",
    "    swappable_assets_df.iloc[0],  # Area A\n",
    "    swappable_assets_df.iloc[1],  # Area B\n",
    "]\n",
    "\n",
    "swap_groups_df"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now we swap! Note that we're going to have two new swapped calculations -- one for each Swap Group. You can see that there are a couple of actions noted in the `Swap Performed` column (separated by a `\\n` line break)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div style=\"background-color: #EEFFEE;color:black; text-align: left;\">Success: Returned 2 swapped item(s).</div><table class=\"tex2jax_ignore\" style=\"color:black;\"><tr><td style=\"background-color: #EEFFEE;\"></td><td style=\"background-color: #EEFFEE; text-align: left;\">Original ID</td><td style=\"background-color: #EEFFEE; text-align: left;\">ID</td><td style=\"background-color: #EEFFEE; text-align: left;\">Type</td><td style=\"background-color: #EEFFEE; text-align: left;\">Name</td><td style=\"background-color: #EEFFEE; text-align: left;\">Result</td><td style=\"background-color: #EEFFEE; text-align: left;\">Swap Performed</td><td style=\"background-color: #EEFFEE; text-align: left;\">Header</td></tr><tr style=\"background-color: #EEFFEE;\"><td style=\"vertical-align: top;\">0</td><td style=\"text-align: left; vertical-align: top;\">0EF5BF17-25A2-7110-8D07-FF485DDCEDB7</td><td style=\"text-align: left; vertical-align: top;\">0EF5BF17-2D8C-66F0-9D31-517D1EBC8DED</td><td style=\"text-align: left; vertical-align: top;\">CalculatedSignal</td><td style=\"text-align: left; vertical-align: top;\">Added Together</td><td style=\"text-align: left; vertical-align: top;\">Success</td><td style=\"text-align: left; vertical-align: top;\">Example >> Cooling Tower 1 >> Area A --> Example >> Cooling Tower 2 >> Area D<br>Example >> Cooling Tower 1 >> Area B --> Example >> Cooling Tower 2 >> Area E</td><td style=\"text-align: left; vertical-align: top;\">Cooling Tower 2 >> Area D, Cooling Tower 2 >> Area E</td></tr><tr style=\"background-color: #EEFFEE;\"><td style=\"vertical-align: top;\">1</td><td style=\"text-align: left; vertical-align: top;\">0EF5BF17-25A2-7110-8D07-FF485DDCEDB7</td><td style=\"text-align: left; vertical-align: top;\">0EF5BF17-2D8C-66F0-9FE8-AEFD5505D999</td><td style=\"text-align: left; vertical-align: top;\">CalculatedSignal</td><td style=\"text-align: left; vertical-align: top;\">Added Together</td><td style=\"text-align: left; vertical-align: top;\">Success</td><td style=\"text-align: left; vertical-align: top;\">Example >> Cooling Tower 1 >> Area A --> Example >> Cooling Tower 2 >> Area D<br>Example >> Cooling Tower 1 >> Area B --> Example >> Cooling Tower 2 >> Area F</td><td style=\"text-align: left; vertical-align: top;\">Cooling Tower 2 >> Area D, Cooling Tower 2 >> Area F</td></tr></table>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<style type=\"text/css\">\n",
       "#T_e8cb4_row0_col0, #T_e8cb4_row0_col1, #T_e8cb4_row0_col2, #T_e8cb4_row0_col3, #T_e8cb4_row1_col0, #T_e8cb4_row1_col1, #T_e8cb4_row1_col2, #T_e8cb4_row1_col3 {\n",
       "  text-align: left;\n",
       "  white-space: pre-wrap;\n",
       "}\n",
       "</style>\n",
       "<table id=\"T_e8cb4\">\n",
       "  <thead>\n",
       "    <tr>\n",
       "      <th class=\"blank level0\" >&nbsp;</th>\n",
       "      <th id=\"T_e8cb4_level0_col0\" class=\"col_heading level0 col0\" >ID</th>\n",
       "      <th id=\"T_e8cb4_level0_col1\" class=\"col_heading level0 col1\" >Name</th>\n",
       "      <th id=\"T_e8cb4_level0_col2\" class=\"col_heading level0 col2\" >Result</th>\n",
       "      <th id=\"T_e8cb4_level0_col3\" class=\"col_heading level0 col3\" >Swap Performed</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th id=\"T_e8cb4_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
       "      <td id=\"T_e8cb4_row0_col0\" class=\"data row0 col0\" >0EF5BF17-2D8C-66F0-9D31-517D1EBC8DED</td>\n",
       "      <td id=\"T_e8cb4_row0_col1\" class=\"data row0 col1\" >Added Together</td>\n",
       "      <td id=\"T_e8cb4_row0_col2\" class=\"data row0 col2\" >Success</td>\n",
       "      <td id=\"T_e8cb4_row0_col3\" class=\"data row0 col3\" >Example >> Cooling Tower 1 >> Area A --> Example >> Cooling Tower 2 >> Area D\n",
       "Example >> Cooling Tower 1 >> Area B --> Example >> Cooling Tower 2 >> Area E</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_e8cb4_level0_row1\" class=\"row_heading level0 row1\" >1</th>\n",
       "      <td id=\"T_e8cb4_row1_col0\" class=\"data row1 col0\" >0EF5BF17-2D8C-66F0-9FE8-AEFD5505D999</td>\n",
       "      <td id=\"T_e8cb4_row1_col1\" class=\"data row1 col1\" >Added Together</td>\n",
       "      <td id=\"T_e8cb4_row1_col2\" class=\"data row1 col2\" >Success</td>\n",
       "      <td id=\"T_e8cb4_row1_col3\" class=\"data row1 col3\" >Example >> Cooling Tower 1 >> Area A --> Example >> Cooling Tower 2 >> Area D\n",
       "Example >> Cooling Tower 1 >> Area B --> Example >> Cooling Tower 2 >> Area F</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n"
      ],
      "text/plain": [
       "<pandas.io.formats.style.Styler at 0x1ccb0e12610>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "swapped_df = spy.swap(added_together_df, swap_groups_df, old_asset_format=False)\n",
    "\n",
    "# Use a specific set of display properties so that the linebreaks are rendered correctly\n",
    "display(swapped_df[['ID', 'Name', 'Result', 'Swap Performed']].style.set_properties(**{\n",
    "    'text-align': 'left',\n",
    "    'white-space': 'pre-wrap',\n",
    "}))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can pull just like we did before:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div style=\"background-color: #EEFFEE;color:black; text-align: left;\">Pull successful from <strong>2021-01-01 00:00:00+00:00</strong> to <strong>2021-01-02 00:00:00+00:00</strong></div><table class=\"tex2jax_ignore\" style=\"color:black;\"><tr><td style=\"background-color: #EEFFEE;\"></td><td style=\"background-color: #EEFFEE; text-align: left;\">ID</td><td style=\"background-color: #EEFFEE; text-align: left;\">Type</td><td style=\"background-color: #EEFFEE; text-align: left;\">Name</td><td style=\"background-color: #EEFFEE; text-align: left;\">Header</td><td style=\"background-color: #EEFFEE; text-align: right;\">Time</td><td style=\"background-color: #EEFFEE; text-align: right;\">Count</td><td style=\"background-color: #EEFFEE; text-align: right;\">Pages</td><td style=\"background-color: #EEFFEE; text-align: left;\">Data Processed</td><td style=\"background-color: #EEFFEE; text-align: left;\">Result</td></tr><tr style=\"background-color: #EEFFEE;\"><td style=\"vertical-align: top;\">0</td><td style=\"text-align: left; vertical-align: top;\">0EF5BF17-2D8C-66F0-9D31-517D1EBC8DED</td><td style=\"text-align: left; vertical-align: top;\">CalculatedSignal</td><td style=\"text-align: left; vertical-align: top;\">Added Together</td><td style=\"text-align: left; vertical-align: top;\">Cooling Tower 2 >> Area D, Cooling Tower 2 >> Area E</td><td style=\"vertical-align: top;\">00:00:00.09</td><td style=\"text-align: right; vertical-align: top;\">97</td><td style=\"text-align: right; vertical-align: top;\">1</td><td style=\"text-align: right; vertical-align: top;\">11 KB</td><td style=\"text-align: left; vertical-align: top;\">Success</td></tr><tr style=\"background-color: #EEFFEE;\"><td style=\"vertical-align: top;\">1</td><td style=\"text-align: left; vertical-align: top;\">0EF5BF17-2D8C-66F0-9FE8-AEFD5505D999</td><td style=\"text-align: left; vertical-align: top;\">CalculatedSignal</td><td style=\"text-align: left; vertical-align: top;\">Added Together</td><td style=\"text-align: left; vertical-align: top;\">Cooling Tower 2 >> Area D, Cooling Tower 2 >> Area F</td><td style=\"vertical-align: top;\">00:00:00.08</td><td style=\"text-align: right; vertical-align: top;\">97</td><td style=\"text-align: right; vertical-align: top;\">1</td><td style=\"text-align: right; vertical-align: top;\">11 KB</td><td style=\"text-align: left; vertical-align: top;\">Success</td></tr></table>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Cooling Tower 2 &gt;&gt; Area D, Cooling Tower 2 &gt;&gt; Area E</th>\n",
       "      <th>Cooling Tower 2 &gt;&gt; Area D, Cooling Tower 2 &gt;&gt; Area F</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2021-01-01 00:00:00+00:00</th>\n",
       "      <td>29.362794</td>\n",
       "      <td>28.016513</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2021-01-01 00:15:00+00:00</th>\n",
       "      <td>32.655979</td>\n",
       "      <td>28.082996</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2021-01-01 00:30:00+00:00</th>\n",
       "      <td>28.149479</td>\n",
       "      <td>28.149479</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2021-01-01 00:45:00+00:00</th>\n",
       "      <td>32.784786</td>\n",
       "      <td>28.215962</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2021-01-01 01:00:00+00:00</th>\n",
       "      <td>32.813098</td>\n",
       "      <td>28.282445</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2021-01-01 23:00:00+00:00</th>\n",
       "      <td>27.369611</td>\n",
       "      <td>27.335406</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2021-01-01 23:15:00+00:00</th>\n",
       "      <td>32.330629</td>\n",
       "      <td>27.660053</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2021-01-01 23:30:00+00:00</th>\n",
       "      <td>28.261489</td>\n",
       "      <td>28.236783</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2021-01-01 23:45:00+00:00</th>\n",
       "      <td>32.405502</td>\n",
       "      <td>27.776533</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2021-01-02 00:00:00+00:00</th>\n",
       "      <td>30.209830</td>\n",
       "      <td>27.584574</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>97 rows × 2 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "                           Cooling Tower 2 >> Area D, Cooling Tower 2 >> Area E  \\\n",
       "2021-01-01 00:00:00+00:00                                             29.362794   \n",
       "2021-01-01 00:15:00+00:00                                             32.655979   \n",
       "2021-01-01 00:30:00+00:00                                             28.149479   \n",
       "2021-01-01 00:45:00+00:00                                             32.784786   \n",
       "2021-01-01 01:00:00+00:00                                             32.813098   \n",
       "...                                                                         ...   \n",
       "2021-01-01 23:00:00+00:00                                             27.369611   \n",
       "2021-01-01 23:15:00+00:00                                             32.330629   \n",
       "2021-01-01 23:30:00+00:00                                             28.261489   \n",
       "2021-01-01 23:45:00+00:00                                             32.405502   \n",
       "2021-01-02 00:00:00+00:00                                             30.209830   \n",
       "\n",
       "                           Cooling Tower 2 >> Area D, Cooling Tower 2 >> Area F  \n",
       "2021-01-01 00:00:00+00:00                                             28.016513  \n",
       "2021-01-01 00:15:00+00:00                                             28.082996  \n",
       "2021-01-01 00:30:00+00:00                                             28.149479  \n",
       "2021-01-01 00:45:00+00:00                                             28.215962  \n",
       "2021-01-01 01:00:00+00:00                                             28.282445  \n",
       "...                                                                         ...  \n",
       "2021-01-01 23:00:00+00:00                                             27.335406  \n",
       "2021-01-01 23:15:00+00:00                                             27.660053  \n",
       "2021-01-01 23:30:00+00:00                                             28.236783  \n",
       "2021-01-01 23:45:00+00:00                                             27.776533  \n",
       "2021-01-02 00:00:00+00:00                                             27.584574  \n",
       "\n",
       "[97 rows x 2 columns]"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "spy.pull(swapped_df, start='2021-01-01', end='2021-01-02')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Multi-level Swaps\n",
    "\n",
    "If you have a hierarchy that contains \"commonly named\" nodes at the bottom of the tree, you'll need to do a multi-level swap. Here's an example where \"Raw\" and \"Cleansed\" are categorical child \"assets\" that are common between the uniquely-named assets (Area A & Area B):\n",
    "\n",
    "```\n",
    "Multi-level Swap Example >> Area A >> Raw      >> Temperature\n",
    "                                      Cleansed >> Temperature\n",
    "                            Area B >> Raw      >> Temperature\n",
    "                                      Cleansed >> Temperature\n",
    "```\n",
    "\n",
    "You must specify the uniquely-named assets as your \"Swap Out\" values, and SPy will figure out how to perform the swap at the lower level. Here's an example where the categories are _Raw_ and _Cleansed_:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div style=\"background-color: #EEFFEE;color:black; text-align: left;\">Pushed successfully to datasource <strong>Seeq Data Lab [Datasource ID: Seeq Data Lab]</strong> and scoped to workbook ID <strong>0EF5BF17-09A9-66C0-869E-364B7AAAD204</strong><br>Click the following link to see what you pushed in Seeq:<br><a href=\"http://localhost:34216/0EF5BE2D-2738-FFA0-81E0-D2B058859C4D/workbook/0EF5BF17-09A9-66C0-869E-364B7AAAD204/worksheet/0EF5BF17-0A19-FBA0-AE66-FB4A92EC60AF\" target=\"_blank\">http://localhost:34216/0EF5BE2D-2738-FFA0-81E0-D2B058859C4D/workbook/0EF5BF17-09A9-66C0-869E-364B7AAAD204/worksheet/0EF5BF17-0A19-FBA0-AE66-FB4A92EC60AF</a></div>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>ID</th>\n",
       "      <th>Type</th>\n",
       "      <th>Path</th>\n",
       "      <th>Asset</th>\n",
       "      <th>Name</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0EF5BF17-3AE3-FF60-A244-0B35E0F1FA9A</td>\n",
       "      <td>CalculatedSignal</td>\n",
       "      <td>Multi-level Swap Example &gt;&gt; Area A</td>\n",
       "      <td>Raw</td>\n",
       "      <td>Temperature</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0EF5BF17-3BF0-E840-833B-3A01274979EE</td>\n",
       "      <td>CalculatedSignal</td>\n",
       "      <td>Multi-level Swap Example &gt;&gt; Area B</td>\n",
       "      <td>Raw</td>\n",
       "      <td>Temperature</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0EF5BF17-3C34-EE00-993E-6E9C7100E2E9</td>\n",
       "      <td>CalculatedSignal</td>\n",
       "      <td>Multi-level Swap Example &gt;&gt; Area A</td>\n",
       "      <td>Cleansed</td>\n",
       "      <td>Temperature</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0EF5BF17-4000-E8E0-996B-4C867B5969DB</td>\n",
       "      <td>CalculatedSignal</td>\n",
       "      <td>Multi-level Swap Example &gt;&gt; Area B</td>\n",
       "      <td>Cleansed</td>\n",
       "      <td>Temperature</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0EF5BF17-40F2-6410-A74C-0261F5EE356F</td>\n",
       "      <td>CalculatedSignal</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Raw and Cleansed Averaged</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>__side_effect_asset_1__</th>\n",
       "      <td>0EF5BF17-4049-ECC0-BF3B-42081211FDA8</td>\n",
       "      <td>Asset</td>\n",
       "      <td></td>\n",
       "      <td>Multi-level Swap Example</td>\n",
       "      <td>Multi-level Swap Example</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>__side_effect_asset_2__</th>\n",
       "      <td>0EF5BF17-404E-EAE0-81E2-BED0CCC6507B</td>\n",
       "      <td>Asset</td>\n",
       "      <td>Multi-level Swap Example</td>\n",
       "      <td>Area A</td>\n",
       "      <td>Area A</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>__side_effect_asset_3__</th>\n",
       "      <td>0EF5BF17-404E-EAE0-813E-837416D86FBB</td>\n",
       "      <td>Asset</td>\n",
       "      <td>Multi-level Swap Example &gt;&gt; Area A</td>\n",
       "      <td>Raw</td>\n",
       "      <td>Raw</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>__side_effect_asset_4__</th>\n",
       "      <td>0EF5BF17-404E-EAE0-B533-FC0592C89204</td>\n",
       "      <td>Asset</td>\n",
       "      <td>Multi-level Swap Example</td>\n",
       "      <td>Area B</td>\n",
       "      <td>Area B</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>__side_effect_asset_5__</th>\n",
       "      <td>0EF5BF17-404E-EAE0-9383-4030C7678323</td>\n",
       "      <td>Asset</td>\n",
       "      <td>Multi-level Swap Example &gt;&gt; Area B</td>\n",
       "      <td>Raw</td>\n",
       "      <td>Raw</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>__side_effect_asset_6__</th>\n",
       "      <td>0EF5BF17-4051-71F0-B400-2565C9549F62</td>\n",
       "      <td>Asset</td>\n",
       "      <td>Multi-level Swap Example &gt;&gt; Area A</td>\n",
       "      <td>Cleansed</td>\n",
       "      <td>Cleansed</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>__side_effect_asset_7__</th>\n",
       "      <td>0EF5BF17-4051-71F0-9498-17BD173B0567</td>\n",
       "      <td>Asset</td>\n",
       "      <td>Multi-level Swap Example &gt;&gt; Area B</td>\n",
       "      <td>Cleansed</td>\n",
       "      <td>Cleansed</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                                           ID  \\\n",
       "0                        0EF5BF17-3AE3-FF60-A244-0B35E0F1FA9A   \n",
       "1                        0EF5BF17-3BF0-E840-833B-3A01274979EE   \n",
       "2                        0EF5BF17-3C34-EE00-993E-6E9C7100E2E9   \n",
       "3                        0EF5BF17-4000-E8E0-996B-4C867B5969DB   \n",
       "4                        0EF5BF17-40F2-6410-A74C-0261F5EE356F   \n",
       "__side_effect_asset_1__  0EF5BF17-4049-ECC0-BF3B-42081211FDA8   \n",
       "__side_effect_asset_2__  0EF5BF17-404E-EAE0-81E2-BED0CCC6507B   \n",
       "__side_effect_asset_3__  0EF5BF17-404E-EAE0-813E-837416D86FBB   \n",
       "__side_effect_asset_4__  0EF5BF17-404E-EAE0-B533-FC0592C89204   \n",
       "__side_effect_asset_5__  0EF5BF17-404E-EAE0-9383-4030C7678323   \n",
       "__side_effect_asset_6__  0EF5BF17-4051-71F0-B400-2565C9549F62   \n",
       "__side_effect_asset_7__  0EF5BF17-4051-71F0-9498-17BD173B0567   \n",
       "\n",
       "                                     Type                                Path  \\\n",
       "0                        CalculatedSignal  Multi-level Swap Example >> Area A   \n",
       "1                        CalculatedSignal  Multi-level Swap Example >> Area B   \n",
       "2                        CalculatedSignal  Multi-level Swap Example >> Area A   \n",
       "3                        CalculatedSignal  Multi-level Swap Example >> Area B   \n",
       "4                        CalculatedSignal                                 NaN   \n",
       "__side_effect_asset_1__             Asset                                       \n",
       "__side_effect_asset_2__             Asset            Multi-level Swap Example   \n",
       "__side_effect_asset_3__             Asset  Multi-level Swap Example >> Area A   \n",
       "__side_effect_asset_4__             Asset            Multi-level Swap Example   \n",
       "__side_effect_asset_5__             Asset  Multi-level Swap Example >> Area B   \n",
       "__side_effect_asset_6__             Asset  Multi-level Swap Example >> Area A   \n",
       "__side_effect_asset_7__             Asset  Multi-level Swap Example >> Area B   \n",
       "\n",
       "                                            Asset                       Name  \n",
       "0                                             Raw                Temperature  \n",
       "1                                             Raw                Temperature  \n",
       "2                                        Cleansed                Temperature  \n",
       "3                                        Cleansed                Temperature  \n",
       "4                                             NaN  Raw and Cleansed Averaged  \n",
       "__side_effect_asset_1__  Multi-level Swap Example   Multi-level Swap Example  \n",
       "__side_effect_asset_2__                    Area A                     Area A  \n",
       "__side_effect_asset_3__                       Raw                        Raw  \n",
       "__side_effect_asset_4__                    Area B                     Area B  \n",
       "__side_effect_asset_5__                       Raw                        Raw  \n",
       "__side_effect_asset_6__                  Cleansed                   Cleansed  \n",
       "__side_effect_asset_7__                  Cleansed                   Cleansed  "
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# First we have to create the asset tree we want from Example data.\n",
    "\n",
    "area_ab_df = spy.search({\n",
    "    'Path': 'Example >> Cooling Tower 1',\n",
    "    'Asset': '/Area [AB]/',\n",
    "    'Name': 'Temperature'\n",
    "}, old_asset_format=False)\n",
    "\n",
    "raw_signals = area_ab_df.copy()\n",
    "raw_signals['Path'] = 'Multi-level Swap Example >> ' + raw_signals['Asset']\n",
    "raw_signals['Asset'] = 'Raw'\n",
    "raw_signals['Reference'] = True\n",
    "\n",
    "cleansed_signals = area_ab_df.copy()\n",
    "cleansed_signals['Path'] = 'Multi-level Swap Example >> ' + cleansed_signals['Asset']\n",
    "cleansed_signals['Asset'] = 'Cleansed'\n",
    "cleansed_signals['Reference'] = True\n",
    "\n",
    "combined_signal = pd.DataFrame([{\n",
    "    'Name': 'Raw and Cleansed Averaged',\n",
    "    'Type': 'Signal',\n",
    "    'Formula': '($r + $c) / 2',\n",
    "    'Formula Parameters': {\n",
    "        '$r': {'Path': 'Multi-level Swap Example >> Area A', 'Asset': 'Raw',      'Name': 'Temperature'},\n",
    "        '$c': {'Path': 'Multi-level Swap Example >> Area A', 'Asset': 'Cleansed', 'Name': 'Temperature'}\n",
    "    }\n",
    "}])\n",
    "\n",
    "pushed_items_df = spy.push(metadata=pd.concat([raw_signals, cleansed_signals, combined_signal], ignore_index=True),\n",
    "                           workbook='SPy Documentation Examples >> spy.swap')\n",
    "\n",
    "pushed_items_df[['ID', 'Type', 'Path', 'Asset', 'Name']]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div style=\"background-color: #EEFFEE;color:black; text-align: left;\">Success: Returned 1 swapped item(s).</div><table class=\"tex2jax_ignore\" style=\"color:black;\"><tr><td style=\"background-color: #EEFFEE;\"></td><td style=\"background-color: #EEFFEE; text-align: left;\">Original ID</td><td style=\"background-color: #EEFFEE; text-align: left;\">ID</td><td style=\"background-color: #EEFFEE; text-align: left;\">Type</td><td style=\"background-color: #EEFFEE; text-align: left;\">Name</td><td style=\"background-color: #EEFFEE; text-align: left;\">Result</td><td style=\"background-color: #EEFFEE; text-align: left;\">Swap Performed</td><td style=\"background-color: #EEFFEE; text-align: left;\">Header</td></tr><tr style=\"background-color: #EEFFEE;\"><td style=\"vertical-align: top;\">0</td><td style=\"text-align: left; vertical-align: top;\">0EF5BF17-40F2-6410-A74C-0261F5EE356F</td><td style=\"text-align: left; vertical-align: top;\">0EF5BF17-491C-7190-A57D-F9BC640E189B</td><td style=\"text-align: left; vertical-align: top;\">CalculatedSignal</td><td style=\"text-align: left; vertical-align: top;\">Raw and Cleansed Averaged</td><td style=\"text-align: left; vertical-align: top;\">Success</td><td style=\"text-align: left; vertical-align: top;\">Multi-level Swap Example >> Area A >> Raw --> Multi-level Swap Example >> Area B >> Raw<br>Multi-level Swap Example >> Area A >> Cleansed --> Multi-level Swap Example >> Area B >> Cleansed</td><td style=\"text-align: left; vertical-align: top;\">Area B >> Raw, Area B >> Cleansed</td></tr></table>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<style type=\"text/css\">\n",
       "#T_1e209_row0_col0, #T_1e209_row0_col1, #T_1e209_row0_col2 {\n",
       "  text-align: left;\n",
       "  white-space: pre-wrap;\n",
       "}\n",
       "</style>\n",
       "<table id=\"T_1e209\">\n",
       "  <thead>\n",
       "    <tr>\n",
       "      <th class=\"blank level0\" >&nbsp;</th>\n",
       "      <th id=\"T_1e209_level0_col0\" class=\"col_heading level0 col0\" >ID</th>\n",
       "      <th id=\"T_1e209_level0_col1\" class=\"col_heading level0 col1\" >Name</th>\n",
       "      <th id=\"T_1e209_level0_col2\" class=\"col_heading level0 col2\" >Swap Performed</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th id=\"T_1e209_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
       "      <td id=\"T_1e209_row0_col0\" class=\"data row0 col0\" >0EF5BF17-491C-7190-A57D-F9BC640E189B</td>\n",
       "      <td id=\"T_1e209_row0_col1\" class=\"data row0 col1\" >Raw and Cleansed Averaged</td>\n",
       "      <td id=\"T_1e209_row0_col2\" class=\"data row0 col2\" >Multi-level Swap Example >> Area A >> Raw --> Multi-level Swap Example >> Area B >> Raw\n",
       "Multi-level Swap Example >> Area A >> Cleansed --> Multi-level Swap Example >> Area B >> Cleansed</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n"
      ],
      "text/plain": [
       "<pandas.io.formats.style.Styler at 0x1ccb0e131d0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "raw_plus_cleansed = pushed_items_df[pushed_items_df['Name'] == 'Raw and Cleansed Averaged']\n",
    "area_a_df = pushed_items_df[(pushed_items_df['Type'] == 'Asset') & (pushed_items_df['Name'] == 'Area A')]\n",
    "area_b_df = pushed_items_df[(pushed_items_df['Type'] == 'Asset') & (pushed_items_df['Name'] == 'Area B')]\n",
    "\n",
    "# Create a Swap In / Swap Out pairing that uses the unique level of the tree, namely:\n",
    "#  Swap Out:  test_multilevel_swap >> Example >> Cooling Tower 1 >> Area A\n",
    "#  Swap In:   test_multilevel_swap >> Example >> Cooling Tower 1 >> Area B\n",
    "\n",
    "assets_df = area_b_df.copy()                  # Swap In\n",
    "assets_df['Swap Out'] = [area_a_df.iloc[0]]   # Swap Out\n",
    "\n",
    "swap_results = spy.swap(raw_plus_cleansed, assets_df)\n",
    "\n",
    "display(swap_results[['ID', 'Name', 'Swap Performed']].style.set_properties(**{\n",
    "    'text-align': 'left',\n",
    "    'white-space': 'pre-wrap',\n",
    "}))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Detailed Help\n",
    "\n",
    "All SPy functions have detailed documentation to help you use them. Just execute `help(spy.<func>)` like\n",
    "you see below.\n",
    "\n",
    "**Make sure you re-execute the cell below to see the latest documentation. It otherwise might be from an\n",
    "earlier version of SPy.**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Help on function swap in module seeq.spy._swap:\n",
      "\n",
      "swap(items: pandas.core.frame.DataFrame, assets: pandas.core.frame.DataFrame, *, partial_swaps_ok: bool = False, old_asset_format: Optional[bool] = None, errors: Optional[str] = None, quiet: Optional[bool] = None, status: Optional[seeq.spy._status.Status] = None, session: Optional[seeq.spy._session.Session] = None)\n",
      "    Operates on a DataFrame of items by swapping out the assets that those\n",
      "    items are based on. The returned DataFrame can be supplied to\n",
      "    spy.pull() to retrieve the resulting data.\n",
      "    \n",
      "    Parameters\n",
      "    ----------\n",
      "    items : {pd.DataFrame}\n",
      "        A DataFrame of items over which to perform the swapping operation. The\n",
      "        only required column is ID. Typically, you will have derived this\n",
      "        DataFrame via a spy.search() or spy.push(metadata) call.\n",
      "    \n",
      "    assets : {pd.DataFrame}\n",
      "        A DataFrame of Asset items (and ONLY Asset items) to swap IN. Each row\n",
      "        must have valid ID, Type, Path, Asset, and Name columns. Typically, you\n",
      "        will have derived this DataFrame via a spy.search() call.\n",
      "    \n",
      "        When a calculation depends on multiple assets, you must specify Swap\n",
      "        Groups (with the notable exception of a \"multi-level swap\", see below.\n",
      "        You can determine the set of \"swappable assets\" by invoking\n",
      "        spy.search(include_swappable_assets=True). Then you must assemble an\n",
      "        assets DataFrame where each row is the asset to be swapped in and there\n",
      "        is a \"Swap Out\" column that specifies the corresponding asset (from\n",
      "        the list of swappable assets) to be swapped out. The \"Swap Out\" column\n",
      "        can be a string ID, the latter portion of an asset path/name, or a\n",
      "        DataFrame row representing the asset (which could be used directly\n",
      "        from the \"Swappable Assets\" column of your search result).\n",
      "        Additionally, assuming you want to produce several swapped\n",
      "        calculations, you must group the swap rows together by specifying a\n",
      "        \"Swap Group\" column where unique values are used to group together\n",
      "        the rows that comprise the set of assets to be swapped in/out.\n",
      "    \n",
      "        If a calculation depends on multiple assets where the immediate\n",
      "        parent asset is a \"categorical\" name (e.g. \"Raw\" and \"Cleansed\"), it\n",
      "        is referred to as a \"multi-level swap\", where you actually wish to\n",
      "        swap at a level higher than the immediate parent. You can do so by\n",
      "        specifying that higher level, and spy.swap() will automatically\n",
      "        figure out the actual lower-level items that are appropriate to swap.\n",
      "    \n",
      "    partial_swaps_ok : bool, default False\n",
      "        If True, allows partial swaps to occur. A partial swap occurs when\n",
      "        the incoming asset has children that only partially match the outgoing\n",
      "        asset.\n",
      "    \n",
      "    old_asset_format : bool, default True\n",
      "        If your DataFrame doesn't use the \"old\" asset format, you can specify\n",
      "        False for this argument. See spy.search() documentation for more info.\n",
      "    \n",
      "    quiet : bool, default False\n",
      "        If True, suppresses progress output. Note that when status is\n",
      "        provided, the quiet setting of the Status object that is passed\n",
      "        in takes precedence.\n",
      "    \n",
      "    errors : {'raise', 'catalog'}, default 'raise'\n",
      "        If 'raise', any errors encountered will cause an exception. If 'catalog',\n",
      "        errors will be added to a 'Result' column in the status.df DataFrame\n",
      "        (or 'Swap Result' column if using `spy.options.compatibility = 189` or lower).\n",
      "    \n",
      "    status : spy.Status, optional\n",
      "        If specified, the supplied Status object will be updated as the command\n",
      "        progresses. It gets filled in with the same information you would see\n",
      "        in Jupyter in the blue/green/red table below your code while the\n",
      "        command is executed. The table itself is accessible as a DataFrame via\n",
      "        the status.df property.\n",
      "    \n",
      "    session : spy.Session, optional\n",
      "        If supplied, the Session object (and its Options) will be used to\n",
      "        store the login session state. This is useful to log in to different\n",
      "        Seeq servers at the same time or with different credentials.\n",
      "    \n",
      "    Returns\n",
      "    -------\n",
      "    pandas.DataFrame\n",
      "        A DataFrame with rows for each item swapped. Includes a \"Result\"\n",
      "        column that is either \"Success\" or an error message (when\n",
      "        errors='catalog'). Also includes a \"Swap Performed\" column that\n",
      "        specifies the details of what swap pairs were utilized.\n",
      "    \n",
      "        Additionally, the following properties are stored on the \"spy\"\n",
      "        attribute of the output DataFrame:\n",
      "    \n",
      "        =================== ===================================================\n",
      "        Property            Description\n",
      "        =================== ===================================================\n",
      "        func                A str value of 'spy.swap'\n",
      "        kwargs              A dict with the values of the input parameters\n",
      "                            passed to spy.swap to get the output DataFrame\n",
      "        status              A spy.Status object with the status of the\n",
      "                            spy.swap call\n",
      "        =================== ===================================================\n",
      "\n"
     ]
    }
   ],
   "source": [
    "help(spy.swap)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3.11",
   "language": "python",
   "name": "python311"
  },
  "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.11.9"
  },
  "pycharm": {
   "stem_cell": {
    "cell_type": "raw",
    "metadata": {
     "collapsed": false
    },
    "source": []
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
