4. Hello World Example

This “Hello World” example demonstrates where various components of the SDK are located and how to run a basic test. Most of this example is optional. The ContigFilter example adds more features of the SDK.

Note: if running this tutorial step-by-step then in the previous step you already declared your_kbase_username, username, and module_name as bash variables and initialized a repository named {username}HelloWorld. If not, then define these variables: your_kbase_username=jane.smith and username=${your_kbase_username}. You’ll also be using the bash variable module_name in this tutorial, but it will change depending on the different examples - first you can define it as module_name=HelloWorld.

kb-sdk init --language python --user ${your_kbase_username} ${username}${module_name}
cd ${username}${module_name}
make

The setup for the module includes:

  1. Customizing the description of the module

  2. Specify inputs, outputs, and functions of the module

  3. Validate the module and its apps

  4. Customize the Narrative User Interface

  5. Add statements to the app

  6. Run a first test

4.1. Module Description

In the root directory of the module is the file kbase.yml. Examine the file. It has a placeholder for information that you will eventually add to the module. The module-name and service-language will not change but the other items will change as you prepare the module for release or update. The default module-description doesn’t say anything about your module. You will want to edit this before the module is released. Be sure to describe what your module and its app will do. The module-version needs to be incremented before updates can be released. For the first version of an app, it can remain 0.0.1. The owners is a list of users that can approve updates to a module. The information in this file shows up in the Module Catalog entry for the module. A more complete example is kb_SPAdes.

4.2. Edit the Narrative UI (optional)

The specifications for the app’s Narrative user interface are under the directory named ui/narrative/methods/run_{username}HelloWorld. Note that the name of the directory is the same as the name of the function in the spec file above. Functions that become user-facing apps need a directory that defines the user interface.

This directory has two files spec.json and display.yaml. The example module ContigFilter will go into more depth for these files. The documenting your app page provides information on the purpose of the subdirectory img.

Now open up ui/narrative/methods/run_{username}HelloWorld/spec.json. This file is in JSON format and defines a mapping between the KBase Interface Description Language (KIDL) {username}HelloWorld.spec file and how our parameters will show up in the app’s user interface.

In the section parameters already defines parameter_1:

{
    "parameters": [
        {
            "id": "parameter_1",
            "optional": true,
            "advanced": false,
            "allow_multiple": false,
            "default_values": [ "" ],
            "field_type": "text",
            "text_options": {
                "valid_ws_types": [ ]
            }
        }
    ]
}

Additional parameters added to the spec file need to be added to this section. This will be covered in the next example module.

The behavior section describes how the parameters from the Narrative UI are passed to the Python code. For example, the Narrative UI automatically passes two hidden parameters about the narrative, the workspace and the workspace_id. When these are passed to the Python code, the workspace from the Narrative is passed as workspace_name to Python.

The display.yaml file is in YAML format and defines how your app will appear in the App Catalog . Examine the file found in ui/narrative/methods/run_{username}HelloWorld/display.yaml. View the documenting your app page for more on the how this file is used.

Finally, if you made any changes, run kb-sdk validate from the base of your app directory (e.g., {username}HelloWorld) and make sure it passes! After validation, now we can start to work on the functionality of the app.

Note

For a more exhaustive overview of the spec.json and display.yaml files, take a look at the UI specification guide . You can also experiment with UI generation with the App Spec Editor Narrative (pending narrative permissions).

4.3. Code Implementation

The actual code for your app will live in the Python package under lib/{username}HelloWorld. The entry point, where your code is initially called, lives in the file: lib/{username}HelloWorld/{username}HelloWorldImpl.py. It is sometimes called the “Implementation” file or simply the “Impl” file. This is the file where you edit your own Python code.

This “Implementation” file defines the Python methods available in the module. All of the functions defined in the spec file correspond to Python methods and they are part of the class inside {username}HelloWorldImpl.py.

Much of the Implementation file is auto-generated based on the spec file. The make command updates the Implementation file. To separate auto-generated code from developer code, developer code belongs between sets of #BEGIN and #END comments. For example:

#BEGIN_HEADER
#END_HEADER

#BEGIN_CLASS_HEADER
#END_CLASS_HEADER

#BEGIN_CONSTRUCTOR
#END_CONSTRUCTOR

#BEGIN run_jsmithHelloWorld
#END run_jsmithHelloWorld

The make command preserves everything between the #BEGIN and #END comments and replaces everything else.

Warning

Don’t put any spaces between the ‘#’ and ‘BEGIN’ or ‘END’. It has bad consequences.

4.4. Check Inputs (optional)

Open {username}HelloWorldImpl.py and find the run_{username}HelloWorld method, which should have some auto-generated boilerplate code and docstrings.

You want to limit your code edits to regions between the comments #BEGIN run_{username}HelloWorld and #END run_{username}HelloWorld. These are special SDK-generated annotations that we have to keep in the code to get everything to compile correctly. If you run make again in the future, it will update the code outside these comments, but will not change the code you put between the sets of #BEGIN and #END comments.

Between the comments, add a simple print statement, such as: print ("Input parameter",params['parameter_1']).

#BEGIN run_{username}HelloWorld
print ("Input parameter",params['parameter_1'])
report = KBaseReport(self.callback_url)
report_info = report.create({'report': {'objects_created':[],
                                        'text_message': params['parameter_1']},
                                        'workspace_name': params['workspace_name']})
output = {
    'report_name': report_info['name'],
    'report_ref': report_info['ref'],
}
#END run_{username}HelloWorld

Don’t try to change the docstring, or anything else outside the #BEGIN run_{username}HelloWorld and #END run_{username}HelloWorld comments, as your change will get overwritten by the make command.

4.5. Run First Test

As a default, your {username}HelloWorldImpl.py file is tested using test/{username}HelloWorld_server_test.py. This file has some auto-generated boilerplate code. Python will automatically run all methods that start with the name test.

Near the bottom of the test file, find the method test_your_method. The default test is to call run_{username}HelloWorld with a workspace_name for the test and a parameter_1 of ‘Hello World’. If you added the optional parameters in the earlier steps, you can modify the test method to test the returned output.

Add a simple print statement to the end of the test method:

print ("report_name", ret[0]['report_name'])

Note

Make sure that you have put your developer token in the test_local/test.cfg as mentioned in the Initialize the Module

Run kb-sdk test and, if everything works, you’ll see the docker container boot up, the run_{username}HelloWorld method will get called, and you will see some printed output. If you added the input and output parameters, the output should include the two lines.

Input parameter Hello World!
report_name report_675e061a-2fce-47aa-ac85-67e3ec975776

When running an app, the messages created by the Impl file and the test will show up in the log. For this module, setting up the docker container will take the most time and generate the most lines in the log. The next example includes a report builder that is used by the Narrative User Interface.