diff --git a/environment.yml b/environment.yml
index 483bec2..04b6ec0 100644
--- a/environment.yml
+++ b/environment.yml
@@ -21,6 +21,7 @@ dependencies:
- statsmodels
- scikit-learn
- scikit-optimize
+ - typer
- pip
- pip:
diff --git a/moepy/_nbdev.py b/moepy/_nbdev.py
index 10bf655..825ea9d 100644
--- a/moepy/_nbdev.py
+++ b/moepy/_nbdev.py
@@ -71,13 +71,18 @@
"construct_df_pred": "05-price-moe.ipynb",
"calc_error_metrics": "05-price-moe.ipynb",
"get_model_pred_ts": "05-price-moe.ipynb",
- "weighted_mean_s": "05-price-moe.ipynb"}
+ "weighted_mean_s": "05-price-moe.ipynb",
+ "app": "10-ci-cd.ipynb",
+ "get_current_package_version": "10-ci-cd.ipynb",
+ "increment_package_version": "10-ci-cd.ipynb",
+ "set_current_package_version": "10-ci-cd.ipynb"}
modules = ["retrieval.py",
"eda.py",
"lowess.py",
"surface.py",
- "moe.py"]
+ "moe.py",
+ "cicd.py"]
doc_url = "https://AyrtonB.github.io/Merit-Order-Effect/"
diff --git a/moepy/cicd.py b/moepy/cicd.py
new file mode 100644
index 0000000..efe2bfd
--- /dev/null
+++ b/moepy/cicd.py
@@ -0,0 +1,64 @@
+# AUTOGENERATED! DO NOT EDIT! File to edit: nbs/10-ci-cd.ipynb (unless otherwise specified).
+
+__all__ = ['app', 'get_current_package_version', 'increment_package_version', 'set_current_package_version']
+
+# Cell
+import os
+import re
+import typer
+import logging
+from warnings import warn
+from configparser import ConfigParser
+
+# Cell
+app = typer.Typer()
+
+# Cell
+@app.command()
+def get_current_package_version(settings_fp: str='settings.ini'):
+ config = ConfigParser(delimiters=['='])
+ config.read(settings_fp)
+ version = config.get('DEFAULT', 'version')
+
+ return version
+
+# Cell
+@app.command()
+def increment_package_version(old_version: str, increment_level: str='micro'):
+ increment = lambda rev: str(int(rev)+1)
+
+ major, minor, micro = old_version.split('.') # naming from - https://the-hitchhikers-guide-to-packaging.readthedocs.io/en/latest/specification.html#sequence-based-scheme
+
+ if increment_level == 'major':
+ major = increment(major)
+ elif increment_level == 'minor':
+ minor = increment(minor)
+ elif increment_level == 'micro':
+ micro = increment(micro)
+
+ new_version = '.'.join([major, minor, micro])
+
+ return new_version
+
+# Cell
+@app.command()
+def set_current_package_version(version: str, settings_fp: str='settings.ini'):
+ version = version.replace('v', '')
+
+ config = ConfigParser(delimiters=['='])
+ config.read(settings_fp)
+
+ config.set('DEFAULT', 'version', version)
+
+ with open(settings_fp, 'w') as configfile:
+ config.write(configfile)
+
+ logger = logging.getLogger('package_release')
+ logger.setLevel('INFO')
+ logger.info(f'The package version has to be updated to {version}')
+
+ return
+
+# Cell
+if __name__ == '__main__' and '__file__' in globals():
+ app()
\ No newline at end of file
diff --git a/nbs/10-ci-cd.ipynb b/nbs/10-ci-cd.ipynb
new file mode 100644
index 0000000..89825e9
--- /dev/null
+++ b/nbs/10-ci-cd.ipynb
@@ -0,0 +1,360 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# default_exp cicd"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# CI/CD\n",
+ "\n",
+ "
\n",
+ "\n",
+ "This notebook includes helper functions and processes used in the continuous integration and deployment of the `moepy` library.\n",
+ "\n",
+ "
\n",
+ "\n",
+ "### Imports"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "#exports\n",
+ "import os\n",
+ "import re\n",
+ "import typer\n",
+ "import logging\n",
+ "from warnings import warn\n",
+ "from configparser import ConfigParser"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "
\n",
+ "\n",
+ "### Initialising CLI "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "#exports\n",
+ "app = typer.Typer()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "
\n",
+ "\n",
+ "### Incrementing the Package Version\n",
+ "\n",
+ "We'll start by retrieving the current package version specified in `settings.ini`"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "#exports\n",
+ "@app.command()\n",
+ "def get_current_package_version(settings_fp: str='settings.ini'):\n",
+ " config = ConfigParser(delimiters=['='])\n",
+ " config.read(settings_fp)\n",
+ " version = config.get('DEFAULT', 'version')\n",
+ " \n",
+ " return version"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'0.0.3'"
+ ]
+ },
+ "execution_count": 6,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "settings_fp = '../settings.ini'\n",
+ "\n",
+ "original_version = get_current_package_version(settings_fp)\n",
+ "\n",
+ "original_version"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "
\n",
+ "\n",
+ "We'll now increment the package version"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "#exports\n",
+ "@app.command()\n",
+ "def increment_package_version(old_version: str, increment_level: str='micro'):\n",
+ " increment = lambda rev: str(int(rev)+1)\n",
+ " \n",
+ " major, minor, micro = old_version.split('.') # naming from - https://the-hitchhikers-guide-to-packaging.readthedocs.io/en/latest/specification.html#sequence-based-scheme\n",
+ " \n",
+ " if increment_level == 'major':\n",
+ " major = increment(major)\n",
+ " elif increment_level == 'minor':\n",
+ " minor = increment(minor)\n",
+ " elif increment_level == 'micro':\n",
+ " micro = increment(micro)\n",
+ " \n",
+ " new_version = '.'.join([major, minor, micro])\n",
+ " \n",
+ " return new_version"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'0.0.4'"
+ ]
+ },
+ "execution_count": 8,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "increment_package_version(original_version)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "
\n",
+ "\n",
+ "But what about if we've made large changes to the code-base and wish to express the size of these revisions in the version? For that we can specify the `increment_level`."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'1.0.3'"
+ ]
+ },
+ "execution_count": 9,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "increment_package_version(original_version, increment_level='major')"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "
\n",
+ "\n",
+ "And finally we can set the version"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "#exports\n",
+ "@app.command()\n",
+ "def set_current_package_version(version: str, settings_fp: str='settings.ini'):\n",
+ " version = version.replace('v', '')\n",
+ " \n",
+ " config = ConfigParser(delimiters=['='])\n",
+ " config.read(settings_fp)\n",
+ "\n",
+ " config.set('DEFAULT', 'version', version)\n",
+ "\n",
+ " with open(settings_fp, 'w') as configfile:\n",
+ " config.write(configfile)\n",
+ " \n",
+ " logger = logging.getLogger('package_release')\n",
+ " logger.setLevel('INFO')\n",
+ " logger.info(f'The package version has to be updated to {version}')\n",
+ " \n",
+ " return "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 11,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'9.9.9'"
+ ]
+ },
+ "execution_count": 11,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "set_current_package_version('9.9.9', settings_fp)\n",
+ "get_current_package_version(settings_fp)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "
\n",
+ "\n",
+ "Before we move on we'll change the version on file back to the original"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 12,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'0.0.3'"
+ ]
+ },
+ "execution_count": 12,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "set_current_package_version(original_version, settings_fp)\n",
+ "get_current_package_version(settings_fp)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "
\n",
+ "\n",
+ "Finally we need to ensure the CLI app is available when the module is loaded.\n",
+ "\n",
+ "N.b. we've included the condition `'__file__' in globals()` to make sure this isn't when inside the notebook"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 13,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "#exports\n",
+ "if __name__ == '__main__' and '__file__' in globals():\n",
+ " app()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 15,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Converted 01-retrieval.ipynb.\n",
+ "Converted 02-eda.ipynb.\n",
+ "Converted 03-lowess.ipynb.\n",
+ "Converted 04-price-surface-estimation.ipynb.\n",
+ "Converted 05-price-moe.ipynb.\n",
+ "Converted 06-carbon-surface-estimation-and-moe.ipynb.\n",
+ "Converted 07-prediction-confidence-and-intervals.ipynb.\n",
+ "Converted 08-hyper-parameter-tuning.ipynb.\n",
+ "Converted 09-tables-and-figures.ipynb.\n",
+ "Converted 10-ci-cd.ipynb.\n"
+ ]
+ }
+ ],
+ "source": [
+ "#hide\n",
+ "from nbdev.export import *\n",
+ "notebook2script()"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "MOE",
+ "language": "python",
+ "name": "moe"
+ },
+ "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.9.1"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/settings.ini b/settings.ini
index ab51f9a..0ef8982 100644
--- a/settings.ini
+++ b/settings.ini
@@ -21,4 +21,5 @@ title = moepy
doc_path = docs
doc_host = https://AyrtonB.github.io
doc_baseurl = /Merit-Order-Effect/
-requirements = pandas==1.2.0 numpy==1.19.5 matplotlib==3.3.3 seaborn==0.11.1 lxml==4.6.2 ipypb==0.5.2 dagster==0.9.21 scikit-learn==0.24.0 scipy==1.6.0
\ No newline at end of file
+requirements = pandas==1.2.0 numpy==1.19.5 matplotlib==3.3.3 seaborn==0.11.1 lxml==4.6.2 ipypb==0.5.2 dagster==0.9.21 scikit-learn==0.24.0 scipy==1.6.0
+