{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import sys"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'3.7.9 (default, Aug 31 2020, 07:22:35) \\n[Clang 10.0.0 ]'"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sys.version"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Warning: QApplication was created before pyqtgraph was imported; there may be problems (to avoid bugs, call QApplication.setGraphicsSystem(\"raster\") before the QApplication is created).\n"
     ]
    }
   ],
   "source": [
    "import sys\n",
    "\n",
    "sys.path.append(\"/users/samuel/documents/github/pyrpl\")\n",
    "from pyrpl import Pyrpl\n",
    "from pyrpl.async_utils import ensure_future, sleep_async\n",
    "\n",
    "import os\n",
    "\n",
    "os.environ[\"REDPITAYA_HOSTNAME\"] = \"redpitaya\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Populating the interactive namespace from numpy and matplotlib\n"
     ]
    }
   ],
   "source": [
    "%pylab qt\n",
    "import sys\n",
    "\n",
    "sys.path.append(\"/users/samuel/documents/github/pyrpl\")\n",
    "\n",
    "import os\n",
    "\n",
    "os.environ[\"REDPITAYA_HOSTNAME\"] = \"redpitaya\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:pyrpl.redpitaya:Successfully connected to Redpitaya with hostname redpitaya.\n"
     ]
    }
   ],
   "source": [
    "p = Pyrpl(config=\"\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "from asyncio import Future"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import nbformat\n",
    "from nbconvert.preprocessors import ExecutePreprocessor\n",
    "from nbconvert.preprocessors.execute import CellExecutionError\n",
    "\n",
    "\n",
    "class MyExecutePreprocessor(ExecutePreprocessor):\n",
    "    def preprocess_cell(self, cell, resources, cell_index):\n",
    "        if cell.source.startswith(\"#no-test\"):\n",
    "            return cell, resources\n",
    "        if cell.source.startswith(\"#define-hostname\"):\n",
    "            # replace hostname by unittest hostname\n",
    "            if defaultparameters[\"hostname\"] is not None:\n",
    "                cell.source = \"HOSTNAME = \" + defaultparameters[\"hostname\"]\n",
    "            if \"REDPITAYA_HOSTNAME\" in os.environ:\n",
    "                cell.source = 'HOSTNAME = \"' + os.environ[\"REDPITAYA_HOSTNAME\"] + '\"'\n",
    "        return super(MyExecutePreprocessor, self).preprocess_cell(cell, resources, cell_index)\n",
    "\n",
    "\n",
    "filename = (\n",
    "    r\"/Users/samuel/Documents/GitHub/pyrpl/pyrpl/test/test_ipython_notebook/test_notebook.ipynb\"\n",
    ")\n",
    "\n",
    "\n",
    "def _notebook_run(path):\n",
    "    \"\"\"\n",
    "    Execute a notebook via nbconvert and collect output.\n",
    "    :returns (parsed nb object, execution errors)\n",
    "    \"\"\"\n",
    "    kernel_name = \"python%d\" % sys.version_info[0]\n",
    "    errors = []\n",
    "\n",
    "    with open(path) as f:\n",
    "        nb = nbformat.read(f, as_version=4)\n",
    "        nb.metadata.get(\"kernelspec\", {})[\"name\"] = kernel_name\n",
    "        ep = MyExecutePreprocessor(kernel_name=kernel_name, timeout=65)  # ,\n",
    "        # allow_errors=True\n",
    "        # ep.start_new_kernel()\n",
    "        try:\n",
    "            ep.preprocess(nb, resources={\"metadata\": {\"path\": \"\"}})\n",
    "        except (CellExecutionError, TimeoutError) as e:\n",
    "            if hasattr(e, \"traceback\") and \"SKIP\" in e.traceback:\n",
    "                print(str(e.traceback).split(\"\\n\")[-2])\n",
    "            else:\n",
    "                raise e\n",
    "    return nb, errors\n",
    "\n",
    "\n",
    "_notebook_run(filename)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<coroutine object sleep_async at 0x7fd95600d710>"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sleep_async(1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "isinstance(ensure_future(sleep_async(1)), Future)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "t = ensure_future(sleep_async(1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "isinstance(t, Future)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Task finished coro=<sleep_async() done, defined at /Users/samuel/Documents/GitHub/pyrpl/pyrpl/async_utils.py:66> result=None>"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "t"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Task pending coro=<sleep_async() running at /Users/samuel/Documents/GitHub/pyrpl/pyrpl/async_utils.py:66>>"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ensure_future(sleep_async(1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "_asyncio.Future"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Future"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "_asyncio.Task"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "t.__class__"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'\\n    Schedules the task described by the coroutine. Deals properly with\\n    IPython kernel integration.\\n    '"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ensure_future.__doc__"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "from asyncio.tasks import Task"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "ERROR:asyncio:Task exception was never retrieved\n",
      "future: <Task finished coro=<sleep_async() done, defined at /Users/samuel/Documents/GitHub/pyrpl/pyrpl/async_utils.py:66> exception=RuntimeError('Task <Task pending coro=<sleep_async() running at /Users/samuel/Documents/GitHub/pyrpl/pyrpl/async_utils.py:71>> got Future <Future pending> attached to a different loop')>\n",
      "Traceback (most recent call last):\n",
      "  File \"/Users/samuel/Documents/GitHub/pyrpl/pyrpl/async_utils.py\", line 71, in sleep_async\n",
      "    await asyncio.sleep(time_s, loop=LOOP)\n",
      "  File \"/Users/samuel/opt/anaconda3/envs/py37/lib/python3.7/asyncio/tasks.py\", line 595, in sleep\n",
      "    return await future\n",
      "RuntimeError: Task <Task pending coro=<sleep_async() running at /Users/samuel/Documents/GitHub/pyrpl/pyrpl/async_utils.py:71>> got Future <Future pending> attached to a different loop\n"
     ]
    }
   ],
   "source": [
    "isinstance(Task(sleep_async(1)), Future)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython",
   "version": "3.7.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
