Python Plugin Developer Guide
Python plugins let you rapidly extend hobbits processing abilities with Python code. Hobbits has a built-in interpreter, and a Python API that allows you to process data at near-native speeds while still taking full advantage of the flexibility and power of Python.
Basic Plugin Structure
Plugins are broken into 2 main parts:
- A JSON file describing the plugin
- A Python script implementing the described plugin
Plugin Installation
Python plugins can be installed in python_displays, python_analyzers,
python_operators, or python_importers folders wherever hobbits searches for
plugins (e.g. ~/.local/share/hobbits/plugins or the plugins folder adjacent
to the hobbits binary.) For example, you could add display plugin files like:
~/.local/share/hobbits/plugins/python_displays/MyPyDisplay/plugin.json
~/.local/share/hobbits/plugins/python_displays/MyPyDisplay/plugin.py
JSON File Structure
The JSON file should provide the following fields:
name- the name of the plugin (string)description- a brief description of the plugin (string)tags- tags for categorizing the plugin (array of strings)script- the name of the python file with the implementation code (string)type- the type of the plugin ("importer","operator", or"analyzer")extra_paths- directories on the local machine where supporting python files/libraries can be found (array of strings)parameters- the parameters that are required by the plugin. It is an array of parameter objects, each of which contains anamefield (string) and atypefield ("string","integer","decimal", or"boolean"). Optionally, a parameter object can list all valid values in an array in apossible_valuesfield, or, in the case of"integer"and"decimal"types, specify minimum and maximum values in theminandmaxfields.
Here's an example JSON file:
{
"name": "String Importer",
"description": "Simple example string importer",
"tags": ["Example"],
"script": "plugin.py",
"type": "importer",
"extra_paths": [],
"parameters": [
{
"name": "my_string",
"type": "string"
}
]
}
Here's a more complicated parameter list:
"parameters": [
{
"name": "hero",
"type": "string",
"possible_values": [
"Sam",
"Frodo",
"Merry",
"Pippin",
"Bilbo
]
},
{
"name": "breakfast_count",
"type": "integer",
"min": 2,
"max": 10
}
]
Display plugins can optionally set their render_config (default values shown):
{
...
"type": "display",
"render_config": {
"asynchronous": true,
"hide_bit_offset_controls": false,
"hide_frame_offset_controls": false
},
...
}
Python Script Structure
The Python script must be valid Python, and it must define a valid entry point function based on the JSON configuration of the plugin. For example, a valid script for the "String Importer" above could be:
def import_bits(bits, info, my_string, progress):
bits.set_bytes(0, my_string.encode('ascii'))
In general terms, a Python plugin with a type of "importer" must have a function
named import_bits that takes the following parameters (in order):
- A
hobbits.BitArraythat will be the imported bits - A
hobbits.BitInfothat will be the imported bits info/metadata - A parameter for each parameter object specified in the
"parameters"array of the JSON configuration - A
hobbits.ActionProgessthat can be used to update progress and check for cancellation
Similarly, an "exporter" type plugin must have a function named export_bits
that takes:
- A
hobbits.ImmutableBitContainerthat will be exported - A parameter for each parameter object specified in the
"parameters"array of the JSON configuration - A
hobbits.ActionProgessthat can be used to update progress and check for cancellation
Similarly, an "analyzer" type plugin must have a function named analyze_bits
that takes:
- A
hobbits.ImmutableBitContainerthat will contain the bits and info to be analyzed - A
hobbits.BitInfothat will be the new info for the bits post-analysis - A parameter for each parameter object specified in the
"parameters"array of the JSON configuration - A
hobbits.ActionProgessthat can be used to update progress and check for cancellation
Similarly, an "operator" type plugin must have a function named operate_on_bits
that takes:
- A
hobbits.ImmutableBitContainerthat will contain the bits and info to be operated on - A
hobbits.BitArraythat will be the output bits of the operation - A
hobbits.BitInfothat will be the output bits info of the operation - A parameter for each parameter object specified in the
"parameters"array of the JSON configuration - A
hobbits.ActionProgessthat can be used to update progress and check for cancellation
A "display" type plugin must have a function named render_display
that takes:
- A
hobbits.DisplayHandlethat will contain the bit container and offsets - A
hobbits.ImageBufferthat will have a size and should be filled with raw ARGB image data - A parameter for each parameter object specified in the
"parameters"array of the JSON configuration - A
hobbits.ActionProgessthat can be used to update progress and check for cancellation
Hobbits Python API
hobbits.BitContainer
BitContainer.bitsgets ahobbits.ImmutableBitArrayBitContainer.infogets ahobbits.BitInfohobbits.ImmutableBitContainerreturns ahobbits.ImmutableBitInfofor theinfoproperty
hobbits.BitArray
BitArray.sizereturns the size of theBitArrayin bitsBitArray.at(i)returns the value of theith bitBitArray.resize(n)resizes theBitArrayto lengthnBitArray.set(i, x)sets theith bit to boolean valuexBitArray.read_bytes(i, n)readsnbytes starting from theith byte and returns the value as a PythonbytearrayBitArray.set_bytes(i, x)writes bytes-like objectxto theBitArraystarting at theith byteBitArray.write_to(fname)writes the contents of theBitArrayto a file namedfnameBitArray.read_from(i, fname)reads the contents of the file namedfnameinto theBitArraystarting at theBitArray'sith bytehobbits.ImmutableBitArrayonly supportssize,at,read_bytes, andwrite_to
hobbits.BitInfo
BitInfo.set_metadata(key, value)sets the metadatakeytovalue(keyandvalueare both strings)BitInfo.get_metadata(key)gets the metadata value ofkeyif it is set (returns empty string if not set)BitInfo.add_highlight(category, label, start, end, color=0x44ff8800)adds a RangeHighlight from bitstarttoend-
BitInfo.get_highlights(category)gets a list of all RangeHighlights of categorycategory -
hobbits.ImmutableBitInfoonly supportsget_metadataandget_highlights
hobbits.ActionProgess
ActionProgess.is_cancelled()returns true if the plugin action was cancelled and should be abortedActionProgress.set_progress_percent(x)reports the progress of the plugin action asxout of 100ActionProgress.set_progress(x, n)reports the progress of the plugin action asxout ofn
hobbits.DisplayHandle
DisplayHandle.current_containertheBitContainerthat should be displayedDisplayHandle.bit_offsetthe current bit offsetDisplayHandle.frame_offsetthe current frame offsetDisplayHandle.total_bit_offsetthe total bit offset (start of offset frame + bit offset)
hobbits.ImageBuffer
ImageBuffer.set_bytes(x)sets the image data to bytes-like objectx(should be 4 *width*heightlong)ImageBuffer.widthwidth of the image (read-only)ImageBuffer.heightthe height of the image (read-only)
Helpful Tools
In order to simplify the process of developing plugins, there are cookiecutters that take care of most of the boilerplate code.
Visit the GitHub repository for Hobbits plugin cookiecutters for a variety of useful cookiecutters and instructions for how to use them.