gluetool
modules¶
All application specific functionality should be placed into modules. Modules are defined in one Python file and the module class must inherit from the class gluetool.glue.Module
.
Importing of modules¶
The framework searches for modules in the module path(s). By default the module path is gluetool/modules
in the project’s root directory. You can override the module path with the --module-path
option on the command line or via the gluetool configuration. The search algorithm tries to be clever about the import. It firstly parses the syntax tree of all *.py
files it finds in the modules path(s) and imports it only if it finds a class definition which inherits from the gluetool.glue.Module
class.
Note
The module importing logic requires that you always inherit from the
gluetool.glue.Modules
class or your module will not be imported. So for example, if you want to extend an existing moduleKoji
toMyKoji
, you need to use:class MyKoji(Koji, Module): ...
Basic attributes¶
Name and description¶
Module must define one or more unique names with the class variable name
. This name identifies the module on the command line. For more information about modules providing multiple names see the section Modules with multiple names.
Module should also define description with the class variable description
, which will be displayed in the module listing, i.e. gluetool -l
.
Options¶
Modules can define an options
dictionary, which defines their command line arguments and also the module configuration at once. Modules can use their option method <gluetool.glue.Module.option> to access the option value. The method returns None
if option does not exist or it’s value is not defined.
Note
The
gluetool
framework currently provides support only for named options/arguments. It is strongly advised to use named options only.
A module option value can be specified in 3 ways and in this precedence (later replaces the previously defined value):
- value defined by the
default
key in the option’s dictionary- value read from the module configuration <modules_configuration>
- value read from the module’s command line argument
The first two possibilities are used to define the option defaults. The command line argument value is used to override these if needed.
Modules can define a list of required options using the required_options
class variable. The required options specify which options need to be specified when executing the module.
Note
It is advised to use
required_options
list instead of argparse’s required option because the latter will only require the option specified on the command line, while therequired_options
list also takes into account values read from the module configuration <modules_configuration>.
Basic methods¶
Modules usually want to implement three main Module
methods - sanity
, execute
and destroy
.
The sanity method
is called after parsing the command line options and the configuration files before any module is executed. The usual use-case for using the sanity method is to do additional actions before any module is executed.
The execute method
is the main entrypoint for the module. This method usually implements the module’s main functionality.
The destroy method
is called after the execution of all the modules specified in the pipeline. The destroy methods are called in the opposite direction as the modules are executed and the methods are called also if the execution of the pipeline did not finish (e.g. a module aborted the execution).
Examples¶
A minimal module¶
Adding a new gluetool module is very simple. This is a minimal module that just prints ‘hello world’:
from gluetool import Module class MinimalModule(Module): name = 'example-minimal' description = 'A minimal module' def execute(self): self.info('hello world')
Drop this module into the module path and try to run the module via:
$ gluetool minimal
Advanced development techniques¶
Modules with multiple names¶
Modules can actually define multiple names under which they can be called on the command line. This is very useful, if you have the same plugin providing access to various instances of the same system, or a system that can be used using the same API. An example can be a postgresql module, that can be also used to connect to an Teiid instance. The benefit from having the same module appearing with different name is that you can define specific configuration for each module incarnation.
from gluetool import Module class Posgresql(Module): name = ('postgresql', 'teiid') ....