from seeq import spy

# Set the compatibility option so that you maximize the chance that SPy will remain compatible with your notebook/script
spy.options.compatibility = 193
# Log into the Seeq Server if you're not using Seeq Data Lab:
spy.login(url='http://localhost:34216', credentials_file='../credentials.key', force=False)

spy.widgets

A set of ipython widgets designed specifically for working with Seeq.

These widgets can be used on their own or incorporated into an ipywidgets UI.

IPyWidgets are not installed with core SPy. You may need to uncomment the cell below to install the ‘widgets’ extras of SPy.

# pip install seeq-spy[widgets]

SeeqItemSelect

The Seeq Item Selector is a configurable item selector. Creating a basic item selector that allows searching for seeq items by name and type can be created with no arguments.

item_selector1 = spy.widgets.SeeqItemSelect()
display(item_selector1)

Once a search has been performed, an item may be selected in the results window and information on that item is available through the selected_value attribute. Perform a search in the above selector and select an item before running the next cell.

item_selector1.selected_value

There are a number of options available which can be found in the widget’s documentation. In this example, the widget will be shown with: - search fields of name, type, a datasource dropdown and a selector to include archived items - type options limited to ‘Signal’, ‘Condition’, and ‘Scalar’ - a default type of ’Condition - a collapsible help window - a results window 15 rows long - a maximum of 200 results displayed - the ability to select multiple items

item_selector2 = spy.widgets.SeeqItemSelect(
    show_fields=['Name', 'Type', 'Datasource Dropdown', 'Archived'],
    type_options=['Signal', 'Condition', 'Scalar'],
    item_type='Condition',
    show_help=True,
    results_box_rows=15,
    max_displayed_results=200,
    mulit_selct=True
)
display(item_selector2)

Logging Widget and WidgetLogHandler

This tutorial shows how to use the spy.widgets.LogWindowWidget with the spy.widgets.WidgetLogHandler. Keep in mind that the WidgetLogHandler can be used with any ipywidget that has a value property, so you are not required to use the LogWindowWidget to display your logs.

import logging

Setting up the widget and handler

First, create the logging widget

log_widget = spy.widgets.LogWindowWidget('<b>Log Output</b>')

Then, create a log handler and configure it’s behavior

widget_log_handler = spy.widgets.WidgetLogHandler()
widget_log_handler.set_widget(log_widget.message_window)
widget_log_handler.setLevel(log_widget.log_level)
formatter = logging.Formatter('[%(levelname)s] %(asctime)s - %(message)s')
widget_log_handler.setFormatter(formatter)
widget_log_handler.concat='prepend'

To make the widget_log_handler handling level change when the widget level changes, we need to register the handler with the logging widget.

log_widget.handlers.append(widget_log_handler)

We’ll display the widget here.

log_widget

Finally, get the logger that you want to use and set it’s log level and register the WidgetLogHandler as one of its handlers. Remember Python loggers have a variety of ways that levels are set, but generally you set a low level for the logger, then higher levels for your handlers.

I’m going to use the root logger. This likely isn’t what you want as it will also handle jupyter logs. If you get a higher level logger, remember that it will inherit it’s log level from the root logger (or any logger below it), so if you are using multiple loggers, it’s good practice to set the root logger to NOTSET or DEBUG since the default is WARNING. Also, if you register the handler with multiple loggers that see the same message (loggers have inheritance!) you’ll see your message multiple times in the window.

logger = logging.getLogger()
logger.setLevel(logging.NOTSET)
# add the handler
logger.addHandler(widget_log_handler)
# log some messages!
# You can change the widget log level and see how it's behaviour changes when you re-run this cell.
logger.info('An info message')
logger.warning('A warning!')
logger.error('Uh oh...an ERROR!!!')