#######################
Writing your own plugin
#######################
Two python files are provided within the documentation to help you write your own plugin:
This :download:`First <../../examples/First.py>` one and this :download:`Second <../../examples/Second.py>` 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 :download:`here <../../../bsPlugins/base/wordlist.py>`
* **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 links to some documentation or
other
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 :download:`file <../../examples/Second.py>`. 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 links to some documentation or
other
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 :ref:`bs-form-label` section.