{
 "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.search\n",
    "\n",
    "Finds signals (tags), conditions (with capsules), scalars (constants), assets or any other type of item that Seeq indexes or keeps track of.\n",
    "\n",
    "You will generally use this command before executing `spy.pull()`."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`spy.search(query, all_properties=False, workbook='Data Lab >> Data Lab Analysis')`"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Query Syntax\n",
    "\n",
    "The `query` parameter is a dictionary of `'Property': 'Filter'` values that are applied using AND logic by Seeq Server. Let's use the following examples to illustrate the important parts:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "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: left;\">Path</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;\">Humid</td><td style=\"text-align: left; vertical-align: top;\">Example >> Cooling Tower 1</td><td style=\"vertical-align: top;\">00:00:00.04</td><td style=\"text-align: right; vertical-align: top;\">8</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-7E6E-7160-ACE8-E1D5408B23E1</td>\n",
       "      <td>Example &gt;&gt; Cooling Tower 1</td>\n",
       "      <td>Area A</td>\n",
       "      <td>Relative Humidity</td>\n",
       "      <td>NaN</td>\n",
       "      <td>StoredSignal</td>\n",
       "      <td>%</td>\n",
       "      <td>Example Data</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0EF58FC2-7EA1-75B0-B352-19D4D8CD997E</td>\n",
       "      <td>Example &gt;&gt; Cooling Tower 1</td>\n",
       "      <td>Area B</td>\n",
       "      <td>Relative Humidity</td>\n",
       "      <td>NaN</td>\n",
       "      <td>StoredSignal</td>\n",
       "      <td>%</td>\n",
       "      <td>Example Data</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0EF58FC2-7F95-77F0-96CD-7C9D1C3AA19A</td>\n",
       "      <td>Example &gt;&gt; Cooling Tower 1</td>\n",
       "      <td>Area C</td>\n",
       "      <td>Relative Humidity</td>\n",
       "      <td>NaN</td>\n",
       "      <td>StoredSignal</td>\n",
       "      <td>%</td>\n",
       "      <td>Example Data</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0EF58FC2-81A7-6480-BBBC-E2C2978378BC</td>\n",
       "      <td>Example &gt;&gt; Cooling Tower 1</td>\n",
       "      <td>Area G</td>\n",
       "      <td>Relative Humidity</td>\n",
       "      <td>NaN</td>\n",
       "      <td>StoredSignal</td>\n",
       "      <td>%</td>\n",
       "      <td>Example Data</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0EF58FC2-8945-FF70-B3B6-A1D7044F3E0E</td>\n",
       "      <td>Example &gt;&gt; Cooling Tower 1</td>\n",
       "      <td>Area K</td>\n",
       "      <td>Relative Humidity</td>\n",
       "      <td>NaN</td>\n",
       "      <td>StoredSignal</td>\n",
       "      <td>%</td>\n",
       "      <td>Example Data</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>0EF58FC2-89C4-EEB0-B2A7-B8E1DA1D6274</td>\n",
       "      <td>Example &gt;&gt; Cooling Tower 1</td>\n",
       "      <td>Area J</td>\n",
       "      <td>Relative Humidity</td>\n",
       "      <td>NaN</td>\n",
       "      <td>StoredSignal</td>\n",
       "      <td>%</td>\n",
       "      <td>Example Data</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>0EF58FC2-89F3-64E0-92BC-972EE275A66D</td>\n",
       "      <td>Example &gt;&gt; Cooling Tower 1</td>\n",
       "      <td>Area I</td>\n",
       "      <td>Relative Humidity</td>\n",
       "      <td>NaN</td>\n",
       "      <td>StoredSignal</td>\n",
       "      <td>%</td>\n",
       "      <td>Example Data</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>0EF58FC2-8A80-EE80-87A2-FC5D1E032DB1</td>\n",
       "      <td>Example &gt;&gt; Cooling Tower 1</td>\n",
       "      <td>Area H</td>\n",
       "      <td>Relative Humidity</td>\n",
       "      <td>NaN</td>\n",
       "      <td>StoredSignal</td>\n",
       "      <td>%</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-7E6E-7160-ACE8-E1D5408B23E1  Example >> Cooling Tower 1  Area A   \n",
       "1  0EF58FC2-7EA1-75B0-B352-19D4D8CD997E  Example >> Cooling Tower 1  Area B   \n",
       "2  0EF58FC2-7F95-77F0-96CD-7C9D1C3AA19A  Example >> Cooling Tower 1  Area C   \n",
       "3  0EF58FC2-81A7-6480-BBBC-E2C2978378BC  Example >> Cooling Tower 1  Area G   \n",
       "4  0EF58FC2-8945-FF70-B3B6-A1D7044F3E0E  Example >> Cooling Tower 1  Area K   \n",
       "5  0EF58FC2-89C4-EEB0-B2A7-B8E1DA1D6274  Example >> Cooling Tower 1  Area J   \n",
       "6  0EF58FC2-89F3-64E0-92BC-972EE275A66D  Example >> Cooling Tower 1  Area I   \n",
       "7  0EF58FC2-8A80-EE80-87A2-FC5D1E032DB1  Example >> Cooling Tower 1  Area H   \n",
       "\n",
       "                Name  Description          Type Value Unit Of Measure  \\\n",
       "0  Relative Humidity          NaN  StoredSignal                     %   \n",
       "1  Relative Humidity          NaN  StoredSignal                     %   \n",
       "2  Relative Humidity          NaN  StoredSignal                     %   \n",
       "3  Relative Humidity          NaN  StoredSignal                     %   \n",
       "4  Relative Humidity          NaN  StoredSignal                     %   \n",
       "5  Relative Humidity          NaN  StoredSignal                     %   \n",
       "6  Relative Humidity          NaN  StoredSignal                     %   \n",
       "7  Relative Humidity          NaN  StoredSignal                     %   \n",
       "\n",
       "  Datasource Name  Archived  \n",
       "0    Example Data     False  \n",
       "1    Example Data     False  \n",
       "2    Example Data     False  \n",
       "3    Example Data     False  \n",
       "4    Example Data     False  \n",
       "5    Example Data     False  \n",
       "6    Example Data     False  \n",
       "7    Example Data     False  "
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "spy.search({\n",
    "    'Name': 'Humid',\n",
    "    'Path': 'Example >> Cooling Tower 1'\n",
    "})"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This query returns anything with `Humid` in its `Name` property that also lives somewhere under `Example >> Cooling Tower 1` in an asset tree.\n",
    "\n",
    "There are several capabilities and some constraints associated with querying:\n",
    "\n",
    "1. The `Name` and `Description` properties are queried upon with the [same wildcard and RegEx support as the Data tab in Seeq Workbench](https://telemetry.seeq.com/support-link/kb/latest/cloud/basic-item-search-and-filtering).\n",
    "\n",
    "2. The `Path` property is a _virtual_ property that specifies the path through an asset tree from its root, with `>>` as delimiters for each level in the asset tree.\n",
    "\n",
    "3. The returned `Asset` property is just the leaf asset node in the tree. It can only be used in tandem with the `Path` property.\n",
    "\n",
    "4. For the `Type` property, you can specify just `Signal`, `Condition` or `Scalar` if you want to return both _stored_ and _calculated_ items.\n",
    "\n",
    "5. You can specify `Datasource Name` _or_ you can specify both `Datasource ID` and `Datasource Class` to differentiate between datasources with the same name.\n",
    "\n",
    "6. You can filter on `Data ID`, which is a unique identifier that is generally the same across instances of Seeq Server.\n",
    "\n",
    "7. You can filter on `Archived` and `Cache Enabled` using either `True` or `False` Python boolean values.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Retrieving all properties\n",
    "\n",
    "`spy.search()` only returns a subset of item properties as can be seen in the output above. If you want to retrieve all properties, use `all_properties=True`. Note that when interfacing with Seeq Server version R61 and earlier, this can be an expensive (slow) operation for queries that return many rows. In R62 and later, this query has been optimized to be much faster."
   ]
  },
  {
   "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;\">Name</td><td style=\"background-color: #EEFFEE; text-align: left;\">Datasource 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;\">Area A_*Humid*</td><td style=\"text-align: left; vertical-align: top;\">Example Data</td><td style=\"vertical-align: top;\">00:00:00.02</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>Source Value Unit Of Measure</th>\n",
       "      <th>Datasource ID</th>\n",
       "      <th>Sync Token</th>\n",
       "      <th>...</th>\n",
       "      <th>Cache ID</th>\n",
       "      <th>Datasource Class</th>\n",
       "      <th>Cache Enabled</th>\n",
       "      <th>Data ID</th>\n",
       "      <th>Interpolation Method</th>\n",
       "      <th>Stored Series Cache Version</th>\n",
       "      <th>Unsearchable</th>\n",
       "      <th>Source Maximum Interpolation</th>\n",
       "      <th>Locked</th>\n",
       "      <th>Maximum Interpolation</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0EF58FC2-83AA-66B0-8B9F-E021808A2620</td>\n",
       "      <td>Area A_Relative Humidity</td>\n",
       "      <td>NaN</td>\n",
       "      <td>StoredSignal</td>\n",
       "      <td>%</td>\n",
       "      <td>Example Data</td>\n",
       "      <td>False</td>\n",
       "      <td>%</td>\n",
       "      <td>Example Data</td>\n",
       "      <td>2024-08-12T22:42:29.096271800Z</td>\n",
       "      <td>...</td>\n",
       "      <td>0EF58FC2-83AA-66B0-97B4-77D1DFC3C715</td>\n",
       "      <td>Time Series CSV Files</td>\n",
       "      <td>False</td>\n",
       "      <td>[Tag] Area A_Relative Humidity.sim.ts.csv</td>\n",
       "      <td>Linear</td>\n",
       "      <td>1</td>\n",
       "      <td>False</td>\n",
       "      <td>2min</td>\n",
       "      <td>False</td>\n",
       "      <td>2min</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>1 rows × 22 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "                                     ID                      Name  \\\n",
       "0  0EF58FC2-83AA-66B0-8B9F-E021808A2620  Area A_Relative Humidity   \n",
       "\n",
       "   Description          Type Value Unit Of Measure Datasource Name  Archived  \\\n",
       "0          NaN  StoredSignal                     %    Example Data     False   \n",
       "\n",
       "  Source Value Unit Of Measure Datasource ID                      Sync Token  \\\n",
       "0                            %  Example Data  2024-08-12T22:42:29.096271800Z   \n",
       "\n",
       "   ...                              Cache ID       Datasource Class  \\\n",
       "0  ...  0EF58FC2-83AA-66B0-97B4-77D1DFC3C715  Time Series CSV Files   \n",
       "\n",
       "  Cache Enabled                                    Data ID  \\\n",
       "0         False  [Tag] Area A_Relative Humidity.sim.ts.csv   \n",
       "\n",
       "   Interpolation Method Stored Series Cache Version Unsearchable  \\\n",
       "0                Linear                           1        False   \n",
       "\n",
       "   Source Maximum Interpolation  Locked Maximum Interpolation  \n",
       "0                          2min   False                  2min  \n",
       "\n",
       "[1 rows x 22 columns]"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "spy.search({\n",
    "    'Name': 'Area A_*Humid*',\n",
    "    'Datasource Name': 'Example Data'\n",
    "}, all_properties=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can also use the `include_properties=['Property Name 1', 'Property Name 2']` argument if you want to explicitly return certain properties."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Estimating signal sample period\n",
    "The `estimate_sample_period` parameter adds an `Estimated Sample Period` column with a value for each signal \n",
    "returned in search query for a specified time frame. This period is calculated using the `estimateSamplePeriod()` Formula function."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "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: left;\">Datasource 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;\">Area ?_Compressor Stage</td><td style=\"text-align: left; vertical-align: top;\">Example Data</td><td style=\"vertical-align: top;\">00:00:00.04</td><td style=\"text-align: right; vertical-align: top;\">11</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>Estimated Sample Period</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0EF58FC2-85EA-F970-941E-20CF2C149E2D</td>\n",
       "      <td>Area A_Compressor Stage</td>\n",
       "      <td>NaN</td>\n",
       "      <td>StoredSignal</td>\n",
       "      <td>string</td>\n",
       "      <td>Example Data</td>\n",
       "      <td>False</td>\n",
       "      <td>0 days 00:02:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0EF58FC2-83F6-71A0-AD5D-9221D44C09F7</td>\n",
       "      <td>Area B_Compressor Stage</td>\n",
       "      <td>NaN</td>\n",
       "      <td>StoredSignal</td>\n",
       "      <td>string</td>\n",
       "      <td>Example Data</td>\n",
       "      <td>False</td>\n",
       "      <td>0 days 00:02:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0EF58FC2-82B6-6470-8624-89662770C268</td>\n",
       "      <td>Area C_Compressor Stage</td>\n",
       "      <td>NaN</td>\n",
       "      <td>StoredSignal</td>\n",
       "      <td>string</td>\n",
       "      <td>Example Data</td>\n",
       "      <td>False</td>\n",
       "      <td>0 days 00:02:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0EF58FC2-87A4-77C0-834E-6FC3BE50DF96</td>\n",
       "      <td>Area D_Compressor Stage</td>\n",
       "      <td>NaN</td>\n",
       "      <td>StoredSignal</td>\n",
       "      <td>string</td>\n",
       "      <td>Example Data</td>\n",
       "      <td>False</td>\n",
       "      <td>0 days 00:02:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0EF58FC2-8862-EEA0-B745-5FB881E17467</td>\n",
       "      <td>Area E_Compressor Stage</td>\n",
       "      <td>NaN</td>\n",
       "      <td>StoredSignal</td>\n",
       "      <td>string</td>\n",
       "      <td>Example Data</td>\n",
       "      <td>False</td>\n",
       "      <td>0 days 00:02:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>0EF58FC2-8C3F-EAF0-A54D-2EDBDA836AD2</td>\n",
       "      <td>Area G_Compressor Stage</td>\n",
       "      <td>NaN</td>\n",
       "      <td>StoredSignal</td>\n",
       "      <td>string</td>\n",
       "      <td>Example Data</td>\n",
       "      <td>False</td>\n",
       "      <td>0 days 00:02:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>0EF58FC2-827B-EAF0-ABEB-B847CFA93BC5</td>\n",
       "      <td>Area H_Compressor Stage</td>\n",
       "      <td>NaN</td>\n",
       "      <td>StoredSignal</td>\n",
       "      <td>string</td>\n",
       "      <td>Example Data</td>\n",
       "      <td>False</td>\n",
       "      <td>0 days 00:02:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>0EF58FC2-8AEE-EC50-9B3A-ADC758E457C3</td>\n",
       "      <td>Area I_Compressor Stage</td>\n",
       "      <td>NaN</td>\n",
       "      <td>StoredSignal</td>\n",
       "      <td>string</td>\n",
       "      <td>Example Data</td>\n",
       "      <td>False</td>\n",
       "      <td>0 days 00:02:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>0EF58FC2-87EB-6490-B2D3-F03E6A073359</td>\n",
       "      <td>Area J_Compressor Stage</td>\n",
       "      <td>NaN</td>\n",
       "      <td>StoredSignal</td>\n",
       "      <td>string</td>\n",
       "      <td>Example Data</td>\n",
       "      <td>False</td>\n",
       "      <td>0 days 00:02:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>0EF58FC2-8561-FDF0-8A83-A26B3E1B3A2B</td>\n",
       "      <td>Area K_Compressor Stage</td>\n",
       "      <td>NaN</td>\n",
       "      <td>StoredSignal</td>\n",
       "      <td>string</td>\n",
       "      <td>Example Data</td>\n",
       "      <td>False</td>\n",
       "      <td>0 days 00:02:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>0EF58FC2-8533-77C0-BC96-07EEAC52BF24</td>\n",
       "      <td>Area Z_Compressor Stage</td>\n",
       "      <td>NaN</td>\n",
       "      <td>StoredSignal</td>\n",
       "      <td>string</td>\n",
       "      <td>Example Data</td>\n",
       "      <td>False</td>\n",
       "      <td>0 days 00:00:02</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                      ID                     Name  \\\n",
       "0   0EF58FC2-85EA-F970-941E-20CF2C149E2D  Area A_Compressor Stage   \n",
       "1   0EF58FC2-83F6-71A0-AD5D-9221D44C09F7  Area B_Compressor Stage   \n",
       "2   0EF58FC2-82B6-6470-8624-89662770C268  Area C_Compressor Stage   \n",
       "3   0EF58FC2-87A4-77C0-834E-6FC3BE50DF96  Area D_Compressor Stage   \n",
       "4   0EF58FC2-8862-EEA0-B745-5FB881E17467  Area E_Compressor Stage   \n",
       "5   0EF58FC2-8C3F-EAF0-A54D-2EDBDA836AD2  Area G_Compressor Stage   \n",
       "6   0EF58FC2-827B-EAF0-ABEB-B847CFA93BC5  Area H_Compressor Stage   \n",
       "7   0EF58FC2-8AEE-EC50-9B3A-ADC758E457C3  Area I_Compressor Stage   \n",
       "8   0EF58FC2-87EB-6490-B2D3-F03E6A073359  Area J_Compressor Stage   \n",
       "9   0EF58FC2-8561-FDF0-8A83-A26B3E1B3A2B  Area K_Compressor Stage   \n",
       "10  0EF58FC2-8533-77C0-BC96-07EEAC52BF24  Area Z_Compressor Stage   \n",
       "\n",
       "    Description          Type Value Unit Of Measure Datasource Name  Archived  \\\n",
       "0           NaN  StoredSignal                string    Example Data     False   \n",
       "1           NaN  StoredSignal                string    Example Data     False   \n",
       "2           NaN  StoredSignal                string    Example Data     False   \n",
       "3           NaN  StoredSignal                string    Example Data     False   \n",
       "4           NaN  StoredSignal                string    Example Data     False   \n",
       "5           NaN  StoredSignal                string    Example Data     False   \n",
       "6           NaN  StoredSignal                string    Example Data     False   \n",
       "7           NaN  StoredSignal                string    Example Data     False   \n",
       "8           NaN  StoredSignal                string    Example Data     False   \n",
       "9           NaN  StoredSignal                string    Example Data     False   \n",
       "10          NaN  StoredSignal                string    Example Data     False   \n",
       "\n",
       "   Estimated Sample Period  \n",
       "0          0 days 00:02:00  \n",
       "1          0 days 00:02:00  \n",
       "2          0 days 00:02:00  \n",
       "3          0 days 00:02:00  \n",
       "4          0 days 00:02:00  \n",
       "5          0 days 00:02:00  \n",
       "6          0 days 00:02:00  \n",
       "7          0 days 00:02:00  \n",
       "8          0 days 00:02:00  \n",
       "9          0 days 00:02:00  \n",
       "10         0 days 00:00:02  "
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "spy.search({\n",
    "    'Name': 'Area ?_Compressor Stage',\n",
    "    'Datasource Name': 'Example Data'\n",
    "}, estimate_sample_period=dict(Start='2019-01-01', End='2019-01-30'))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Workbook scoping\n",
    "\n",
    "The `workbook=<workbook_path>` parameter allows you to include items in your results that are scoped to a particular workbook. If you exclude the argument, then by default your search results will include both globally-scoped items and workbook-scoped items from the **Data Lab >> Data Lab Analysis** workbook (folder path delimiter by `>>`, workbook name at the end). This workbook generally will only exist if you have previous called `spy.push()`. This default behavior forces your `spy.push()` and subsequent `spy.search()` activities to be _sandboxed_, meaning that they will only be visible to you within a particular workbook.\n",
    "\n",
    "If you want all items regardless of scope, specify `workbook=spy.GLOBALS_AND_ALL_WORKBOOKS`.\n",
    "\n",
    "If you want only globally-scoped items, specify `workbook=spy.GLOBALS_ONLY`.\n",
    "        \n",
    "Another option is to specify `Scoped To` within your query block. You must supply a Workbook ID -- not a workbook path like the `workbook` parameter. This approach will limit your search to just those items scoped to a particular workbook (it will _exclude_ globally-scoped items)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## DataFrame as input\n",
    "\n",
    "Instead of a Python dictionary for the `query` parameter, you can supply a Pandas DataFrame.\n",
    "\n",
    "This is generally useful when you have a DataFrame full of tag names but don't know the Seeq `ID` value and therefore can't retrieve data via `spy.pull()`. Calling `spy.search(data_frame)` effectively \"fills in\" the `ID` field for you wherever possible.\n",
    "\n",
    "The column headers specify the properties to search on and the column values specify the match criteria.\n",
    "\n",
    "If you don't specify wildcards or use a RegEx, the match must be exact. (This behavior is in contrast to the dictionary case, where the non-wildcard/RegEx match is a \"contains\" comparison.) It is assumed that your DataFrame property values should match exactly so that you can have a large set of items to query for and there won't be ambiguity between item names like `F1843CC` and `F1843CC.SP`."
   ]
  },
  {
   "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>Name</th>\n",
       "      <th>Datasource Name</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Area A_Temperature</td>\n",
       "      <td>Example Data</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Area B_Compressor Power</td>\n",
       "      <td>Example Data</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>Optimize</td>\n",
       "      <td>Example Data</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                      Name Datasource Name\n",
       "0       Area A_Temperature    Example Data\n",
       "1  Area B_Compressor Power    Example Data\n",
       "2                 Optimize    Example Data"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "my_items = pd.DataFrame({\n",
    "    'Name': [\n",
    "        'Area A_Temperature',\n",
    "        'Area B_Compressor Power',\n",
    "        'Optimize'\n",
    "    ],\n",
    "    'Datasource Name': 'Example Data'\n",
    "})\n",
    "\n",
    "my_items"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "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: left;\">Datasource 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;\">Area A_Temperature</td><td style=\"text-align: left; vertical-align: top;\">Example Data</td><td style=\"vertical-align: top;\">00:00:00.02</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><tr style=\"background-color: #EEFFEE;\"><td style=\"vertical-align: top;\">1</td><td style=\"text-align: left; vertical-align: top;\">Area B_Compressor Power</td><td style=\"text-align: left; vertical-align: top;\">Example Data</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><tr style=\"background-color: #EEFFEE;\"><td style=\"vertical-align: top;\">2</td><td style=\"text-align: left; vertical-align: top;\">Optimize</td><td style=\"text-align: left; vertical-align: top;\">Example Data</td><td style=\"vertical-align: top;\">00:00:00.01</td><td style=\"text-align: right; vertical-align: top;\">0</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",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0EF58FC2-8206-77F0-8519-ECD251B886A6</td>\n",
       "      <td>Area A_Temperature</td>\n",
       "      <td>NaN</td>\n",
       "      <td>StoredSignal</td>\n",
       "      <td>°F</td>\n",
       "      <td>Example Data</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0EF58FC2-85A1-7590-AA5F-C66CA82059F8</td>\n",
       "      <td>Area B_Compressor Power</td>\n",
       "      <td>NaN</td>\n",
       "      <td>StoredSignal</td>\n",
       "      <td>kW</td>\n",
       "      <td>Example Data</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                     ID                     Name  Description  \\\n",
       "0  0EF58FC2-8206-77F0-8519-ECD251B886A6       Area A_Temperature          NaN   \n",
       "1  0EF58FC2-85A1-7590-AA5F-C66CA82059F8  Area B_Compressor Power          NaN   \n",
       "\n",
       "           Type Value Unit Of Measure Datasource Name  Archived  \n",
       "0  StoredSignal                    °F    Example Data     False  \n",
       "1  StoredSignal                    kW    Example Data     False  "
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "spy.search(my_items)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Notice that there are no results with `Optimize` in the name because it does not exactly match any items."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "## Workbench Analysis URL as input\n",
    "Alternatively, you can supply the URL of a Workbench Analysis worksheet to the `query` parameter. The URL must be \n",
    "provided as a `str`.\n",
    "\n",
    "This is generally useful when you already have an Analysis worksheet loaded with signals, scalars or conditions \n",
    "and want to programmatically know what is loaded in that particular worksheet from Seeq Data Lab. A common scenario is \n",
    "that you want to pull all signals or conditions from a worksheet into the Data Lab notebook but you want to see first \n",
    "how many or which signals and conditions are loaded in that worksheet. \n",
    "\n",
    "```\n",
    "spy.search('http://localhost:34216/workbook/<workbookID>/worksheet/<worksheetID>')\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "## Pickling\n",
    "Sometimes a search is \"expensive\" and takes a long time to complete. In that case, it is common to\n",
    "\"pickle\" the resulting DataFrame for later use, like so:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "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: left;\">Datasource 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;\">Area ?_Compressor Stage</td><td style=\"text-align: left; vertical-align: top;\">Example Data</td><td style=\"vertical-align: top;\">00:00:00.03</td><td style=\"text-align: right; vertical-align: top;\">11</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"
    }
   ],
   "source": [
    "my_items = spy.search({\n",
    "    'Name': 'Area ?_Compressor Stage',\n",
    "    'Datasource Name': 'Example Data'\n",
    "}, estimate_sample_period=dict(Start='2019-01-01', End='2019-01-30'))\n",
    "my_items.to_pickle('pickled_search.pkl')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "Now you can \"unpickle\" the DataFrame and use it for a pull without incurring the cost of re-executing the search:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "pycharm": {
     "name": "#%% \n"
    }
   },
   "outputs": [],
   "source": [
    "unpickled_search = pd.read_pickle('pickled_search.pkl')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "You can access some of the original context of the search via the `spy` attribute of the unpickled\n",
    "DataFrame. For example, the `spy.status` tells you what queries were successful and what queries failed."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "pycharm": {
     "name": "#%% \n"
    }
   },
   "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>Name</th>\n",
       "      <th>Datasource Name</th>\n",
       "      <th>Time</th>\n",
       "      <th>Count</th>\n",
       "      <th>Pages</th>\n",
       "      <th>Result</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Area ?_Compressor Stage</td>\n",
       "      <td>Example Data</td>\n",
       "      <td>0 days 00:00:00.034308</td>\n",
       "      <td>11</td>\n",
       "      <td>1</td>\n",
       "      <td>Success</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                      Name Datasource Name                   Time  Count  \\\n",
       "0  Area ?_Compressor Stage    Example Data 0 days 00:00:00.034308     11   \n",
       "\n",
       "   Pages   Result  \n",
       "0      1  Success  "
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "unpickled_search.spy.status.df"
   ]
  },
  {
   "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": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Help on function search in module seeq.spy._search:\n",
      "\n",
      "search(query, *, all_properties=False, include_properties: 'List[str]' = None, workbook: 'Optional[str]' = 'Data Lab >> Data Lab Analysis', recursive: 'bool' = True, ignore_unindexed_properties: 'bool' = True, include_archived: 'bool' = False, include_swappable_assets: 'bool' = False, estimate_sample_period: 'Optional[dict]' = None, old_asset_format: 'bool' = None, order_by: 'Union[str, List[str]]' = None, limit: 'Optional[int]' = -1, errors: 'str' = None, quiet: 'bool' = None, status: 'Status' = None, session: 'Optional[Session]' = None) -> 'pd.DataFrame'\n",
      "    Issues a query to the Seeq Server to retrieve metadata for signals,\n",
      "    conditions, scalars and assets. This metadata can then be used to retrieve\n",
      "    samples, capsules for a particular time range via spy.pull().\n",
      "    \n",
      "    Parameters\n",
      "    ----------\n",
      "    query : {str, dict, list, pd.DataFrame, pd.Series}\n",
      "        A mapping of property / match-criteria pairs or a Seeq Workbench URL\n",
      "    \n",
      "        If you supply a dict or list of dicts, then the matching\n",
      "        operations are \"contains\" (instead of \"equal to\").\n",
      "    \n",
      "        If you supply a DataFrame or a Series, then the matching\n",
      "        operations are \"equal to\" (instead of \"contains\").\n",
      "    \n",
      "        If you supply a str, it must be the URL of a Seeq Workbench worksheet.\n",
      "        The retrieved metadata will be the signals, conditions and scalars\n",
      "        currently present on the Details Panel.\n",
      "    \n",
      "        'Name' and 'Description' fields support wildcard and regular expression\n",
      "        (regex) matching with the same syntax as within the Data tab in Seeq\n",
      "        Workbench.\n",
      "    \n",
      "        The 'Path' field allows you to query within an asset tree, where >>\n",
      "        separates each level from the next. E.g.: 'Path': 'Example >> Cooling*'\n",
      "        You can use wildcard and regular expression matching at any level but,\n",
      "        unlike the Name/Description fields, the match must be a \"full match\",\n",
      "        meaning that 'Path': 'Example' will match on a root asset tree node of\n",
      "        'Example' but not 'Example (AF)'.\n",
      "    \n",
      "        Available options are:\n",
      "    \n",
      "        =================== ===================================================\n",
      "        Property            Description\n",
      "        =================== ===================================================\n",
      "        Name                Name of the item (wildcards/regex supported)\n",
      "        Path                Asset tree path of the item (should not include the\n",
      "                            \"leaf\" asset), using ' >> ' hierarchy delimiters\n",
      "        Asset               Asset name (i.e., the name of the leaf asset) or ID\n",
      "        Type                The item type. One of 'Signal', 'Condition',\n",
      "                            'Scalar', 'Asset', 'Chart', 'Metric', 'Workbook',\n",
      "                            'Worksheet', and 'Display'\n",
      "        ID                  The item ID. If specified, all other properties\n",
      "                            are ignored and the item is retrieved directly. If\n",
      "                            the item ID is not found, an error will be raised.\n",
      "        Description         Description of the item (wildcards/regex supported)\n",
      "        Datasource Name     Name of the datasource\n",
      "        Datasource ID       The datasource ID, which corresponds to the Id\n",
      "                            field in the connector configuration\n",
      "        Datasource Class    The datasource class (e.g. 'OSIsoft PI')\n",
      "        Data ID             The data ID, whose format is managed by the\n",
      "                            datasource connector\n",
      "        Cache Enabled       True to find items where data caching is enabled\n",
      "        Scoped To           The Seeq ID of a workbook such that results are\n",
      "                            limited to ONLY items scoped to that workbook.\n",
      "        =================== ===================================================\n",
      "    \n",
      "    all_properties : bool, default False\n",
      "        Return all item properties in the result. If you would like to specify\n",
      "        exactly which properties to return (for better performance/less data),\n",
      "        use include_properties instead. If both all_properties and\n",
      "        include_properties are omitted, you will get only the properties that\n",
      "        come \"for free\" (no performance penalty) with the query.\n",
      "    \n",
      "    include_properties : list, optional\n",
      "        A list of extra properties to include in the results. If omitted, the\n",
      "        default set of properties will be returned. If both all_properties and\n",
      "        include_properties are omitted, you will get only the properties that\n",
      "        come \"for free\" (no performance penalty) with the query.\n",
      "    \n",
      "    workbook : {str, None}, default 'Data Lab >> Data Lab Analysis'\n",
      "        A path string (with ' >> ' delimiters) or an ID to indicate a workbook\n",
      "        such that, in addition to globally-scoped items, the workbook's scoped\n",
      "        items will also be returned in the results.\n",
      "    \n",
      "        If you want all items regardless of scope, use\n",
      "        workbook=spy.GLOBALS_AND_ALL_WORKBOOKS\n",
      "    \n",
      "        If you want only globally-scoped items, use\n",
      "        workbook=spy.GLOBALS_ONLY\n",
      "    \n",
      "        If you don't want globally-scoped items in your results, use the\n",
      "        'Scoped To' field in the 'query' argument instead. (See 'query'\n",
      "        argument documentation above.)\n",
      "    \n",
      "        The ID for a workbook is visible in the URL of Seeq Workbench, directly\n",
      "        after the \"workbook/\" part.\n",
      "    \n",
      "    recursive : bool, default True\n",
      "        If True, searches that include a Path entry will include items at and\n",
      "        below the specified location in an asset tree. If False, then only\n",
      "        items at the specified level will be returned. To get only the root\n",
      "        assets, supply a Path value of ''.\n",
      "    \n",
      "    ignore_unindexed_properties : bool, default True\n",
      "        If False, a ValueError will be raised if any properties are supplied\n",
      "        that cannot be used in the search.\n",
      "    \n",
      "    include_archived : bool, default False\n",
      "        If True, includes trashed/archived items in the output.\n",
      "    \n",
      "    include_swappable_assets : bool, default False\n",
      "        Adds a \"Swappable Assets\" column to the output where each cell is an\n",
      "        embedded DataFrame that includes the assets that the item refers to and\n",
      "        can theoretically be swapped for other assets using spy.swap().\n",
      "    \n",
      "    estimate_sample_period : dict, default None\n",
      "        A dict with the keys 'Start' and 'End'. If provided, an estimated\n",
      "        sample period for all signals will be included in the output. The\n",
      "        values for the 'Start' and 'End' keys must be a string that\n",
      "        pandas.to_datetime() can parse, or a pandas.Timestamp. The start\n",
      "        and end times are used to bound the calculation of the sample period.\n",
      "        If the start and end times encompass a time range that is insufficient\n",
      "        to determine the sample period, a pd.NaT will be returned.\n",
      "        If the value of 'Start' is set to None, it will default to the value\n",
      "        of 'End' minus 1 hour. Conversely, if the value of 'End' is set to\n",
      "        None, it will default to now.\n",
      "    \n",
      "    old_asset_format : bool, default True\n",
      "        Historically, spy.search() returned rows with a \"Type\" of \"Asset\"\n",
      "        whereby the \"Asset\" column was the name of the parent asset. This is\n",
      "        inconsistent with all other aspects of SPy, including\n",
      "        spy.push(metadata). If you would like Asset rows to instead be\n",
      "        consistent with the rest of SPy (whereby the \"Asset\" column is the\n",
      "        name of the current asset, not the parent), pass in False for this\n",
      "        argument.\n",
      "    \n",
      "    order_by : {str, list}, default None\n",
      "        An optional field or list of fields used to sort the search results.\n",
      "        Fields on which results can be sorted are 'ID', 'Name', and\n",
      "        'Description'.\n",
      "    \n",
      "    limit : int, default 1000\n",
      "        A limit on the number of results returned. By default, the limit is\n",
      "        1000. Specify limit=None to return all results.\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\n",
      "        'catalog', errors will be added to a 'Result' column in the status.df\n",
      "        DataFrame.\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 found and columns for each\n",
      "        property.\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.search'\n",
      "        kwargs              A dict with the values of the input parameters\n",
      "                            passed to spy.search to get the output DataFrame\n",
      "        old_asset_format    True if the old Asset format was used (see doc for\n",
      "                            old_asset_format argument)\n",
      "        status              A spy.Status object with the status of the\n",
      "                            spy.search call\n",
      "        =================== ===================================================\n",
      "    \n",
      "    Examples\n",
      "    --------\n",
      "    Search for signals with the name 'Humid' on the asset tree under\n",
      "    'Example >> Cooling Tower 1', retrieving all properties on the results:\n",
      "    \n",
      "    >>> search_results = spy.search({'Name': 'Humid', 'Path': 'Example >> Cooling Tower 1'}, all_properties=True)\n",
      "    \n",
      "    To access the stored properties:\n",
      "    >>> search_results.spy.kwargs\n",
      "    >>> search_results.spy.status\n",
      "    \n",
      "    Search for signals that have a name that starts with 'Area' in the\n",
      "    datasource 'Example Data' and determine the sample period of each signal\n",
      "    during the month of January 2018\n",
      "    \n",
      "    >>> search_results = spy.search({\n",
      "    >>>    'Name': 'Area ?_*',\n",
      "    >>>    'Datasource Name': 'Example Data'\n",
      "    >>> }, estimate_sample_period=dict(Start='2018-01-01', End='2018-02-01'))\n",
      "    \n",
      "    Using a pandas.DataFrame as the input:\n",
      "    \n",
      "    >>> my_items = pd.DataFrame(\n",
      "    >>>     {'Name': ['Area A_Temperature', 'Area B_Compressor Power', 'Optimize' ],\n",
      "    >>>      'Datasource Name': 'Example Data'})\n",
      "    >>> spy.search(my_items)\n",
      "    \n",
      "    Using a URL from a Seeq Workbench worksheet:\n",
      "    \n",
      "    >>> my_worksheet_items = spy.search(\n",
      "    >>> 'https://seeq.com/workbook/17F31703-F0B6-4C8E-B7FD-E20897BD4819/worksheet/CE6A0B92-EE00-45FC-9EB3-D162632DBB48')\n",
      "\n"
     ]
    }
   ],
   "source": [
    "help(spy.search)"
   ]
  }
 ],
 "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
}
