diff --git a/Makefile b/Makefile
index e8d9782f5..d7494b6f9 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-# https://stackoverflow.com/questions/10858261/how-to-abort-makefile-if-variable-not-set
+ # https://stackoverflow.com/questions/10858261/how-to-abort-makefile-if-variable-not-set
check_defined = \
$(strip $(foreach 1,$1, \
$(call __check_defined,$1,$(strip $(value 2)))))
@@ -79,3 +79,7 @@ ensure-clean-notebooks:
check: copyright format lint test verify-copyright verify-exposed-credentials ensure-clean-notebooks
.PHONY: docs
+
+notebook:
+ @python notebooks/templates/e2e_template.py
+ git status | grep -v 'notebooks/templates'
diff --git a/notebooks/README.md b/notebooks/README.md
index 327645c77..24a923b91 100644
--- a/notebooks/README.md
+++ b/notebooks/README.md
@@ -8,8 +8,6 @@ Sample notebooks are organized into the following folders:
* `notebooks/how_to` — Learn how to use specific ValidMind features, e.g. how to list all test suites
* `notebooks/tutorials` — Get step-by-step instructions and learn about ValidMind concepts in depth
* `notebooks/code_sharing` — Share your own notebooks or document code internally
-* `notebooks/archive` — Deprecrated notebooks, that have either been retired or replaced with newer content
-
## Getting started
@@ -19,3 +17,7 @@ If this is your first time trying out ValidMind, you can make use of the followi
- [Get started](https://docs.validmind.ai/get-started/get-started.html) — The basics, including key concepts, and how our products work
- [Get started with the ValidMind Library](https://docs.validmind.ai/developer/get-started-validmind-library.html) — The path for developers, more code samples, and our developer reference
+
+## Contributing code samples
+
+Head over to [`notebooks/templates`](templates/) to find templates to help you create your own custom ValidMind code samples.
diff --git a/notebooks/templates/README.md b/notebooks/templates/README.md
new file mode 100644
index 000000000..70a46d4d7
--- /dev/null
+++ b/notebooks/templates/README.md
@@ -0,0 +1,18 @@
+# Jupyter Notebook template QuickStart
+
+Want to create some code samples for ValidMind? Our **[End-to-end notebook template generation](e2e-notebook.ipynb) notebook** will generate a new file with all the bits and pieces of a standard ValidMind notebook to get you started.
+
+The same functionality is also accesible [in our root directory Makefile](../../Makefile) as a command:
+
+```bash
+make notebook
+```
+
+## Mini-templates
+
+The template generation script/notebook draws from the following mini-templates, should you need to revise them or grab the information from them manually:
+
+- [`about-validmind.ipynb`](about-validmind.ipynb): Conceptual overview of ValidMind & prerequisites.
+- [`install-initialize-validmind.ipynb`](install-initialize-validmind.ipynb): ValidMind Library installation & initialization instructions.
+- [`next-steps.ipynb`](next-steps.ipynb): Directions to review the generated documentation within the ValidMind Platform & additional learning resources.
+- [`upgrade-validmind.ipynb`](upgrade-validmind.ipynb): Instructions for comparing & upgrading versions of the ValidMind Library.
\ No newline at end of file
diff --git a/notebooks/templates/about-validmind.ipynb b/notebooks/templates/about-validmind.ipynb
new file mode 100644
index 000000000..ace181c85
--- /dev/null
+++ b/notebooks/templates/about-validmind.ipynb
@@ -0,0 +1,82 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "about-intro",
+ "metadata": {},
+ "source": [
+ "## About ValidMind\n",
+ "\n",
+ "ValidMind is a suite of tools for managing model risk, including risk associated with AI and statistical models. \n",
+ "\n",
+ "You use the ValidMind Library to automate documentation and validation tests, and then use the ValidMind Platform to collaborate on model documentation. Together, these products simplify model risk management, facilitate compliance with regulations and institutional standards, and enhance collaboration between yourself and model validators."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "about-begin",
+ "metadata": {},
+ "source": [
+ "### Before you begin\n",
+ "\n",
+ "This notebook assumes you have basic familiarity with Python, including an understanding of how functions work. If you are new to Python, you can still run the notebook but we recommend further familiarizing yourself with the language. \n",
+ "\n",
+ "If you encounter errors due to missing modules in your Python environment, install the modules with `pip install`, and then re-run the notebook. For more help, refer to [Installing Python Modules](https://docs.python.org/3/installing/index.html)."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "about-signup",
+ "metadata": {},
+ "source": [
+ "### New to ValidMind?\n",
+ "\n",
+ "If you haven't already seen our [Get started with the ValidMind Library](https://docs.validmind.ai/guide/get-started-validmind-library.html), we recommend you explore the available resources for developers at some point. There, you can learn more about documenting models, find code samples, or read our developer reference.\n",
+ "\n",
+ "
For access to all features available in this notebook, create a free ValidMind account.\n",
+ "
\n",
+ "Signing up is FREE —
Register with ValidMind "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "about-concepts",
+ "metadata": {},
+ "source": [
+ "### Key concepts\n",
+ "\n",
+ "**Model documentation**: A structured and detailed record pertaining to a model, encompassing key components such as its underlying assumptions, methodologies, data sources, inputs, performance metrics, evaluations, limitations, and intended uses. It serves to ensure transparency, adherence to regulatory requirements, and a clear understanding of potential risks associated with the model’s application.\n",
+ "\n",
+ "**Documentation template**: Functions as a test suite and lays out the structure of model documentation, segmented into various sections and sub-sections. Documentation templates define the structure of your model documentation, specifying the tests that should be run, and how the results should be displayed.\n",
+ "\n",
+ "**Tests**: A function contained in the ValidMind Library, designed to run a specific quantitative test on the dataset or model. Tests are the building blocks of ValidMind, used to evaluate and document models and datasets, and can be run individually or as part of a suite defined by your model documentation template.\n",
+ "\n",
+ "**Metrics**: A subset of tests that do not have thresholds. In the context of this notebook, metrics and tests can be thought of as interchangeable concepts.\n",
+ "\n",
+ "**Custom metrics**: Custom metrics are functions that you define to evaluate your model or dataset. These functions can be registered with the ValidMind Library to be used in the ValidMind Platform.\n",
+ "\n",
+ "**Inputs**: Objects to be evaluated and documented in the ValidMind Library. They can be any of the following:\n",
+ "\n",
+ " - **model**: A single model that has been initialized in ValidMind with [`vm.init_model()`](/validmind/validmind.html#init_model).\n",
+ " - **dataset**: Single dataset that has been initialized in ValidMind with [`vm.init_dataset()`](/validmind/validmind.html#init_dataset).\n",
+ " - **models**: A list of ValidMind models - usually this is used when you want to compare multiple models in your custom metric.\n",
+ " - **datasets**: A list of ValidMind datasets - usually this is used when you want to compare multiple datasets in your custom metric. See this [example](/notebooks/how_to/run_tests_that_require_multiple_datasets.ipynb) for more information.\n",
+ "\n",
+ "**Parameters**: Additional arguments that can be passed when running a ValidMind test, used to pass additional information to a metric, customize its behavior, or provide additional context.\n",
+ "\n",
+ "**Outputs**: Custom metrics can return elements like tables or plots. Tables may be a list of dictionaries (each representing a row) or a pandas DataFrame. Plots may be matplotlib or plotly figures.\n",
+ "\n",
+ "**Test suites**: Collections of tests designed to run together to automate and generate model documentation end-to-end for specific use-cases.\n",
+ "\n",
+ "Example: the [`classifier_full_suite`](/validmind/validmind/test_suites/classifier.html#ClassifierFullSuite) test suite runs tests from the [`tabular_dataset`](/validmind/validmind/test_suites/tabular_datasets.html) and [`classifier`](/validmind/validmind/test_suites/classifier.html) test suites to fully document the data and model sections for binary classification model use-cases."
+ ]
+ }
+ ],
+ "metadata": {
+ "language_info": {
+ "name": "python"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/notebooks/templates/e2e-notebook.ipynb b/notebooks/templates/e2e-notebook.ipynb
new file mode 100644
index 000000000..0aea82b80
--- /dev/null
+++ b/notebooks/templates/e2e-notebook.ipynb
@@ -0,0 +1,285 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# End-to-end notebook template generation\n",
+ "\n",
+ "This notebook (and attached script) creates a new `.ipynb` file in `~notebooks/code_sharing` to get you started with crafting a custom code sample for ValidMind."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Contents\n",
+ "- [Setting up](#toc1_) \n",
+ " - [Import the notebook creation script](#toc1_1_) \n",
+ " - [Designate the filename](#toc1_2_) \n",
+ " - [Set the title](#toc1_3_) \n",
+ "- [Single-sourcing from mini-templates](#toc2_) \n",
+ " - [Insert information about ValidMind](#toc2_1_) \n",
+ " - [Insert installation instructions](#toc2_2_) \n",
+ " - [Insert next steps](#toc2_3_) \n",
+ " - [Insert upgrade information](#toc2_4_) \n",
+ "- [Next steps](#toc3_) \n",
+ " - [Show files to commit](#toc3_1_) \n",
+ " - [Wrap it up](#toc3_2_) \n",
+ "\n",
+ "\n",
+ ""
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ "## Setting up "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ "### Import the notebook creation script \n",
+ "\n",
+ "This step loads our custom [`e2e_template.py`](e2e_template.py) and its dependencies with a shortened alias so that the subsequent cells have access to the script."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import e2e_template as tm"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ "### Designate the filename \n",
+ "\n",
+ "You'll be asked to input the filename, without the `.ipynb` extension. If you don't provide one, no file will be created.\n",
+ "\n",
+ "**This step will create a `.ipynb` file in `~/notebooks/code_sharing` on your behalf.** It will also open up the file for you so you don't have to go and find it. "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "filepath = tm.create_notebook()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ "### Set the title \n",
+ "\n",
+ "You'll then be asked to add a title, which will be inserted as an `h1` header in a markdown cell at the top of the notebook.\n",
+ "\n",
+ "If you don't provide input, adding the title will be skipped."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "if filepath:\n",
+ " tm.set_title(filepath)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ "## Single-sourcing from mini-templates "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ "### Insert information about ValidMind \n",
+ "\n",
+ "You'll be asked if you want to include the contents of [`about-validmind.ipynb`](about-validmind.ipynb). "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "if filepath:\n",
+ " tm.add_about(filepath)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ "### Insert installation instructions \n",
+ "\n",
+ "Next, you'll be asked if you want to include the contents of [`install-initialize-validmind.ipynb`](install-initialize-validmind.ipynb). \n",
+ "\n",
+ "**You'll also be prompted to enter a `{template}` and a `{use-case}` here if you choose to include the installation instructions.**"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "if filepath:\n",
+ " tm.add_install(filepath)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ "### Insert next steps \n",
+ "\n",
+ "You'll then asked if you want to include the contents of [`next-steps.ipynb`](next-steps.ipynb). "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "if filepath:\n",
+ " tm.next_steps(filepath)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ "### Insert upgrade information \n",
+ "\n",
+ "Finally, you'll be asked if you want to include the contents of [`upgrade-validmind.ipynb`](upgrade-validmind.ipynb). "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "if filepath:\n",
+ " tm.add_upgrade(filepath)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ "## Next steps \n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ "### Show files to commit \n",
+ "\n",
+ "This block shows you the files changed or added by the notebook you need to commit — it should omit any files in `~notebooks/templates`. "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "%%bash\n",
+ "cd ../../\n",
+ "git status | grep -v 'notebooks/templates'"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "On commiting files\n",
+ "
\n",
+ "Make sure that when you commit your changes to remote, do NOT include the changes in the ~/notebooks/templates folder as that would commit changed notebook with the output cells.
"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ "\n",
+ "### Wrap it up \n",
+ "\n",
+ "- [ ] Review the generated notebook to confirm that everything you expect to be included is there.\n",
+ "- [ ] If inserted, confirm that the **Documentation template** and **Use case** under `Get your code snippet` from [`install-initialize-validmind.ipynb`](install-initialize-validmind.ipynb) matches your actual requirements.\n",
+ "- [ ] Go forth and complete that custom sample!"
+ ]
+ }
+ ],
+ "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": "ipython3",
+ "version": "3.10.13"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/notebooks/templates/e2e_template.py b/notebooks/templates/e2e_template.py
new file mode 100644
index 000000000..3973ae3c1
--- /dev/null
+++ b/notebooks/templates/e2e_template.py
@@ -0,0 +1,289 @@
+import nbformat
+import os
+import uuid
+import subprocess
+
+def ensure_ids(notebook):
+ """Ensure every cell in the notebook has a unique id."""
+ for cell in notebook.cells:
+ if "id" not in cell:
+ cell["id"] = str(uuid.uuid4())
+ return notebook
+
+def create_notebook():
+ """Creates a new Jupyter Notebook file by asking the user for a filename and opens it in VS Code."""
+ filename = input("Enter the name for the new notebook (without .ipynb extension): ").strip()
+ if not filename:
+ print("Filename cannot be empty, file not created")
+ return
+
+ if not filename.endswith(".ipynb"):
+ filename += ".ipynb"
+
+ current_dir = os.path.dirname(__file__)
+ directory = os.path.join(current_dir, "..", "code_sharing")
+
+ if not os.path.exists(directory):
+ os.makedirs(directory)
+
+ filepath = os.path.join(directory, filename)
+
+ notebook = nbformat.v4.new_notebook()
+ notebook["metadata"] = {
+ "kernelspec": {
+ "name": "python3",
+ "display_name": "Python 3",
+ "language": "python"
+ },
+ "language_info": {
+ "name": "python",
+ "version": "3.10"
+ }
+ }
+
+ notebook = ensure_ids(notebook)
+
+ try:
+ with open(filepath, "w") as f:
+ nbformat.write(notebook, f)
+ print(f"Created '{filepath}'")
+
+ subprocess.run(["code", filepath], check=True)
+ except Exception as e:
+ print(f"Error creating or opening notebook: {e}")
+
+ return filepath
+
+def set_title(filepath):
+ """Adds a markdown cell with a h1 title to the specified notebook."""
+ if not os.path.exists(filepath):
+ print("The specified notebook file does not exist")
+ return
+
+ try:
+ with open(filepath, "r") as f:
+ notebook = nbformat.read(f, as_version=4)
+ except Exception as e:
+ print(f"Error reading notebook: {e}")
+ return
+
+ title = input("Enter the title for the notebook: ").strip()
+ if not title:
+ print("No title inputted, skipped insertion")
+ return
+
+ markdown_cell = nbformat.v4.new_markdown_cell(f"# {title}")
+ notebook.cells.insert(0, markdown_cell)
+
+ notebook = ensure_ids(notebook)
+
+ try:
+ with open(filepath, "w") as f:
+ nbformat.write(notebook, f)
+ print(f"Set title for '{filepath}': '{title}'")
+ except Exception as e:
+ print(f"Error updating notebook: {e}")
+
+def add_about(filepath):
+ """Appends the contents of 'about-validmind.ipynb' to the specified notebook if the user agrees."""
+ source_notebook_path = os.path.join(os.path.dirname(__file__), "about-validmind.ipynb")
+
+ if not os.path.exists(source_notebook_path):
+ print(f"Source notebook '{source_notebook_path}' does not exist")
+ return
+
+ user_input = input("Do you want to include information about ValidMind? (yes/no): ").strip().lower()
+ if user_input not in ("yes", "y"):
+ print("Skipping appending 'about-validmind.ipynb'")
+ return
+
+ try:
+ with open(filepath, "r") as target_file:
+ target_notebook = nbformat.read(target_file, as_version=4)
+
+ with open(source_notebook_path, "r") as source_file:
+ source_notebook = nbformat.read(source_file, as_version=4)
+ except Exception as e:
+ print(f"Error reading notebooks: {e}")
+ return
+
+ for cell in source_notebook.cells:
+ original_id = cell.get("id", f"cell-{uuid.uuid4()}")
+ new_id = f"{original_id}-{uuid.uuid4()}"
+ cell["id"] = new_id
+
+ target_notebook.cells.extend(source_notebook.cells)
+ target_notebook = ensure_ids(target_notebook)
+
+ try:
+ with open(filepath, "w") as target_file:
+ nbformat.write(target_notebook, target_file)
+ print(f"'about-validmind.ipynb' appended to '{filepath}'")
+ except Exception as e:
+ print(f"Error appending notebooks: {e}")
+
+def replace_variables(filepath):
+ """Replaces target variables in the open file based on user input."""
+ try:
+ with open(filepath, "r") as file:
+ content = file.read()
+
+ # Track if any replacements were made
+ replacements_made = False
+
+ # Locate and replace {template}
+ if "{template}" in content:
+ template_value = input("Enter a value to replace {template}: ").strip()
+ if not template_value:
+ print("No value entered for {template}, skipping replacement")
+ else:
+ content = content.replace("{template}", template_value)
+ print(f"Template: {template_value}")
+ replacements_made = True
+
+ # Locate and replace {use-case}
+ if "{use-case}" in content:
+ use_case_value = input("Enter a value to replace {use-case}: ").strip()
+ if not use_case_value:
+ print("No value entered for {use-case}, skipping replacement")
+ else:
+ content = content.replace("{use-case}", use_case_value)
+ print(f"Use case: {use_case_value}")
+ replacements_made = True
+
+ with open(filepath, "w") as file:
+ file.write(content)
+
+ if replacements_made:
+ print(f"Replaced template and use case variables in '{filepath}'")
+ except Exception as e:
+ print(f"Error replacing variables in file: {e}")
+
+def add_install(filepath):
+ """Appends the contents of 'install-initialize-validmind.ipynb' to the specified notebook if the user agrees."""
+ source_notebook_path = os.path.join(os.path.dirname(__file__), "install-initialize-validmind.ipynb")
+
+ if not os.path.exists(source_notebook_path):
+ print(f"Source notebook '{source_notebook_path}' does not exist")
+ return
+
+ user_input = input("Do you want to include installation and initialization instructions? (yes/no): ").strip().lower()
+ if user_input not in ("yes", "y"):
+ print("Skipping appending 'install-initialize-validmind.ipynb'")
+ return
+
+ try:
+ with open(filepath, "r") as target_file:
+ target_notebook = nbformat.read(target_file, as_version=4)
+
+ with open(source_notebook_path, "r") as source_file:
+ source_notebook = nbformat.read(source_file, as_version=4)
+ except Exception as e:
+ print(f"Error reading notebooks: {e}")
+ return
+
+ for cell in source_notebook.cells:
+ original_id = cell.get("id", f"cell-{uuid.uuid4()}")
+ new_id = f"{original_id}-{uuid.uuid4()}"
+ cell["id"] = new_id
+
+ target_notebook.cells.extend(source_notebook.cells)
+ target_notebook = ensure_ids(target_notebook)
+
+ try:
+ with open(filepath, "w") as target_file:
+ nbformat.write(target_notebook, target_file)
+ print(f"'install-initialize-validmind.ipynb' appended to '{filepath}'")
+ except Exception as e:
+ print(f"Error appending notebooks: {e}")
+
+ replace_variables(filepath)
+
+def next_steps(filepath):
+ """Appends the contents of 'next-steps.ipynb' to the specified notebook if the user agrees."""
+ source_notebook_path = os.path.join(os.path.dirname(__file__), "next-steps.ipynb")
+
+ if not os.path.exists(source_notebook_path):
+ print(f"Source notebook '{source_notebook_path}' does not exist")
+ return
+
+ user_input = input("Do you want to include next steps? (yes/no): ").strip().lower()
+ if user_input not in ("yes", "y"):
+ print("Skipping appending 'next-steps.ipynb'")
+ return
+
+ try:
+ with open(filepath, "r") as target_file:
+ target_notebook = nbformat.read(target_file, as_version=4)
+
+ with open(source_notebook_path, "r") as source_file:
+ source_notebook = nbformat.read(source_file, as_version=4)
+ except Exception as e:
+ print(f"Error reading notebooks: {e}")
+ return
+
+ for cell in source_notebook.cells:
+ original_id = cell.get("id", f"cell-{uuid.uuid4()}")
+ new_id = f"{original_id}-{uuid.uuid4()}"
+ cell["id"] = new_id
+
+ target_notebook.cells.extend(source_notebook.cells)
+ target_notebook = ensure_ids(target_notebook)
+
+ try:
+ with open(filepath, "w") as target_file:
+ nbformat.write(target_notebook, target_file)
+ print(f"'next-steps.ipynb' appended to '{filepath}'")
+ except Exception as e:
+ print(f"Error appending notebooks: {e}")
+
+def add_upgrade(filepath):
+ """Appends the contents of 'upgrade-validmind.ipynb' to the specified notebook if the user agrees."""
+ source_notebook_path = os.path.join(os.path.dirname(__file__), "upgrade-validmind.ipynb")
+
+ if not os.path.exists(source_notebook_path):
+ print(f"Source notebook '{source_notebook_path}' does not exist")
+ return
+
+ user_input = input("Do you want to include information about upgrading ValidMind? (yes/no): ").strip().lower()
+ if user_input not in ("yes", "y"):
+ print("Skipping appending 'upgrade-validmind.ipynb'")
+ return
+
+ try:
+ with open(filepath, "r") as target_file:
+ target_notebook = nbformat.read(target_file, as_version=4)
+
+ with open(source_notebook_path, "r") as source_file:
+ source_notebook = nbformat.read(source_file, as_version=4)
+ except Exception as e:
+ print(f"Error reading notebooks: {e}")
+ return
+
+ for cell in source_notebook.cells:
+ original_id = cell.get("id", f"cell-{uuid.uuid4()}")
+ new_id = f"{original_id}-{uuid.uuid4()}"
+ cell["id"] = new_id
+
+ target_notebook.cells.extend(source_notebook.cells)
+ target_notebook = ensure_ids(target_notebook)
+
+ try:
+ with open(filepath, "w") as target_file:
+ nbformat.write(target_notebook, target_file)
+ print(f"'upgrade-validmind.ipynb' appended to '{filepath}'")
+ except Exception as e:
+ print(f"Error appending notebooks: {e}")
+
+if __name__ == "__main__":
+
+ script_dir = os.path.dirname(os.path.abspath(__file__))
+ os.chdir(script_dir)
+
+ filepath = create_notebook()
+ if filepath:
+ set_title(filepath)
+ add_about(filepath)
+ add_install(filepath)
+ next_steps(filepath)
+ add_upgrade(filepath)
\ No newline at end of file
diff --git a/notebooks/templates/install-initialize-validmind.ipynb b/notebooks/templates/install-initialize-validmind.ipynb
new file mode 100644
index 000000000..9cf155995
--- /dev/null
+++ b/notebooks/templates/install-initialize-validmind.ipynb
@@ -0,0 +1,102 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "install-library",
+ "metadata": {},
+ "source": [
+ "## Install the ValidMind Library\n",
+ "\n",
+ "To install the library:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "id": "install-python",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "%pip install -q validmind"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "install-initialize",
+ "metadata": {},
+ "source": [
+ "## Initialize the ValidMind Library\n",
+ "\n",
+ "ValidMind generates a unique _code snippet_ for each registered model to connect with your developer environment. You initialize the ValidMind Library with this code snippet, which ensures that your documentation and tests are uploaded to the correct model when you run the notebook."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "install-snippet",
+ "metadata": {},
+ "source": [
+ "### Get your code snippet\n",
+ "\n",
+ "1. In a browser, [log in to ValidMind](https://docs.validmind.ai/guide/configuration/log-in-to-validmind.html).\n",
+ "\n",
+ "2. In the left sidebar, navigate to **Model Inventory** and click **+ Register Model**.\n",
+ "\n",
+ "3. Enter the model details and click **Continue**. ([Need more help?](https://docs.validmind.ai/guide/model-inventory/register-models-in-inventory.html))\n",
+ "\n",
+ " For example, to register a model for use with this notebook, select:"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "install-variables",
+ "metadata": {},
+ "source": [
+ " - Documentation template: `{template}`\n",
+ " - Use case: `{use-case}`"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "install-credentials",
+ "metadata": {},
+ "source": [
+ " You can fill in other options according to your preference.\n",
+ " \n",
+ "4. Go to **Getting Started** and click **Copy snippet to clipboard**.\n",
+ "\n",
+ "Next, [load your model identifier credentials from an `.env` file](https://docs.validmind.ai/developer/model-documentation/store-credentials-in-env-file.html) or replace the placeholder with your own code snippet:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "id": "install-init",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Load your model identifier credentials from an `.env` file\n",
+ "\n",
+ "%load_ext dotenv\n",
+ "%dotenv .env\n",
+ "\n",
+ "# Or replace with your code snippet\n",
+ "\n",
+ "import validmind as vm\n",
+ "\n",
+ "vm.init(\n",
+ " # api_host=\"...\",\n",
+ " # api_key=\"...\",\n",
+ " # api_secret=\"...\",\n",
+ " # model=\"...\",\n",
+ ")"
+ ]
+ }
+ ],
+ "metadata": {
+ "language_info": {
+ "name": "python"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/notebooks/templates/next-steps.ipynb b/notebooks/templates/next-steps.ipynb
new file mode 100644
index 000000000..655176ef5
--- /dev/null
+++ b/notebooks/templates/next-steps.ipynb
@@ -0,0 +1,50 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "next-steps",
+ "metadata": {},
+ "source": [
+ "## Next steps\n",
+ "\n",
+ "You can look at the output produced by the ValidMind Library right in the notebook where you ran the code, as you would expect. But there is a better way: use the ValidMind Platform to work with your model documentation."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "next-docs",
+ "metadata": {},
+ "source": [
+ "### Work with your model documentation\n",
+ "\n",
+ "1. From the **Model Inventory** in the ValidMind Platform, go to the model you registered earlier. ([Need more help?](https://docs.validmind.ai/guide/model-inventory/working-with-model-inventory.html))\n",
+ "\n",
+ "2. In the left sidebar that appears for your model, click **Documentation**.\n",
+ "\n",
+ "What you see is the full draft of your model documentation in a more easily consumable version. From here, you can make qualitative edits to model documentation, view guidelines, collaborate with validators, and submit your model documentation for approval when it's ready. [Learn more ...](https://docs.validmind.ai/guide/working-with-model-documentation.html)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "next-resources",
+ "metadata": {},
+ "source": [
+ "### Discover more learning resources\n",
+ "\n",
+ "We offer many interactive notebooks to help you document models:\n",
+ "\n",
+ "- [Run tests & test suites](https://docs.validmind.ai/guide/testing-overview.html)\n",
+ "- [Code samples](https://docs.validmind.ai/guide/samples-jupyter-notebooks.html)\n",
+ "\n",
+ "Or, visit our [documentation](https://docs.validmind.ai/) to learn more about ValidMind."
+ ]
+ }
+ ],
+ "metadata": {
+ "language_info": {
+ "name": "python"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/notebooks/templates/upgrade-validmind.ipynb b/notebooks/templates/upgrade-validmind.ipynb
new file mode 100644
index 000000000..850282777
--- /dev/null
+++ b/notebooks/templates/upgrade-validmind.ipynb
@@ -0,0 +1,57 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "upgrade-vm",
+ "metadata": {},
+ "source": [
+ "## Upgrade ValidMind\n",
+ "\n",
+ "After installing ValidMind, you’ll want to periodically make sure you are on the latest version to access any new features and other enhancements.
\n",
+ "\n",
+ "Retrieve the information for the currently installed version of ValidMind:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "id": "upgrade-show",
+ "execution_count": null,
+ "metadata": {
+ "vscode": {
+ "languageId": "plaintext"
+ }
+ },
+ "outputs": [],
+ "source": [
+ "%pip show validmind"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "upgrade-version",
+ "metadata": {},
+ "source": [
+ "If the version returned is lower than the version indicated in our [production open-source code](https://github.com/validmind/validmind-library/blob/prod/validmind/__version__.py), restart your notebook and run:\n",
+ "\n",
+ "```bash\n",
+ "%pip install --upgrade validmind\n",
+ "```"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "upgrade-restart",
+ "metadata": {},
+ "source": [
+ "You may need to restart your kernel after running the upgrade package for changes to be applied."
+ ]
+ }
+ ],
+ "metadata": {
+ "language_info": {
+ "name": "python"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/pyproject.toml b/pyproject.toml
index 04c8d449e..2eb972312 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -10,7 +10,7 @@ description = "ValidMind Library"
license = "Commercial License"
name = "validmind"
readme = "README.pypi.md"
-version = "2.7.2"
+version = "2.7.3"
[tool.poetry.dependencies]
aiohttp = {extras = ["speedups"], version = "*"}
diff --git a/validmind/__version__.py b/validmind/__version__.py
index 7f9085047..573a7705c 100644
--- a/validmind/__version__.py
+++ b/validmind/__version__.py
@@ -1 +1 @@
-__version__ = "2.7.2"
+__version__ = "2.7.3"