# Adding True/False and list value widgets to your Databricks notebook

**Date:** 2019-08-31  
**Author:** Kees C. Bakker  
**Categories:** Databricks / Spark, Python  
**Original:** https://keestalkstech.com/adding-true-false-and-list-widgets-to-your-databricks-notebook/

![Adding True/False and list value widgets to your Databricks notebook](https://keestalkstech.com/wp-content/uploads/2019/08/Databricks_add_widgets_to_your_notebook.jpg)

---

As an engineer, I love to add parameters to my applications. That's why I love the *widget*-feature of Databricks notebooks. It allows me to do parameterization with a nice UI.

![Screenshot of a Databricks notebook with 5 widgets. By default, they stick on top of the notebook.](https://keestalkstech.com/wp-content/uploads/2019/08/2019-08-30_0811.png)
*A Databricks notebook with 5 widgets. By default, they stick on top of the notebook.*

You can add widgets to a notebook by specifying them in the first cells of the notebook. There are [four flavors](https://docs.databricks.com/user-guide/notebooks/widgets.html#widget-types): text, dropdown, combobox, and multiselect. *It is even possible to [specify widgets in SQL](https://docs.databricks.com/user-guide/notebooks/widgets.html#widgets-in-sql), but I'll be using Python today.*

I use them to influence the settings of my notebook, so I can easily change them and run the notebook again. I also love the fact that I can specify a default value for a widget.

## Adding a True/False widget

Unfortunately, there is no checkbox widget in Databricks. We'll be using a dropdown with the values `True` and `False`:

```py
dbutils.widgets.dropdown("skip_send_to_bucket", "False", 
                         ["True", "False"], "Skip send to bucket")

dbutils.widgets.dropdown("force_reclassification", "False",
                         ["True", "False"], "Force Reclassification")
```

This will render the following UI:

![Two Databricks dropdown widgets that show True/False options. The widgets are ordered alphabetically.](https://keestalkstech.com/wp-content/uploads/2019/08/2019-08-30_0558.png)
*The widgets are in alphabetical order.*

Let's say these values are optional. The UI will always provide the values, but when other notebooks are calling this notebook, they might not care to specify all arguments. First, we'll create a function that will read the value or provide a default:

```py
def get_argument_value_or_default(name, default):
  value = getArgument(name)
  if len(value) < 1:
    return default
  return value
```

Next, we must convert the value into a Boolean. Did you know that `bool("False")` or `bool("0")` will return `True`? *This is because the [string is not empty](https://docs.python.org/3/library/stdtypes.html#truth).* We'll create a function to parse to a string value to a Boolean value:

```py
def str_to_bool(value):
  FALSE_VALUES = ['false', 'no', '0']
  TRUE_VALUES = ['true', 'yes', '1']
  lvalue = str(value).lower()
  if lvalue in (FALSE_VALUES): return False
  if lvalue in (TRUE_VALUES):  return True
  raise Exception("String value should be one of {}, but got '{}'.".format(FALSE_VALUES + TRUE_VALUES, value))
```

*For our example we could just check on `'True'` and `'False'`, but I like my functions to give me more options.* Now let's parse the widget values into variables:

```py
force_reclassification = str_to_bool(get_argument_value_or_default("force_reclassification", False))
skip_send_to_bucket = str_to_bool(get_argument_value_or_default("skip_send_to_bucket", False))
```

## What about required values?

When a value is required, you should terminate notebook execution if the value is not provided. Let's create a function that aides us in doing so:

```py
def validate_required_argument_and_return_value(name):
  value = getArgument(name)
  if len(value) < 1:
    dbutils.notebook.exit("'{}' argument value is required.".format(name))
  return value
```

This will cause the notebook to exit with the following message:

```txt
Notebook exited: 'delivery_time_codes_to_skip' argument value is required.
```

## Separated list widget?

I like to specify lists in the form of a comma-separated list of values. I'll be using a *text widget* for these types of values:

```py
dbutils.widgets.text("mcc1_codes_to_reclassify", "F9, G4, J9, W2, G9, M7", "MCC1 for Reclassification")
```

This renders:

![Databricks text field widget with a comma separated list of strings.](https://keestalkstech.com/wp-content/uploads/2019/08/2019-08-30_0659.png)
*The rendered text field is small for a list.*

Let's create a helper functions for parsing the string into a list:

```py
def split_into_string_list(value):
  lst = re.split(';|,|\\[|\\]|"|\'', value)
  lst = map(lambda x: x.strip(), lst)
  lst = filter(lambda x: len(x) > 0, lst)
  return list(lst)
```

We're splitting on everything in the book: commas, semi-colons, pipes. This split parses weird values like `"[\"my\", 1, ' ', 'weird-list',]"` into ` ['my', '1', 'weird-list'] `. It will skip empty values en remove spaces from values. *You might not want or need such an opinionated split.*

Let's combine the `plit_into_string_list` with the `validate_required_argument_and_return_value`:

```py
def validate_required_argument_and_return_list_value(name):
  value = validate_required_argument_and_return_value(name)
  value = split_into_string_list(value)
  if len(value) == 0:
        dbutils.notebook.exit("'{}' list argument has no items.".format(name))
  return value
```

Let's call it:

```py
mcc1_codes_to_reclassify = validate_required_argument_and_return_list_value("mcc1_codes_to_reclassify")
```

## Running a parametrised notebook

Running a notebook from another notebook is easy:

```py
dbutils.notebook.run(
    'Image Classification Pipeline', # name
    60 * 10, # timeout in minutes
    # parameters:
    { 'mcc1_codes_to_reclassify': 'KLM, CKB, W0T',
      'skip_send_to_bucket': 'False',
      'force_reclassification': 'True' })
```

Or use `%run`:

```py
%run /path/to/notebook $mcc1_codes_to_reclassify="KLM, CKB, W0T" $skip_send_to_bucket="False" $force_reclassification="True"
```

## Clearing widgets

If you need to clear the widgets of a notebook, you can use this:

```
dbutils.widgets.removeAll()
```

## Conclusion

That's it. It is easy to add a True/False widget to your notebook, using a dropdown. One big advantage that you don't have to use True or False as a caption, but you can give a more descriptive caption and still use a Boolean value in your notebook.
The list value widgets are harder but will give the end-user great control over feeding a list into your notebook.

## Changelog

2021-10-21 Added the [Clearing widgets sections](#clearing-widgets).
2019-08-31 Initial article.
