Email Notification Add-on Installer
⚠️ Only Seeq Administrators can run this installer to completion, since only Administrators can install Add-ons.
If you are using Seeq’s SaaS product, instead of this Data Lab-based notification mechanism, it is recommended that you utilize the built in notification capabilities in Seeq R60+ as described in the following Seeq Knowledge Base article: https://telemetry.seeq.com/support-link/kb/latest/cloud/notifications-on-conditions
This notebook will walk you through the steps needed to install the Email Notification Scheduler as a Data Lab Tool in Workbench. If you are fine with the defaults and have never installed the scheduler before, you should be able to leave everything as is, running all cells in order.
At the end, if you have encountered no errors: * in the folder you’ve
specified using the path_to_notifications_folder
, you should find
all files listed as source_files
below * the Tools tab in Workbench
should have a tool grouping named Add-ons
* there should be a tool
named Email Notification Scheduler
among the Add-ons
.
There is ONE MORE STEP that must be done to complete installation -
after running all steps in this installer, one must complete the SMTP
server and account configuration in Email Notifier.ipynb
within the
target folder (Email Notifications
if
path_to_notifications_folder
is not changed below). Please note that
anyone that has access to this project will be able to see the account
information provided there. If using the gmail SMTP server, it is
preferred to use an app password rather than the actual password for the
account, and the port should be set to 587 to use STARTTLS. You can find
out more about gmail app passwords in the Google Account
Help.
See the Add-on Tools KB article for further details of Add-on tools.
Install Requirements
Some of the examples in the Email Notification Scheduler and Email Unsubscriber notebooks use the ipyvuetify library. We make sure it is installed in the below cell.
pip install ipyvuetify
Installation Folder
The path to the Notifications folder is set in the next cell. It should be specified relative to the root of the project and should use forward slashes ( / ) for path separators. The folder should be created before proceeding with installation.
path_to_notifications_folder = 'Email Notifications'
How to handle existing files
If the following parameter is changed to True
, any existing files in
the target folder will be overwritten. You may want to do this if you
wish to discard changes to the installed notebooks or if you wish to
upgrade the notebooks with the versions found in this folder (e.g.,
after upgrading the Data Lab server).
overwrite_existing_files = False
How to handle existing versions of Scheduler in Add-on Tools
If the following parameter is True
, any already-installed tools with
the same name as shown in the name
field of the
tool_with_permissions
dictionary below will be removed before the
new tool is installed. By default, the name
of the scheduler is
Email Notification Scheduler
. Be careful! If you change this
parameter to True
, you will be replacing the existing version of the
Add-on Tool with the version found at the
path_to_notifications_folder
in this project for all users of the
Add-on Tool. You may want to change the name
field in the
tool_with_permissions
dictionary instead.
remove_existing_versions = False
Tool Configuration
Check the output of the following cell to confirm the desired configuration for the Add-on Tool. The resulting JSON object will be used to create or update the existing tool.
import urllib.parse as urlparse
target_path_encoded = urlparse.quote(path_to_notifications_folder)
project_id = spy.utils.get_data_lab_project_id()
project_url = spy.utils.get_data_lab_project_url(use_private_url=False)
notebook_name = 'Email Notification Scheduler.ipynb'
query_parameters = '?workbookId={workbookId}&worksheetId={worksheetId}&workstepId={workstepId}&seeqVersion={seeqVersion}'
install_url = f'{project_url}/addon/{path_to_notifications_folder}/{notebook_name}/{query_parameters}'
tool_with_permissions = {
'name': 'Email Notification Scheduler',
'description': 'Data Lab Notebook-based Email Notification Scheduling tool',
'iconClass': 'fa fa-envelope',
'targetUrl': install_url,
'linkType': 'window',
'windowDetails': 'toolbar=0,location=0,scrollbars=1,statusbar=0,menubar=0,resizable=1,height=700,width=600',
'sortKey' : 'e',
'reuseWindow': 'false', # but not relevant, since linkType is 'tab'
'permissions': {
'groups': [],
'users': [spy.user.email]
}
}
print('The following parameters will be used to define the add-on:\n')
tool_with_permissions
⚠️ Advanced Configuration and Automated Installation Beyond This Point
If you are just running this notebook to install or update the Email Notifications Scheduler in a typical fashion, you can just run the remaining cells as is, checking the output of each to confirm the expected results. Contact support if any problems are encountered.
import os
import requests
import shutil
from datetime import datetime, timezone
from pathlib import Path
from seeq import sdk
try:
spy_version = seeq.__version__
except:
spy_version = spy.__version__
print(f'Seeq PyPI package version: {spy_version}')
Check whether the required source files and target folder exist
The source files should be in the same folder as this installer. The target folder for the installation should already exist by the time this installer is run.
home_path = os.environ['HOME']
all_required_paths_exist = False
source_files = [
'Email Notification Scheduler.ipynb',
'Email Notifier.ipynb',
'Email Unsubscriber.ipynb',
'Seeq Data Lab.jpg'
]
source_paths = [
f'{os.getcwd()}/{source_file}' for source_file in source_files
]
target_folder_path = Path(home_path, path_to_notifications_folder)
os.makedirs(target_folder_path, exist_ok=True)
target_folder_exists = os.path.exists(target_folder_path)
all_source_paths_exist = all(iter([os.path.exists(source_path) for source_path in source_paths]))
status_message = ''
if not all_source_paths_exist:
files_string = "\n".join(source_paths)
status_message += f'Not all source files exist. Check for the presence of the following files ' \
f'in the folder that contains this notebook:\n{source_files}'
if not target_folder_exists:
status_message += f'Target folder not found. Add a folder at {path_to_notifications_folder} relative to ' \
f'the root of the Data Lab Project'
if status_message:
print(status_message)
else:
print('All required paths exist. Installation may proceed.')
target_paths = []
if all_source_paths_exist:
existing_files_not_overwritten = False
for source_path in source_paths:
source_file = source_path.split('/').pop()
target_path = Path(home_path, path_to_notifications_folder, source_file)
target_paths.append(target_path)
if overwrite_existing_files or not target_path.exists():
shutil.copyfile(source_path, target_path)
else:
existing_files_not_overwritten = True
if existing_files_not_overwritten:
print(f'Warning! One or more files were not overwritten. Change overwrite_existing_files to True '
f'or delete the files in the target folder to ensure the latest versions.')
all_target_files_exist = all(iter([os.path.exists(target_path) for target_path in target_paths]))
print(f'{"All" if all_target_files_exist else "Not all"} target files exist. '
f'Installation may{" " if all_target_files_exist else " not "}proceed.')
else:
all_target_files_exist = False
print('Please check results of previous step')
Configuration update and tool installation
The following cell enables the Add-on Tools and ScheduledNotebooks features and adds the Email Notifications Scheduler to the Add-on Tools.
# Adapted from the Notebook Add-on Tool Management UI-TEST.ipynb, available at
# https://seeq.atlassian.net/wiki/spaces/SQ/pages/961675391/Add-on+Tools
def create_add_on_tool(tool_with_permissions):
# Create add-on tool
tool = tool_with_permissions.copy()
tool.pop("permissions")
tool_id = sdk.SystemApi(spy.client).create_add_on_tool(body = tool).id
items_api = sdk.ItemsApi(spy.client)
# assign group permissions to add-on tool and data lab project
groups = tool_with_permissions["permissions"]["groups"]
for group_name in groups:
group = sdk.UserGroupsApi(spy.client).get_user_groups(name_search=group_name)
if group:
ace_input = { 'identityId': group.items[0].id, 'permissions': { 'read': True } }
# Add permissions to add-on tool item
items_api.add_access_control_entry(id=tool_id, body=ace_input)
# Add permissions to data lab project if target URL references one
ace_input['permissions']['write'] = True # Data lab project also needs write permission
items_api.add_access_control_entry(id=project_id, body=ace_input)
# assign user permissions to add-on tool and data lab project
users = tool_with_permissions["permissions"]["users"]
for user_name in users:
user = sdk.UsersApi(spy.client).get_users(username_search=user_name)
if user:
ace_input = { 'identityId': user.users[0].id, 'permissions': { 'read': True } }
items_api.add_access_control_entry(id=tool_id, body=ace_input)
# Add permissions to data lab project if target URL references one
ace_input['permissions']['write'] = True # Data lab project also needs write permission
items_api.add_access_control_entry(id=project_id, body=ace_input)
system_api = sdk.SystemApi(spy.client)
if all_target_files_exist:
if not spy.user.is_admin:
raise RuntimeError('Only Administrators can install Add-on Tools')
if int(spy_version.split('.')[0]) >= 54:
configuration_output = system_api.get_configuration_options(limit=5000)
else:
configuration_output = system_api.get_configuration_options()
add_on_tools_already_enabled = next((option.value for option in configuration_output.configuration_options
if option.path == 'Features/AddOnTools/Enabled'), False)
scheduled_notebooks_already_enabled = next((option.value for option in configuration_output.configuration_options
if option.path == 'Features/DataLab/ScheduledNotebooks/Enabled'), False)
configuration_options_update = []
if not add_on_tools_already_enabled:
configuration_options_update.append(
sdk.ConfigurationOptionInputV1(
note = f'Set to true by Email Notifications Installer user {spy.user.email} {datetime.now(timezone.utc)}',
path = 'Features/AddOnTools/Enabled',
value = True
)
)
if not scheduled_notebooks_already_enabled:
configuration_options_update.append(
sdk.ConfigurationOptionInputV1(
note = f'Set to true by Email Notifications Installer user {spy.user.email} {datetime.now(timezone.utc)}',
path = 'Features/DataLab/ScheduledNotebooks/Enabled',
value = True
)
)
if configuration_options_update:
config_options = sdk.ConfigurationInputV1(configuration_options = configuration_options_update)
system_api.set_configuration_options(body=config_options)
existing_tools_output = system_api.get_add_on_tools()
existing_tools = [add_on_tool for add_on_tool in existing_tools_output.add_on_tools
if add_on_tool.name == tool_with_permissions['name']]
if len(existing_tools) > 0:
if not remove_existing_versions:
raise RuntimeError(f'One or more tools exist with name {tool_with_permissions["name"]}, '
f'and remove_existing_versions is False; Cannot create add-on tool')
else:
# Delete existing tools
for existing_tool in existing_tools:
system_api.delete_add_on_tool(id=existing_tool.id)
print(f'Removed {len(existing_tools)} existing tools with name {tool_with_permissions["name"]}')
# Create new tool
create_add_on_tool(tool_with_permissions)
print(f'Success! Check Workbench for the {tool_with_permissions["name"]} tool in the Add-on Tools collection')
else:
print('Not all target files exist; cannot complete installation.')