{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "provenance": [],
      "authorship_tag": "ABX9TyP35mSmCYWm9Bdhv01QXyU7",
      "include_colab_link": true
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "language_info": {
      "name": "python"
    }
  },
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "view-in-github",
        "colab_type": "text"
      },
      "source": [
        "<a href=\"https://colab.research.google.com/github/Jaciss/jai/blob/main/notebooks/bootstrap_a_notebook.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "import os\n",
        "import sys\n",
        "import logging\n",
        "\n",
        "!mkdir -p jai\n",
        "!mkdir -p jai/nbpy"
      ],
      "metadata": {
        "id": "49p5S57dw9CH"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "logger = logging.getLogger()\n",
        "logger.handlers[0].setFormatter(logging.Formatter(\n",
        "    '%(asctime)s %(levelname)-8s %(message)s',\n",
        "    \"%Y-%m-%d %H:%M:%S\"\n",
        "))\n",
        "logger.setLevel(logging.DEBUG)"
      ],
      "metadata": {
        "id": "a_0lgyqnui1C"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "Configuration is important and the most likely thing for a notebook to have so we check against that to see if it's a first time load."
      ],
      "metadata": {
        "id": "D8slQSWO9uE0"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "# check if existing config, if not set name and bootstrap (if not bootstrap)\n",
        "nb_name = 'bootstrap_a_notebook' # would *love* to get this programatically\n",
        "try:\n",
        "  c # try to get config (from remote call)\n",
        "  c['nb_run_by'] = c.get('nb_name',None) # who is running the nb\n",
        "  c['nb_name'] = nb_name # nb_name set to local until end\n",
        "except NameError:\n",
        "  c = {'nb_name':nb_name, 'nb_run_by':nb_name} # if local set c\n",
        "\n",
        "logger.info(c.get('nb_run_by',None)+'@'+c.get('nb_name',None)+' ['+sys.argv[0]+']')"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "-Je9pEtmyXPV",
        "outputId": "614d7720-d903-4b77-d568-b8de7254ead3"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            "2023-01-07 14:22:35 INFO     bootstrap_a_notebook@bootstrap_a_notebook [/usr/local/lib/python3.8/dist-packages/ipykernel_launcher.py]\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "# c['features'] = {'bddtesting','persiststorage'}\n",
        "# c['project'] = 'jai'"
      ],
      "metadata": {
        "id": "XlrIhyATh2PK"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "# stupid persistence\n",
        "from google.colab import drive\n",
        "if not os.path.isdir('/content/drive/'): drive.mount('/content/drive/')\n",
        "c['nb_dir'] = '/content/drive/MyDrive/Colab\\ Notebooks/'"
      ],
      "metadata": {
        "id": "GVw2ePRHZSPn"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "# creates features directories, provides test_notebook()\n",
        "if c['nb_run_by'] != 'bdd_testing_a_notebook' and 'jai.nbpy.bootstrap' not in sys.modules:\n",
        "  %run {c['nb_dir']}bdd_testing_a_notebook.ipynb"
      ],
      "metadata": {
        "id": "Qo6Z5eBlC-Xt",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "a6ac2bfd-29bd-4ab0-ed4e-51715417f8f0"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            "2023-01-07 04:25:04 INFO     bootstrap_a_notebook@test_a_notebook\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "\n",
            "Overwriting features/test_a_notebook.feature\n",
            "Overwriting features/steps/test_a_notebook.py\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "%%writefile features/{c.get('nb_name')}.feature\n",
        "Feature: bootstrap a notebook\n",
        "\n",
        "  # Scenario: notebooks have logging\n",
        "  #   Given we have imported \"bootstrap_a_notebook\"\n",
        "  #   Then we can log messages\n",
        "\n",
        "  Scenario: notebooks have names\n",
        "    Given we have imported \"jai.nbpy.bootstrap\"\n",
        "    When we get configuration key \"nb_name\"\n",
        "    Then configuration key \"nb_name\" is \"bootstrap_a_notebook\"\n",
        "  \n",
        "  # Scenario: notebooks have persistent storage\n",
        "  # can be run from other notebooks\n",
        "  # config"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "7YVHQguOFDB0",
        "outputId": "5c389c2f-06c2-40d2-d166-1c4c4d0fe42b"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Overwriting features/bootstrap_a_notebook.feature\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Global Config\n",
        "Notebooks default to these if they're not set. Notebooks use local config over global when working in the notebook itself.\n",
        "\n",
        "Loading configuration presets will override *all* local notebook configurations if they use `c.get(global,local)`."
      ],
      "metadata": {
        "id": "GnIoPU0YuaPQ"
      }
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "M7rQbQJ_odm6"
      },
      "outputs": [],
      "source": [
        "# import time\n",
        "\n",
        "#@title { run: \"auto\", vertical-output: true, form-width: \"45%\" }\n",
        "jai_log_level = logging.DEBUG #@param [\"logging.DEBUG\", \"logging.INFO\", \"logging.WARN\"] {type:\"raw\"}\n",
        "\n",
        "\n",
        "jai_dir='jai/'\n",
        "# jai_run_level = 3 #@param {type:\"slider\", min:0, max:3, step:1}\n",
        "# timezone = \"America/Anchorage\" #@param ['America/Anchorage','America/Denver'] {allow-input: true}\n",
        "# jairunlevels={0:'system test & setup', 1:'load existing models/data, skip optimization, creation, and save',2:'skip optimization',3:'everything'}\n",
        "# jairunlevels\n",
        "\n",
        "# os.environ['TZ'] = timezone\n",
        "# time.tzset()\n",
        "# logger.info('Set timezone: '+timezone)\n",
        "\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "source": [],
      "metadata": {
        "id": "qBDAcxH19Yo1"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "# print(c['nb_name'],'functions:')\n",
        "# %who function"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "M3QTijYJPi6c",
        "outputId": "adc585bd-732e-4399-df62-c45f1e005bbd"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "bootstrap_a_notebook functions:\n",
            "nb_convert_py\t test_notebook\t view_coverage\t \n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "# if c['nb_name'] == c['nb_run_by'] and \"ipykernel_launcher\" in sys.argv[0]: test_notebook(c['nb_name'])\n",
        "c['nb_name'] = c['nb_run_by'] # return name to calling script, if any"
      ],
      "metadata": {
        "id": "elM0DMwSBDBl",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "4d116bce-f8a5-404e-e474-f4989984563b"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "test_notebook() bootstrap_a_notebook run by bootstrap_a_notebook self: /usr/local/lib/python3.8/dist-packages/ipykernel_launcher.py\n",
            "\n",
            "Feature: bootstrap a notebook\u001b[90m # features/bootstrap_a_notebook.feature:1\u001b[0m\n",
            "\n",
            "  Scenario: notebooks have names \u001b[90m                              # features/bootstrap_a_notebook.feature:7\u001b[0m\n",
            "    \u001b[90mGiven \u001b[0m\u001b[90mwe have imported \"\u001b[0m\u001b[90m\u001b[1mbootstrap_a_notebook\u001b[0m\u001b[90m\"\u001b[0m\u001b[90m              # features/steps/test_a_notebook.py:6\u001b[0m\n",
            "\u001b[2A    \u001b[32mGiven \u001b[0m\u001b[32mwe have imported \"\u001b[0m\u001b[32m\u001b[1mbootstrap_a_notebook\u001b[0m\u001b[32m\"\u001b[0m\u001b[90m              # features/steps/test_a_notebook.py:6 0.343s\u001b[0m\n",
            "    \u001b[90mWhen \u001b[0m\u001b[90mwe get configuration key \"\u001b[0m\u001b[90m\u001b[1mnb_name\u001b[0m\u001b[90m\"\u001b[0m\u001b[90m                    # features/steps/test_a_notebook.py:26\u001b[0m\n",
            "\u001b[2A    \u001b[32mWhen \u001b[0m\u001b[32mwe get configuration key \"\u001b[0m\u001b[32m\u001b[1mnb_name\u001b[0m\u001b[32m\"\u001b[0m\u001b[90m                    # features/steps/test_a_notebook.py:26 0.000s\u001b[0m\n",
            "    \u001b[90mThen \u001b[0m\u001b[90mconfiguration key \"\u001b[0m\u001b[90m\u001b[1mnb_name\u001b[0m\u001b[90m\" is \"\u001b[0m\u001b[90m\u001b[1mbootstrap_a_notebook\u001b[0m\u001b[90m\"\u001b[0m\u001b[90m # features/steps/test_a_notebook.py:31\u001b[0m\n",
            "\u001b[2A    \u001b[32mThen \u001b[0m\u001b[32mconfiguration key \"\u001b[0m\u001b[32m\u001b[1mnb_name\u001b[0m\u001b[32m\" is \"\u001b[0m\u001b[32m\u001b[1mbootstrap_a_notebook\u001b[0m\u001b[32m\"\u001b[0m\u001b[90m # features/steps/test_a_notebook.py:31 0.000s\u001b[0m\n",
            "\n",
            "Feature: test notebooks using bdd\u001b[90m # features/test_a_notebook.feature:1\u001b[0m\n",
            "\n",
            "  Scenario: this notebook is named test_a_notebook \u001b[90m       # features/test_a_notebook.feature:3\u001b[0m\n",
            "    \u001b[90mGiven \u001b[0m\u001b[90mwe have imported the notebook for this step\u001b[0m\u001b[90m     # features/steps/test_a_notebook.py:19\u001b[0m\n",
            "[NbConvertApp] Converting notebook drive/MyDrive/Colab Notebooks/bootstrap_a_notebook.ipynb to python\n",
            "[NbConvertApp] Writing 3117 bytes to ./bootstrap_a_notebook.py\n",
            "\u001b[2A    \u001b[32mGiven \u001b[0m\u001b[32mwe have imported the notebook for this step\u001b[0m\u001b[90m     # features/steps/test_a_notebook.py:19 1.465s\u001b[0m\n",
            "    \u001b[90mWhen \u001b[0m\u001b[90mwe get configuration key \"\u001b[0m\u001b[90m\u001b[1mnb_name\u001b[0m\u001b[90m\"\u001b[0m\u001b[90m               # features/steps/test_a_notebook.py:26\u001b[0m\n",
            "\u001b[2A    \u001b[32mWhen \u001b[0m\u001b[32mwe get configuration key \"\u001b[0m\u001b[32m\u001b[1mnb_name\u001b[0m\u001b[32m\"\u001b[0m\u001b[90m               # features/steps/test_a_notebook.py:26 0.000s\u001b[0m\n",
            "    \u001b[90mThen \u001b[0m\u001b[90mconfiguration key \"\u001b[0m\u001b[90m\u001b[1mnb_name\u001b[0m\u001b[90m\" is \"\u001b[0m\u001b[90m\u001b[1mtest_a_notebook\u001b[0m\u001b[90m\"\u001b[0m\u001b[90m # features/steps/test_a_notebook.py:31\u001b[0m\n",
            "\u001b[2A    \u001b[32mThen \u001b[0m\u001b[32mconfiguration key \"\u001b[0m\u001b[32m\u001b[1mnb_name\u001b[0m\u001b[32m\" is \"\u001b[0m\u001b[32m\u001b[1mtest_a_notebook\u001b[0m\u001b[32m\"\u001b[0m\u001b[90m # features/steps/test_a_notebook.py:31 0.000s\u001b[0m\n",
            "\n",
            "  Scenario: tests calling tests avoids infinite recursion \u001b[90m # features/test_a_notebook.feature:8\u001b[0m\n",
            "    \u001b[90mGiven \u001b[0m\u001b[90mwe have imported \"\u001b[0m\u001b[90m\u001b[1mtest_a_notebook\u001b[0m\u001b[90m\"\u001b[0m\u001b[90m               # features/steps/test_a_notebook.py:6\u001b[0m\n",
            "\u001b[2A    \u001b[32mGiven \u001b[0m\u001b[32mwe have imported \"\u001b[0m\u001b[32m\u001b[1mtest_a_notebook\u001b[0m\u001b[32m\"\u001b[0m\u001b[90m               # features/steps/test_a_notebook.py:6 0.000s\u001b[0m\n",
            "    \u001b[90mAnd \u001b[0m\u001b[90mwe have imported \"\u001b[0m\u001b[90m\u001b[1mbootstrap_a_notebook\u001b[0m\u001b[90m\"\u001b[0m\u001b[90m            # features/steps/test_a_notebook.py:6\u001b[0m\n",
            "\u001b[2A    \u001b[32mAnd \u001b[0m\u001b[32mwe have imported \"\u001b[0m\u001b[32m\u001b[1mbootstrap_a_notebook\u001b[0m\u001b[32m\"\u001b[0m\u001b[90m            # features/steps/test_a_notebook.py:6 0.000s\u001b[0m\n",
            "    \u001b[90mWhen \u001b[0m\u001b[90mwe run test_notebook on \"\u001b[0m\u001b[90m\u001b[1mbootstrap_a_notebook\u001b[0m\u001b[90m\"\u001b[0m\u001b[90m    # features/steps/test_a_notebook.py:35\u001b[0m\n",
            "[NbConvertApp] Converting notebook drive/MyDrive/Colab Notebooks/bootstrap_a_notebook.ipynb to python\n",
            "[NbConvertApp] Writing 3117 bytes to ./bootstrap_a_notebook.py\n",
            "\u001b[2A    \u001b[32mWhen \u001b[0m\u001b[32mwe run test_notebook on \"\u001b[0m\u001b[32m\u001b[1mbootstrap_a_notebook\u001b[0m\u001b[32m\"\u001b[0m\u001b[90m    # features/steps/test_a_notebook.py:35 1.664s\u001b[0m\n",
            "    \u001b[90mThen \u001b[0m\u001b[90mwe will see \"\u001b[0m\u001b[90m\u001b[1minfinite recursion\u001b[0m\u001b[90m\" in output\u001b[0m\u001b[90m        # features/steps/test_a_notebook.py:44\u001b[0m\n",
            "\u001b[2A    \u001b[32mThen \u001b[0m\u001b[32mwe will see \"\u001b[0m\u001b[32m\u001b[1minfinite recursion\u001b[0m\u001b[32m\" in output\u001b[0m\u001b[90m        # features/steps/test_a_notebook.py:44 0.000s\u001b[0m\n",
            "\n",
            "2 features passed, 0 failed, 0 skipped\n",
            "3 scenarios passed, 0 failed, 0 skipped\n",
            "10 steps passed, 0 failed, 0 skipped, 0 undefined\n",
            "Took 0m3.473s\n",
            "Wrote HTML report to htmlcov/index.html\n",
            "Wrote JSON report to coverage.json\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "# view_coverage()"
      ],
      "metadata": {
        "id": "xvw-yfEqHALm"
      },
      "execution_count": null,
      "outputs": []
    }
  ]
}