Writing your own plugin

Two python files are provided within the documentation to help you write your own plugin: This First one and this Second one.

Structure

Plugins are all structured the same way :

  • Imports
  • Metadata
  • Plugin information
  • Form
  • Plugin

We will take the first example to go through all categories, notice that in the first exemple, the form part is skipped and is automatically guessed by BioScript, so we will do that part at the end.

Imports

These are usual python imports, plus one that you need to build your plugin:

import os
import random
from bsPlugins import OperationPlugin

Here os and random are needed for the operation. OperationPlugin is what you need to build your plugin.

Metadata

Some information about the plugin, that will be displayed on the interface:

meta = {
   'version': "1.0.1",
   'author': "Yohan Jarosz",
   'contact': "webmaster-bbcf@epfl.ch"}

Here some information about the version of this plugin, it’s author and how to contact him.

Plugin information

Describe the parameters of your plugin aka all inputs (in) and outputs (out):

parameters = {'in': [{'id': 'input', 'type': 'text', 'required': True}, ],
             'out': [{'id': 'output', 'type': 'file'}, ]}

These are two lists of small dictionnaries that describe the parameters:

  • id: A unique string of your choice that identify the parameter.
  • type: Describe the type of the parameter. There is a list of predefined ones that you can view here
  • required: If the parameter is not optionnal (default: False). For the inputs only.
  • multiple: If the parameter can be inputed several times (default: False). For the inputs only.

Then add a description of your plugin:

plugin_information = {
   'title': 'WriteFile',

   'description': """As an exemple, this plugin writes the input you give in a text file.
   You can also put <a href='https://github.com/bbcf/bs.operations/blob/master/Examples.py'>links</a> to some documentation or
   other <br/> HTML tags.""",

   'path': ['Examples', 'Automatics forms', 'Write output to a file'],

   'in': parameters['in'],
   'out': parameters['out']
}
  • title: A title for your plugin
  • description: A description of whet are doing your plugin
  • path: How to access your plugin from the interface. Here I need to click on Examples then on Automatics forms an finally on Write output to a file.
  • meta: The metadate. Described above.
  • in and out: input and output paramters. Described above.

Plugin

The main plugin part. Let ‘s say you want to plug the following operation:

def write_input_in_a_file(input, output_path):
    """
    Write an input in an output file.
    :param: input: The string that will be written in a file.
    :param: output_path: The ouput path.
    """
    with open(output_path, 'w') as f:
        f.write(input)

Inherit from OperationPlugin

First build a class that will inherit from OperationPlugin:

class Simple(OperationPlugin):
   pass

Integrate the plugin information that you have already defined:

class Simple(OperationPlugin):
   info = plugin_information

Integrate in the __call__

Integrate your function in the __call__ function. Notice that the parameter of your function can now be retrieved with the keyword arguments:

class Simple(OperationPlugin):
    info = plugin_information

    def __call__(self, *args, **kw):
        text = kw.get('input', '')
        output_path = self.temporary_path()

        with open(output_path, 'w') as f:
            f.write(text)

        self.new_file(output_path, 'output')
        return 1

The parameter input of your function can be retrived in the python keyword argument:

text = kw.get('input', '')

Generate temporary paths

The output_path need to be generated by Bioscript, temporary_path will do it. You can provide a name:

output_path = self.temporary_path(fname='my_output.txt')

Then this is the core of your function:

with open(output_path, 'w') as f:
    f.write(text)

Add file in the plugin result

Finally, all temporary files are deleted at the end of the operation, so you need to add the result file as an output:

self.new_file(output_path, 'output')

The first parameter is the path of the file to add. The second parameter is the id of the output that must be present in the output parameters (parameters[‘out’])

Form

Sometimes you want more control over what to display to the user or you want to make something that is dynamic. Or just the default form doesn’t suits you. So you can add a parameter in the plugin information to define your own form.

This example is taken from this file. It is the same as previous but with the form section not skipped.

Import the base form for Bioscript and toscawidget forms and add it to the imports:

import os
import random
from bsPlugins import OperationPlugin
from bsPlugins import BaseForm
from bsPlugins import twf

Declare a new class that inherit from BaseForm:

class MySimpleForm(BaseForm):
    text = twf.TextField(label="Input something in a file : ")
    submit = twf.SubmitButton(id="submit", value="Write it")

Add it to the plugin parameters on the parameter output:

plugin_information = {
    'title': 'WriteFile',

    'description': """As an exemple, this plugin writes the input you give in a text file.
    You can also put <a href='https://github.com/bbcf/bs.operations/blob/master/Examples.py'>links</a> to some documentation or
    other <br/> HTML tags.""",

    'path': ['Examples', 'Automatics forms', 'Write output to a file'],

    'meta': meta,

    'in': parameters['in'],
    'out': parameters['out'],

    'output': MySimpleForm
}

To know more, please go to the Bioscript Forms section.