Documentation/Plugin Development

Plugin Development Guide

Learn how to create custom plugins to extend Bioshift's functionality with your own specialized nodes, tools, and integrations.

Plugin Architecture

Understanding how plugins integrate with Bioshift's core systems.

Plugin System Overview

Understanding how plugins integrate with Bioshift

  • Plugin discovery and loading mechanism
  • Node factory registration system
  • Plugin isolation and sandboxing
  • Version compatibility checking
  • Plugin dependency management

Plugin Structure

Required files and directory structure

  • plugin.json manifest file
  • Python package structure
  • Node implementation files
  • Resource and asset organization
  • Plugin metadata requirements

Plugin Lifecycle

How plugins are loaded and managed

  • Plugin discovery on startup
  • Node registration process
  • Plugin enable/disable functionality
  • Update and compatibility checks
  • Plugin cleanup on shutdown

Step-by-Step Development Guide

Follow these steps to create your first Bioshift plugin.

Step 1: Setup Development Environment

Prepare your development workspace

What you'll do:

  • Install Python 3.8+ with pip
  • Set up virtual environment
  • Install Bioshift development version
  • Install plugin development dependencies
  • Set up code editor with Python support

Example Code:

# Create plugin directory
mkdir my_custom_plugin
cd my_custom_plugin

# Create manifest.json
cat > manifest.json << 'EOF'
{
  "id": "my_custom_plugin",
  "name": "My Custom Plugin",
  "version": "1.0.0",
  "author": "Your Name",
  "description": "A custom plugin for Bioshift",
  "entry_module": "my_plugin.py"
}
EOF

Step 2: Create Plugin Project Structure

Set up the basic plugin skeleton

What you'll do:

  • Create plugin directory structure
  • Write plugin.json manifest file
  • Create __init__.py files
  • Set up Python package configuration
  • Initialize version control

Example Code:

# Plugin directory structure
my_custom_plugin/
├── manifest.json        # Plugin manifest (REQUIRED)
├── my_plugin.py         # Entry module (REQUIRED)
├── icons/               # Optional custom icons
│   └── my_icon.png
└── README.md            # Optional documentation

Step 3: Write Plugin Manifest

Create the plugin.json configuration file

What you'll do:

  • Define plugin metadata
  • Specify plugin dependencies
  • List custom node types
  • Configure plugin settings
  • Set compatibility requirements

Example Code:

{
  "id": "my_custom_plugin",
  "name": "My Custom Plugin",
  "version": "1.0.0",
  "author": "Your Name",
  "description": "A custom plugin for Bioshift",
  "entry_module": "my_plugin.py"
}

Step 4: Implement Custom Nodes

Create your custom node classes

What you'll do:

  • Inherit from BaseNode class
  • Implement required methods
  • Define input/output ports
  • Add node properties and UI
  • Handle node execution logic

Example Code:

from core.nodes import BaseNode


class MyCustomNode(BaseNode):
    """Custom node for special data processing."""

    def __init__(self):
        super().__init__(node_type="my_custom_node", title="My Custom Node")

        # Add input ports
        self.add_input_port("input_data", data_type="string")
        self.add_input_port("parameters", data_type="string")

        # Add output ports
        self.add_output_port("processed_data", data_type="string")
        self.add_output_port("statistics", data_type="string")

        # Set default properties
        self.set_property("processing_mode", "standard")
        self.set_property("enable_logging", True)

    def execute(self, inputs: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
        """Execute the node's processing logic."""
        try:
            # Get input data
            input_data = inputs.get("input_data") if inputs else None
            parameters = inputs.get("parameters", {}) if inputs else {}

            if input_data is None:
                raise ValueError("Input data is required")

            # Process the data
            processed_data, statistics = self._process_data(input_data, parameters)

            # Return results
            return {
                "processed_data": processed_data,
                "statistics": statistics
            }

        except Exception as e:
            self.logger.error(f"Node execution failed: {str(e)}")
            raise

    def _process_data(self, data, parameters):
        """Implement your custom processing logic here."""
        # Example processing - replace with your logic
        import pandas as pd

        if isinstance(data, list) and len(data) > 0:
            df = pd.DataFrame(data)
        elif hasattr(data, '__iter__'):
            df = pd.DataFrame(list(data))
        else:
            raise ValueError("Invalid input data format")

        # Apply your processing
        processed_df = self._apply_custom_processing(df, parameters)

        # Calculate statistics
        stats = {
            'rows_processed': len(processed_df),
            'columns': list(processed_df.columns),
            'processing_mode': self.get_property("processing_mode")
        }

        return processed_df, stats

    def _apply_custom_processing(self, df, parameters):
        """Implement your specific data processing logic."""
        # This is where your custom logic goes
        # Example: add a new calculated column
        df['custom_score'] = df.mean(axis=1)
        return df

    def _inline_summary(self) -> list[str]:
        """Display node status in the canvas."""
        mode = self.get_property("processing_mode")
        return [
            f"Mode: {mode}",
            f"Logging: {'Enabled' if self.get_property('enable_logging') else 'Disabled'}"
        ]

Step 5: Register Plugin with Bioshift

Make your plugin discoverable by Bioshift

What you'll do:

  • Implement plugin registration function
  • Handle node factory integration
  • Set up plugin discovery
  • Configure plugin loading
  • Test plugin registration

Example Code:

def register(api):
    """Register plugin nodes with Bioshift."""
    api.register_node(
        node_type="my_custom_node",
        node_class=MyCustomNode,
        display_name="My Custom Node",
        description="A custom node for data processing",
        category="Examples",
        icon_relpath="icons/my_icon.png"
    )

Step 6: Test and Debug Plugin

Ensure your plugin works correctly

What you'll do:

  • Create test workflows
  • Test node functionality
  • Debug execution errors
  • Validate input/output handling
  • Test edge cases and error conditions

Example Code:

# Testing your plugin:
1. In Bioshift, go to Plugins → Add Plugin…
2. Select your plugin folder
3. Choose Plugins → Reload Plugins
4. Look for your node in the toolbox under the specified category
5. Create a workflow and test the node functionality

# If you encounter issues:
- Check the console output for error messages
- Verify manifest.json has correct format
- Ensure entry_module matches your Python file name
- Make sure register(api) function exists and is properly implemented

Step 7: Package and Distribute

Prepare your plugin for distribution

What you'll do:

  • Create setup.py for pip installation
  • Write comprehensive README
  • Create example workflows
  • Package plugin for distribution
  • Publish to plugin registry

Example Code:

# Create ZIP archive for distribution
zip -r my_custom_plugin.zip my_custom_plugin/

# Alternative: Share the folder directly
# Users can install from folder using Plugins → Add Plugin…

# Distribution tips:
- Include a README.md with usage instructions
- Test your plugin on different systems
- Provide example workflows
- Document any dependencies
- Consider creating a GitHub repository

Advanced Topics

Take your plugin development to the next level with these advanced techniques.

Node UI Customization

Create custom user interfaces for your nodes

  • Custom property dialogs
  • Inline node summaries
  • Interactive controls
  • Progress indicators
  • Real-time status updates

Plugin Configuration

Advanced plugin configuration options

  • Plugin settings management
  • User preferences
  • Configuration validation
  • Settings persistence
  • Plugin-specific options

Error Handling & Logging

Robust error handling and debugging

  • Exception handling strategies
  • Logging best practices
  • Debug mode functionality
  • User-friendly error messages
  • Plugin crash recovery

Performance Optimization

Optimize plugin performance

  • Memory management
  • Asynchronous processing
  • Caching strategies
  • Resource cleanup
  • Performance profiling

Plugin Security

Security considerations for plugin development

  • Input validation
  • Secure file operations
  • Network security
  • API key management
  • Permission handling

Example Plugin Projects

Get inspired by these example plugin projects of varying complexity.

Data Processing Tools

Custom nodes for data manipulation and analysis

Beginner
1-2 weeks
Key Features:
  • Text processing and filtering
  • Data format conversion
  • Statistical calculations
  • Custom data transformations

File Format Converter

Convert between different molecular and data file formats

Intermediate
2-3 weeks
Key Features:
  • Multiple format support
  • Batch conversion
  • Format validation
  • Error reporting

Custom Analysis Nodes

Specialized analysis nodes for specific research workflows

Advanced
3-4 weeks
Key Features:
  • Domain-specific calculations
  • Custom visualization
  • Result export capabilities
  • Integration with external tools

Database Integration

Connect to external databases and import data

Expert
4-6 weeks
Key Features:
  • Database connection management
  • Query execution nodes
  • Data import/export
  • Authentication handling

Ready to Start Building?

Follow our comprehensive step-by-step guide to create your first Bioshift plugin.

Step-by-Step Guide

Follow our detailed tutorial with code examples

Complete Documentation

Comprehensive API reference and examples

Community Support

Get help from the Bioshift developer community