Skip to main content

Python package for interfacing with DiscoveryDV using its API

Project description

This library interacts with DiscoveryDV, a data visualization suite, over a ZMQ-based API. In order to use all features of this software, DiscoveryDV must be installed and run.

License

Please see LICENSE.md for information about use, redistribution, and modification of this library.

The DiscoveryDV application (not included with this package) and the DiscoveryDV name are copyright DecisionVis LLC.

Requirements

  • PyZMQ (pyzmq>=17.0.0)
  • MessagePack (msgpack-python>=0.4.8)
  • Python >= 3.6

Usage

The DiscoveryDV Python module has 3 main components:

  1. Connection

    • This class provides an interface with DiscoveryDV.
    • It is a "Context Manager" and ideally should be used within Python's with statement.
    • If used outside of a with statement, the connection object must be connected first (connection_obj.connect()), and must be closed when finished (connection_obj.close()).
    • The connection can be re-connected with connection_obj.connect(); optionally a different TCP/IP address, and/or different ports can be passed as arguments.
    • The current application state for DiscoveryDV can be retrieved with connection_obj.state; it can be resynchronized by calling connection_obj.reload() and accessing connection_obj.state again.
  2. State

    • This class represents a DiscoveryDV "state" object.
    • It is analogous to Python's namedtuple.
    • It contains _fields, which is a tuple of strings containing field names
    • Fields may be accessed using dot-notation (e.g. state.name) or by subscripting (e.g. state['name']).
    • Values may be State objects, Collection objects, or Python values (int, float, bool, str)
    • Fields may be set using = (e.g. state.name = "New Name", state['name'] = "New Name").
    • Fields may be reset to defaults by deletion (e.g. del state.name, del state['name']).
    • Printing this object will provide an API path and a list of valid fields.
    • This object supplies a repr that "pretty prints" the State recursively
  3. Collection

    • This class represents a DiscoveryDV "collection" object.
    • It is analogous to Python's tuple, but can also be queried by an child's name (similar to Python's dict).
    • Internally in DiscoveryDV these are referred to as OrderedLookup or NameLookup; the main difference is that a NameLookup requires children names to be unique.
    • Children are always State objects that contain a name field
    • Children may be accessed by subscripting, either using a numerical index (e.g. 0, -1) or a string name (e.g. 'Page 001).
    • Children may be added by calling collection_obj.insert(index) or collection_obj.add(); an optional name argument may be supplied to create a child with a specified name.
    • Children may be deleted by calling collection_obj.delete(index/name) or del collection_obj[index/name].
    • Printing this object will provide an API path and a list of children's names.
    • This object supplies a repr that "pretty prints" the Collection recursively

Example

Making a Connection

You will first need to make a connection to DiscoveryDV. It is best to use the Connection class in a with statement:

with Connection('127.0.0.1', 33929, 33930) as ddv:
    # Commands applied to the "ddv" connection object
    ...

Python's with clause will create the connection, connect it to DiscoveryDV, and properly close the connection outside the scope of the with clause, and in the event of an exception.

Alternately, an instance of a Connection can be created, but must be connected before performing actions, and closed afterward:

ddv = Connection('127.0.0.1', 33929, 33930)
ddv.connect()
# Commands applied to the "ddv" connection object
...
ddv.close()

You may wish to include the ddv.close() command in a finally clause to ensure that the connection is properly closed in the event of an exception.

Working with the DiscoveryDV application state

Once connected, the application state can be retrieved as a State object.
This object is an abstraction of the API commands that can be performed in DiscoveryDV.

For example, the following DVS script creates a page, adds a file, creates a PCPlot, and sets up some axes:

add /page/ "LTM"
add /page/LTM/file/ "LTM"
set /page/LTM/file/LTM/path/ "ltm.xlsx"
set /page/LTM/file/LTM/type/ excel
add /page/LTM/pcplot/ "PCPlot"
add /page/LTM/pcplot/PCPlot/parallel/ "Cost" "Error" "Risk" "Mass"
set /page/LTM/pcplot/PCPlot/axis/c/name/ "Cost"

We can replicate this script with the DiscoveryDV Python module:

with Connection('127.0.0.1', 33929, 33930) as ddv:
    ddv.state.page.add("LTM")
    ddv.state.page["LTM"].file.add("LTM")
    ddv.state.page["LTM"].file["LTM"].path = "ltm.xlsx"
    ddv.state.page["LTM"].file["LTM"].type = "excel"
    ddv.state.page["LTM"].pcplot.add("PCPlot")
    ddv.state.page["LTM"].pcplot["PCPlot"].parallel.add("Cost")
    ddv.state.page["LTM"].pcplot["PCPlot"].parallel.add("Error")
    ddv.state.page["LTM"].pcplot["PCPlot"].parallel.add("Risk")
    ddv.state.page["LTM"].pcplot["PCPlot"].parallel.add("Mass")
    ddv.state.page["LTM"].pcplot["PCPlot"].axis.c.name = "Cost"

We could write this is a more Pythonic approach:

with Connection('127.0.0.1', 33929, 33930) as ddv:
    state = ddv.state
    page = state.page.add("LTM")
    file = page.file.add("LTM")
    file.path = "ltm.xlsx"
    file.type = "excel"
    pcplot = page.pcplot.add("PCPlot")
    for name in ("Cost", "Error", "Risk", "Mass"):
        _ = pcplot.parallel.add(name)
    pcplot.axis.c.name = "Cost"

Performing "actions"

The DiscoveryDV API has several commands that do not modify the state. These "actions" can also be performed using this module.

You can see a list of commands you can run by querying the connection object's commands: print(connection_obj.commands).

Try running print(connection_obj.help("verb") to see information from DiscoveryDV on a particular command. Actions for the Connection object take the same arguments as API commands in DiscoveryDV.

You can also perform state modification commands directly using the connection object. For these commands, you will need to provide a full path. Paths in this module are specified using Python tuples rather than "/"-separated as they are in the DiscoveryDV API. For example, /page/0/name/ would be ('page', 0, 'name').

Troubleshooting

It is often useful to print the Connection object and any relevant State/Collection objects, or for more detailed information, print their repr (e.g. print(repr(connection_obj.state))).

  • ValueError with no response from DiscoveryDV:

    • Ensure that DiscoveryDV is running
    • Ensure that the module's Connection object has been connected if not using a with statement
      1. connection_instance.connect()
    • Check that the Connection object's address and ports match DiscoveryDV
      1. print(connection_instance)
      2. Compare address and ports to the log message when starting DiscoveryDV
      3. Reconnect and specify address and ports connection_instance.connect('127.0.0.1', 33929, 33930)
  • KeyError or IndexError when performing state changes

    • Confirm that the name or index are correct
      • print(collection_obj) and compare names/positions
      • print(state_obj) and compare field names
    • Ensure that the module's State object is synchronized with DiscoveryDV
      1. connection_instance.reload()
      2. state_obj = connection_instance.state
  • ValueError when trying to set a State field

    • DiscoveryDV only allows certain types/ranges of values based on a path
    • It may be useful to print the output from obj.help() (for State or Collection), or call Connection's help method using a full path (e.g. connection_obj.help(path)).

Release Notes

Version 0.1 - (August 9, 2019):

  • Initial release.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

DiscoveryDV-0.3.tar.gz (10.5 kB view hashes)

Uploaded Source

Built Distribution

DiscoveryDV-0.3-py3-none-any.whl (11.2 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page