Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Panel

Table of Contents
maxLevel3

Introduction

To demonstrate the process of Extension development, a sample Extension will be created and deployed using Visual Studio Code with the UIP Visual Studio Code Extension.  The UIP Visual Studio Code Extension relies heavily on functionality provided by the uip-cli tool to enhance the UIP development experience.  Therefore, a similar experience can be achieved with other code editors using uip-cli manually.  This alternative use scenario will be documented as well.

...

Note that it is assumed the UIP Visual Studio Code Extension (or uip-cliis already installed. See the previous document for installation instructions.

Step 1 - Create a New Extension Project using the UIP VS Code Extension

As mentioned in (1.2.0) Development Environment Set-Up, this tutorial will be using Visual Studio Code running in Windows and connected to a WSL (Windows Subsystem for Linux) project environment.

...

To begin, create a project directory (for example, ~/dev/extensions/sample-task) in the WSL file system where the Universal Extension will be created.

Select project folder

Next, Use Visual Studio Code to open the sample-task folder in WSL:

...

Note that, this dialog can be used to navigate to another folder.  This is useful if you start the UIP: Initialize New Project process when VS Code is opened on a folder other than the target of initialization.

Selecting a starter template

After selecting "OK", the UIP project initialization process starts on the selected folder and you are presented with a list of available "starter templates" for the UIP project.  Starter templates contain boiler plate code to kick-start a project.  At the time of this writing, two starter templates are available: ue-task and ue-publisher.  For now, we will be working with ue-task (ue-publisher will be demoed later in the tutorial series), so go ahead and click on the ue-task template.

Setting template parameter values for selected starter template

Starter templates contain parameters that allow you to supply project specific values into boilerplate template code at creation time.

...

Expand
titleClick here to expand uip-cli details...

Step 1 supplemental - Create a New Extension Project using the CLI

Create a project directory (for example, ~/dev/extensions/sample-task) where the sample-task Extension will be created, and cd into the directory.

As of now, the CLI offers two starter Extension templates called ue-task and ue-publisher. To see all the available starter Extension templates, type the template-list command:

Both the starter Extensions above can be configured before they are initialized. 

To see the list of variables that can be used to configure one of the starter Extension templates, type the template name after the previous command.

Shown below are the list of variables for the ue-task starter template:

As shown in the image above, there are quite a few ways to configure the Extension. As for the sample Extension developed for this tutorial, we will work with ue-task, and only the owner_name option will be configured. Everything else will be set to the default value.

The Extension can be configured and initialized using the init command. There are three ways to configure the ue-task Extension template using the command line:

  • Using the -e option multiple times:

  • Using a JSON string 

  • Using a JSON/YAML file
    • Create a YAML file called vars.yml and define the variables as follows:

    • Use the YAML file to initialize the project:

Pick one of the three ways shown above; it does not matter which one. Note that an optional, positional argument can be provided at the end of each of the three commands that specifies the directory in which the Extension will be initialized to. If the directory does not exist, the CLI will create it. 

To verify that the Extension was configured as intended, open the extension.yml file (see directory structure below), and ensure the owner_name is SampleOwner.

This is the directory structure of the sample-1 Extension:

Code Block
|-- sample-task                # Sample project directory
    |--setup.py                # Setup file for packaging extension
    |--setup.cfg               # Configuration file for configuring setup
	|--__init__.py             
	|
	|--.uip                    # Folder used by CLI to validate directory
	|	|--config              # Configuration File Folder
	|		|--uip.yml         # Local Configuration File
	|
    |--src                     # Source directory for Extension implementation
        |--extension.py        # Extension implementation
        |--extension.yml       # Extension metadata
		|--__init__.py            
		|
		|--templates
			|--template.json   # Universal Template JSON Definition File


Step 2 - Deploy the Initial Extension using the UIP VS Code Extension

Before deploying the Extension, let's take a look at the code to get a sense of the expected output. Open the ~/dev/extensions/sample-task/src/extension.py in VS Code (It should already be open in the editor following the project initialization):

...

To connect to the Controller, the CLI needs the Controller's URL along with userid and password. To avoid typing the same information multiple times, the URL and userid can be stored in the local configuration file (~/dev/extensions/sample-task/.uip/config/uip.yml), and the password can be stored as an environment variable.  Alternatively, all values can be set as environment variables and, using the UIP VS Code Extension, those values can be persisted with the project and reloaded as needed. 

Set Project specific Environment Variables

Open the VS Code command pallet (ctrl+shift+p) and type "uip set".  This will show a list of UIP commands for setting environment variables:

...

Expand
titleClick here to expand uip-cli specific instructions...

Step 2 Supplemental - Deploy the Initial Extension using the CLI

To connect to the Controller, the CLI needs the Controller's URL along with userid and password. To avoid typing the same information multiple times, the URL and userid will be stored in the local configuration file, and the password will be stored as an environment variable.

  • Recall that the local configuration file is located in ~/dev/extensions/sample-task/.uip/config/uip.yml. Open the file, and enter the URL and userid information near the end of the file. Shown below is a sample snippet: 
  • Go back to the command line, and create an environment variable called UIP_PASSWORD with the password as the value.
    • If using Windows, then in CMD:  set UIP_PASSWORD=<your password>
    • If using Unix/Linux, then in the terminal: export UIP_PASSWORD=<your password>


Using the CLI, there are two primary ways to deploy the Extension: using the push command, or the build command followed by the upload command. The latter method will be shown once below, but in subsequent deployments throughout the rest of the tutorial, the push command will be used.

  • cd into the sample-task directory, if not already in there. The CLI can only execute the deployment commands if it is called from the directory containing the .uip folder. In this case, it is sample-task.
  • Issue the build command as follows: 

    The -a command will build the full package (Extension + Universal Template). Recall that the Universal Template is called UE Task, and it does not exist in the Controller. Therefore, the entire package must be built and uploaded.
  • Verify the full package was built by going to the ~/dev/extensions/sample-task/dist/package_build folder, and making sure UE_Task_universal_template.zip file exists.
  • Upload the full package as follows:

    Once again, the -a option indicates the full package needs to be uploaded.
  • Verify the UE Task Universal Template and Extension are created on the Controller side using the procedure shown above the supplemental


Step 3 - Create and launch a new 'ue-task-test' task

We are now ready to create a new task to test the initial ue-task Extension. In order to make the new UE Task task type available in the Integrations section of the Controller’s Services menu, we must first refresh the Navigation Tree.

...

Expand
titleClick here to expand uip-cli specific instructions...

Step 3 Supplemental - Create and launch a new 'ue-task-test' task

The task creation process is exactly the same as above. As for launching the task, run the command shown in the GIF animation above.

Step 4 - Modify the Extension and Deploy using the UIP VS Code Extension 

So far, we have pushed the initial Extension, created a task for it, and tested the Extension code. Now, the extension.py file will be slightly modified to demonstrate the process of deploying a modified Extension using the UIP VS Code Extension.

...

Notice that this time, the STDERR output is empty and STDOUT output is not. This is expected since we changed the value of the "Action" field in the task form.

Step 5 - Reset the Extension Changes

The For-Loop changes that prints out the 'Hello' message multiple times were added to demonstrate the process of modifying and deploying the Extension. The next few tutorials assume that the For-Loop changes aren't in extension.py, so either undo the For-Loop changes or copy the code shown below to extension.py before moving on to the next guide:

Code Block
languagepy
titleextension.py
linenumberstrue
from __future__ import (print_function)
from universal_extension import UniversalExtension
from universal_extension import ExtensionResult
from universal_extension import logger


class Extension(UniversalExtension):
    """Required class that serves as the entry point for the extension
    """

    def __init__(self):
        """Initializes an instance of the 'Extension' class
        """
        # Call the base class initializer
        super(Extension, self).__init__()

    def extension_start(self, fields):
        """Required method that serves as the starting point for work performed
        for a task instance.

        Parameters
        ----------
        fields : dict
            populated with field values from the associated task instance
            launched in the Controller

        Returns
        -------
        ExtensionResult
            once the work is done, an instance of ExtensionResult must be
            returned. See the documentation for a full list of parameters that
            can be passed to the ExtensionResult class constructor
        """

        # Get the value of the 'action' field
        action = fields.get('action', [""])[0]

        if action.lower() == 'print':
            # Print to standard output...
            print("Hello STDOUT!")
        else:
            # Log to standard error...
            logger.info('Hello STDERR!')

        # Return the result with a payload containing a Hello message...
        return ExtensionResult(
            unv_output='Hello Extension!'
        )

< Previous     Next >