We are currently experiencing an issue with Email verification at this time and working towards a solution. Should you encounter this issue, please click on the "Send Verification Button" a second time and the request should go through. If the issue still persists for you, please email support@alteryx.com for assistance.

Alteryx Designer Knowledge Base

Definitive answers from Designer experts.

Getting Started with SnakePlane and SnakePlane Pilot: A Tutorial

SydneyF
Alteryx Alumni (Retired)
Created
XMSG("Radar Plot")


XMSG("Title Field")



XMSG("Fields to Plot")



  • Now that the interface and configuration files are set up, we can start creating the tool's logic in the Python script main.py (src > radarPlot > engine > src)!


    1. First, add code to import the additional required libraries for our tool. Our tool will requirematplotlib, as well as the pi function from the math package, and re (for regex functionality).

      # 3rd Party Libraries import AlteryxPythonSDK as sdk  from snakeplane.plugin_factory import PluginFactory  # Our added libraries import matplotlib.pyplot as plt from math import pi import re
    2. To make sure these packages end up in our final tool, we should add them to the SnakePlane Pilot virtual environment.If you are using Pycharm, the easiest way to do this is to navigate to File > Settings > Projectand click the little plus button on the right-hand side to add a package. We will only need to add matplotlib.

      2019-03-15_16-17-15.png

      When you build your tool, these packages will be included in the tool’s virtual environment, so it is important to keep tabs on what you add, and what really needs to be packaged with your tool.

    3. Back in the Python code (main.py) we need to modify the plugin factory constructor to reference the name of our new tool. In the line of code that reads PluginFactory("ExampleStreamTool"), replace ExampleStreamTool with radarPlot.

      # Initialization of the plug in factory, used for making the AyxPlugin class factory = PluginFactory("radarPlot")

      Note: it is important that the name you provide the plugin factory constructor matches the directory name of the tool exactly. This is because the plugin factory uses this provided name to locate the configuration (XML)file for the plugin. If this argument is not set correctly, you will not be able to use your tool in Alteryx.

    4. Next, we encounter our first decorator, initialize plugin!This is where we will specify the specific plugin initialization behavior.

      1. Delete all of the code in the example tool between the comment """Initialize the example tool""" and return True.

        2019-03-18_8-10-17.png

      2. In this section, we are going to add code that returns the configuration options set by the user in Alteryx to the Python script.In our GUI, there are two configuration options; the fields to be plotted on the radar chart (the listbox widget) and the field that contains the titles of the plots (a drop down).

        Using the input_mgr.workflow_config()SnakePlane function, we can call the tool's configuration in a workflow by referencing the dataName we gave to the interface widgets in the Gui file (our listbox is named "fields" and our title drop-down widget is named "names").

        confignames.png

        We will save these configuration inputs as user_data.fields and user_data.names, respectively. Saving the input configurations inuser_data allows the information to be accessed later in the script.

            # Get the selected value from the GUI and save it for later use in the user_data     user_data.fields = (input_mgr.workflow_config["fields"])     user_data.names = (input_mgr.workflow_config["names"])
      3. Next, we can add code to return error messages at initialization if the user does not configure the tool. We want to start by setting the variable initSuccess to True by default, and then write two if statements that check if the user_data variables are equal to None. If they are, we use the logger functionality to display an error message, and set the initSucess to False.

            initSuccess = True      if user_data.fields is None:         logger.display_error_msg("Select Fields to Plot")         initSuccess = False      if user_data.names is None:         logger.display_error_msg("Select the Field that Contains the Plot Labels")         initSuccess = False
      4. At the end of the factory.initialize_plugin, we want to return the variable initSuccess. If the interface has been configured correctly, initiSuccess will be equal to True, and we will be able to run the tool and move on to the next section of code. If initSuccess is False, the user will see an error message in Alteryx instructing them to fix their configuration.

           return initSuccess
    5. The next decorator,@factory.process_datais (intuitively) for processing data. This section is where the bulk of your custom tool code will go.

      1. The first thing to note about the factory.process_data() decorator are the two arguments mode and input_type.

        1. Mode allows us to specify which mode we want the plugin to operate in. There are two possible modes; batch and stream. Batch mode brings in all of the input records all at once, which is handy if you are building a tool that needs to see all records simultaneously (like a predictive tool). Stream mode brings in the input records a single row at a time.

        2. Input_type specifies the format of the input data. The two options are list (this is the default) and dataframe. List brings in data as a single list in stream mode or a list of lists in batch mode. Dataframe brings in the input as a pandas dataframe.

      2. For this tool, we will set the mode to stream and the input_type to dataframe.

        @factory.process_data(mode="stream", input_type="dataframe")
      3. We will leave the next few lines of code in the example tool as is. input_mgr
No ratings
Comments
cam_w
11 - Bolide

Suggestion - Part 1 step 3.3 requires access to pip domains (e.g. pythonhosted.org). If you work for a company that uses a proxy, make sure your proxy has these domains available before starting the "env\setup_environ.bat" script.

cam_w
11 - Bolide

Another tip - In Part 3, "Debugging your Tool" step 1, make sure you set the fields you want to plot to numeric data types (Int works nicely). I thought my copy/paste skills were failing until I tried ploting the name field and saw it was faliing to proces the string data type. All I had to do was change the data types for the numeric fields in the Select tool, and voila!

cam_w
11 - Bolide

@SydneyF - I finished up the tutorial yesterday, and it worked nicely! Thank you for the demo! 🙂

 

Couple questions if that's okay ...

 

  1. Does the abstraction measurably change performance of the resulting tools? My knowledge of python decorators is very basic at the moment. I'm hoping the answer is no considering, but wasn't sure if you and others had tested this already.
  2. You mention that we can package multiple tools in one YXI file, which I was already aware of and planning to make use of the grouping of tools with the same virtual environment feature released in 2019.1. Do we just 'invoke build <tool_#1>' all of the tools into the 'package' directory and then 'invoke package <tool_collection>' at the end? My reading of the tasks.py shows me that would work if all the tools are built into that directory, but just wanted to confirm that was the correct process for multiple tools.
  3. Will Alteryx be bringing SnakePlane to Inspire? Or do I have to bring my own snakes? 🙂 But seriously, is there a forum for hacking SDK somewhere during Inspire? I do see @BlytheE 's SDK session, is there another?

Thanks once again!

SydneyF
Alteryx Alumni (Retired)

Hi @cam_w,

 

1. I spoke with one of the developers of SnakePlane, and he said that there are actually typically improvements in processing time for tools built with SnakePlane versus those built without.

 

2. You got it! Just build all of your tools into a shared directory, and then package that directory. The tools will all be included in the resulting .yxi. As a side note, there is some funky behavior with using multiple SDK tools on a single canvas in 2019.1. This is set to be resolved in 2019.2, and also does not occur in 2018.4.

 

3. Have you registered for BUILD2? It's on Tuesday, and people will be developing and analyzing all sorts of neat things. There is a specific SDK track, where you can compete (alone or with a team) to build an awesome Python SDK tool. The event is staffed by Alteryx Employees to provide help and answer questions - this might be exactly what you are looking for. I hope to see you there!

 

I am so glad you found the tutorial valuable! I am excited to see/hear/read about what you create with SnakePlane!

cam_w
11 - Bolide

Hey @SydneyF ,

 

That's good to hear, thank you!

 

Shoot, I think I registered for a platform training on Tuesday afternoon. I'll have to check my registration tomorrow and see what I want to/can do.

 

Thanks!

carl_steinhilber
8 - Asteroid

I've built a couple custom tools from scratch, just starting in on SnakePlane.

 

It might be obvious to others, but what's the difference between a Batch, Source and Stream tool as it pertains to the Python SDK? (ie - the @factory.process_data() modes)

SydneyF
Alteryx Alumni (Retired)

Hi @carl_steinhilber,

 

Mode allows us to specify how we want the plugin to operate in terms of bringing in data. Batch mode brings in all of the data being fed into the tool at once, which is handy if you are building a tool that needs to see all records simultaneously (like a predictive tool). Stream mode brings in the input records a single row at a time (i.e., bring in a row, do the process defined by the script, write the output to the Engine, repeat with the next row). Source mode is for when the tool doesn't expect an input stream of data at all (e.g., an input tool). 

 

You might also find the documentation on the GitHub page helpful for understanding the difference. 

 

Hope this helps!

 

Sydney

carl_steinhilber
8 - Asteroid

Perfect! Thank you Sydney, that's an excellent, clear description. I appreciate it.