Structural Bioinformatics Library
Template C++ / Python API for developping structural bioinformatics applications.
User Manual

Authors: S. Guo and E. Sarti and F. Cazals

Plugin_manager

Goals

Overview

The Plugin_manager package enables the automatic creation of cross‑platform graphical user‑interface (GUI) plugins for command‑line applications, from a single specification. Its objectives are to:

  • Simplify GUI plugin generation for existing command line interface (CLI) tools.
  • Facilitate interactive use of command‑line applications.
  • Provide extensibility for integration with molecular viewers such as PyMOL, VMD, and NGLViewer.
  • Extend to general scientific applications beyond structural biology, such as general geometric data analysis and visualization using Three.js viewer.

Architecture overview

In theory, developing GUI for $$n$$ applications targeting $$m$$ viewers/platforms require , $$n\times m$$ specific developments. In structural bioinformatics, typical platforms are are VMD, PyMOL, or web servers.

We instead propose a solution requiring in $$n+m$$ developments (Fig. Plugin generation). Our solution, detailed below, hinges on (i) one formal specification per application, and (ii) code generate modules which are platform specific.

Plugin generation using one specification file per application. For each application $$A_i$$, one provides a GUI specification $$S_i$$. Each targeted platform is handled by a dedicated code generator $$C_j$$: $$C_j(A_i)$$ generates the code of i-th application for the j-th platform. Platforms are supported by various rendering engines.

Terminology

  • CLI: Command Line Interface tool (compiled executable, executable script)
  • GUI library: The rendering toolkit used to instantiate widgets and connect them with the backend (e.g., PyQt6, tkinter, Panel).
  • Frontend: The set of UI widgets (labels, entries, checkboxes, buttons, output panels).
  • Backend: The logic that converts frontend inputs into a CLI command, executes it, maps results back to output panels, and updates the output panels and molecular viewer.
  • Platform: The hosting environment where the generated GUI runs (e.g., a VMD plugin, a PyMOL plugin, or a web application).
  • Plugin: A software component embedded within a Platform.
  • panel: An area within the GUI that displays input/update controls or output results.

Using existing plugins for the Structural Bioinformatics Library

Existing plugins

Below is a brief overview of the available plugins and their purpose:

sbl_vorlume_pdb, package Space_filling_model_surface_volume : computes molecular surfaces, volumes, and packing properties.

sbl_intervor_ABW_atomic, package Space_filling_model_interface : detects pairs of interface particles, either between partners in a complex or via mediators (e.g., interfacial water molecules).

sbl_bif_chainsW_atomic, package Space_filling_model_interface_finder : analyzes interfaces and interactions within macromolecular complexes.

sbl_kpax, package Kpax : provides a generic implementation of the Kpax algorithm, a reference structural aligner.

sbl_spectraldom, package Spectral_domain_explorer : identifies structural domains by maximizing intra-domain and minimizing inter-domain interactions.

sbl_misa, package Multiple_interface_string_alignment : combines MSA with interface models to yield Multiple Interface String Alignments (MISA) that encode properties of amino acids at protein–protein interfaces.

sbl_tripeptide_loop_closure, package Tripeptide_loop_closure : generates or modifies tripeptide segments using Tripeptide Loop Closure (TLC).

sbl_alpha_complex_of_molecular_model, package Alpha_complex_of_molecular_model : analyzes the alpha complex of a molecular model.

sbl_alphafold_dbrun, package Alphafold_analysis : characterizes the fragmentation of AlphaFold predictions.

To regenerate the GUIs for all of the above at once, run the orchestration script (this is not needed to run because we have already generated them):

cd Applications/Plugin_manager
bash run_generator.sh
We pair tkinter with VMD and PyQt6 with PyMOL because each host application is built around a different GUI stack. VMD’s UI is Tcl/Tk-based and its Python plugin hooks are designed to create Tk windows; using Tkinter keeps us inside the same event loop, matches VMD’s native look-and-feel, and avoids bundling an extra toolkit. PyMOL, in contrast, runs a Qt UI and exposes pymol.Qt/addmenuitemqt for plugins; building the plugin in PyQt6 integrates cleanly with PyMOL’s Qt event loop, docking behavior, and styling. PyQt6 in VMD is only practical as a separate external window (launched as another process). Embedding Qt inside VMD’s Tk application risks event-loop conflicts and complicates distribution. tkinter in PyMOL is theoretically possible if the embedded Python ships with _tkinter, but modern PyMOL builds often omit Tk, and mixing Tk with a Qt application is fragile.


And their installation

Pixi installation from the Anaconda sbl channel

Refer to section Installing and using SBL with Pixi (Linux 64, OSX 64, OSX ARM64) in the SBL Installation Guide for detailed steps on creating a Pixi environment, installing the SBL package, and running sbl-install-plugins.

Once SBL and the plugins are installed, you can use them as follows:

VMD plugins
Open VMD and navigate to Extensions → SBL to access the available plugins.

PyMOL plugins
Open PyMOL and use the following commands in its terminal:

sbl_help # List all available SBL plugins
sbl_<plugin_name> # Run a specific plugin

Web plugins
Launch the Web plugins dashboard:

sbl-web-plugins-launcher

Then open the URL printed in the terminal (typically http://127.0.0.1:8700/) in your web browser.

Note that PyMOL must be built with PyQt6 support for the SBL PyMOL plugins to work correctly. PyMOL with PyQt5 is not supported.


Generating new plugins

Plugin layout


Plugin: structure. A generated plugin is organized into four areas (Fig. GUI architecture):

  • 1) Input area — receives options and file paths.
  • 2) Output area — displays results produced by the executable (text, tables, figures, pdfs, htmls).
  • 3) 3D molecular graphics area — displays structure/graphics outputs.
  • 4) Update area - contains widgets to refresh outputs and 3D graphics.

We adopt the Model–View–Presenter (MVP) pattern for both the generator and the generated plugins:

  • Model: data and state — the formal JSON specification and runtime metadata.
  • View: the concrete widget layout rendered by the target toolkit.
  • Presenter: generated glue that binds Model and View, handles user events, builds and executes the CLI, runs post‑analysis, and refreshes outputs and viewers.


Plugin at work: data flow.

  • 1) User options are collected in the input area and translated into a CLI command.
  • 2) After execution, an optional post‑analysis script extracts and formats results for the output area.
  • 3) Two callbacks are then triggered: one populates output panels; the other drives 3D visualization.
  • 4) The update area allows users to manually refresh outputs and 3D graphics.

On desktop platforms, VMD and PyMOL execute the viewer scripts (.vmd or .py) produced by the post analysis script and render them in their display windows. In the web platform, a Panel application embeds or links to an NGLViewer / Three.js viewer page served on a standalone port. The viewer is refreshed based on the json file generated by the post‑analysis script.

GUI: generic architecture
A plugin consists of four main areas: (1) the Input area enabling the specification of input data, (2) The output are to display statistics and figures, (3) The 3D molecular graphics area, and (4) The update area for refreshing outputs.

The three steps


Plugin design: the three steps. A typical workflow comprises three phases:

  • Step 1) Design — choose input options, desired outputs, update options, and the arrangement of input/output/update areas.
  • Step 2) Formal specification — automatically generate a JSON specification of the plugin layout and behavior.
  • Step 3) Code generation — produce concrete plugin code for the selected platform(s).

The user designed associated files are as follows:

  • layout.ui — Qt Designer file defining geometry for input/output/update areas.
  • selected_flags.txt — plain‑text list of CLI flags to expose in the input area.
  • update_area_flags.txt — optional plain‑text list of flags for the post‑analysis script.
  • post_analysis.py — Python script that converts raw CLI outputs into panel‑ready and viewer-ready files.


The script run_generator.sh A convenience script (run_generator.sh) in Applications/ <AppName>/plugins automates code generation. The command: bash run_generator.sh, which run in the plugins folder will produce the three GUIs: Tkinter for VMD, PyQt6 for PyMOL, and Panel for the web under the folder Applications/ <AppName>/plugins/step3_generated_code. Fig. GUI design workflow shows the design workflow of SBL GUI plugins using an example.


Files generated. For each application, say SBL_DIR/Application_XXX, the $\text{\texttt{plugins}}$ directory contains exactly three subfolders hosting the generated files:

  • $\text{\texttt{step1\_design/}}$: inputs for the generator, including $\text{\texttt{layout.ui}}$, $\text{\texttt{selected\_flags.txt}}$, and optional $\text{\texttt{update\_area\_flags.txt}}$.
  • $\text{\texttt{step2\_formal\_spec/}}$: the auto–generated formal specification in JSON format.
  • $\text{\texttt{step3\_generated\_code/}}$: the auto–generated plugin code, packaged as $\text{\texttt{vmd.tar.gz}}$, $\text{\texttt{pymol.tar.gz}}$, and $\text{\texttt{web.tar.gz}}$.

GUI: design example
An example of using the sbl-gui-generator.py to automatic create cross‑platform graphical user‑interface (GUI) plugins for command‑line applications.

Example -

Preparing the input files


Step 1: Preparing layout.ui. Requirements:

  • Each area (input, output, optional update) must have a geometry rectangle (x, y, width, height).
  • The input area must be named inputPanel. The update area is optional and must be named updatePanel.
  • Output widgets must be named by type and index: outputText\d *, outputFigure\d *, outputPDF\d *, outputTable\d *, outputHtml\d *, or outputHtmlTabs.

This .ui file is created using Qt Designer and saved as layout.ui.

The following is the layout file for the plugin sbl_spectraldom from the package Spectral_domain_explorer :

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Form</class>
<widget class="QWidget" name="Form">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1332</width>
<height>738</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<widget class="QFrame" name="inputPanel">
<property name="geometry">
<rect>
<x>20</x>
<y>20</y>
<width>611</width>
<height>701</height>
</rect>
</property>
<property name="frameShape">
<enum>QFrame::Shape::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Shadow::Raised</enum>
</property>
</widget>
<widget class="QFrame" name="outputPDF1">
<property name="geometry">
<rect>
<x>680</x>
<y>110</y>
<width>631</width>
<height>611</height>
</rect>
</property>
<property name="frameShape">
<enum>QFrame::Shape::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Shadow::Raised</enum>
</property>
</widget>
<widget class="QFrame" name="updatePanel">
<property name="geometry">
<rect>
<x>680</x>
<y>20</y>
<width>631</width>
<height>81</height>
</rect>
</property>
<property name="frameShape">
<enum>QFrame::Shape::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Shadow::Raised</enum>
</property>
</widget>
</widget>
<resources/>
<connections/>
</ui>


Step 1: Preparing selected_flags.txt. This file lists the options to expose in the inputPanel.

The following is the selected_flags.txt file for the plugin sbl_spectraldom from the package Spectral_domain_explorer-package:

--mode
--pdb-fpath
--load-chains
--msa-fpath
--structures-fpath
--kmin
--kmax
--dmax-contacts
--stiffness-cov
--stiffness-ncov
--stiffness-hbond
--stiffness-mode
--post
--output-dir

Mapping to widgets:

  • Options with parameters → an Entry (file/directory options also provide a Browse Button) plus a tooltip Label (shows CLI help on hover).
  • Boolean flags → a Checkbox plus a tooltip Label.
  • Each flag’s controls are grouped in a Frame.
  • An additional free‑form Entry accepts extra CLI options.
  • A Run Button is appended, with a tooltip displaying the CLI header.

Advanced usage of selected_flags.txt. Beyond the simple "one flag per line" format shown above, an optional CSV‑style format allows you to control tooltips, default values, and widget behaviour on a per‑flag basis. Each non‑comment line can contain up to four comma‑separated fields:

flag, info message, default value, entry type

Blank fields fall back to the values parsed from the CLI --help output. Comment lines starting with # are ignored. An example is provided :

# flag name, info message, default value, entry type
-f,,,isInputStructure
-P, chains of first partner (such as: AB),,
-P, chains of second parter (such as: C),,
--water,,true,
--hetatoms,,false,
-d,,,isOutputDir

The four columns have the following meaning:

  • flag: the CLI flag to expose (exactly as in --help).
  • info message: optional tooltip text overriding the description taken from --help (leave empty to use the help description).
  • default value: optional default value overriding the one from --help. For flags with an argument this fills the corresponding Entry; for boolean flags (no argument) this controls the initial state of the Checkbox (accepted truthy values include 1/true/yes/on/y/t; false values include 0/false/no/off/n/f).
  • entry type: optional semantic tag used by the generators to specialise behaviour. For instance, isInputStructure forces a file chooser to be attached to the Entry, and isOutputDir forces a directory chooser.


Step1: Preparing post_analysis.py. To align with widget names, the post‑analysis script must produce files using the following conventions:

  • outputFigure1outputFigure1.png (static image) and/or outputFigure1.dat (data for interactive figures)
  • outputPDF1outputPDF1.pdf (PDF)
  • outputTable1outputTable1.csv (table)
  • outputText1outputText1.txt (text)
  • outputHtml1outputHtml1.html (standalone HTML)
  • 1.vmd / 1.py / 1.json → viewer script or json for molecular graphics area

Reference script for the SBL Intervor plugin: $SBL_DIR/Applications/Space_filling_model_interface/scripts/intervor_abw_atomic_plugin_post_analysis.py

Example call:

intervor_abw_atomic_plugin_post_analysis.py \
-d /path/to/sbl_output \
-p /path/to/post_analysis_output \
-w 80 \
--viewer vmd/pymol/ngl
Note
The generated plugin invokes the post‑analysis script with -d (executable output directory), -p (post‑analysis output directory), --post-flag <value from Update area, if present>, and --viewer <vmd|pymol|ngl> depending on the target platform. The plugin then refreshes its Output area and the molecular viewer based on the files produced by the post‑analysis script.

The following is the plugin_post_analysis.py file for the plugin sbl_spectraldom from the package Spectral_domain_explorer-package:

#!/usr/bin/env python3
"""Runner for Spectraldom post-analysis.
This script only parses CLI arguments and delegates all logic to the
SpectraldomPostAnalyzer service.
"""
import argparse
import sys
from pathlib import Path
from spectraldom_post_analysis_services import SpectraldomPostAnalyzer
def parse_args() -> argparse.Namespace:
"""Parse command-line arguments for spectraldom post-analysis."""
parser = argparse.ArgumentParser(
description="Process spectraldom outputs: extract quality plot, local maxima, and prepare viewer assets."
)
parser.add_argument(
"-d", "--output-dir", required=True, help="Directory containing run outputs"
)
parser.add_argument(
"-p", "--post-dir", required=True, help="Directory to store post-analysis outputs"
)
parser.add_argument(
"-k", "--k-value", type=int, help="Desired k-value (overrides automatic selection from local maxima)"
)
parser.add_argument(
"--viewer", choices=["vmd", "pymol", "ngl"], help="Viewer type to prepare assets for"
)
return parser.parse_args()
def main() -> int:
"""CLI entrypoint for spectraldom post-analysis."""
args = parse_args()
out_dir = Path(args.output_dir).resolve()
post_dir = Path(args.post_dir).resolve()
if not out_dir.exists():
print(f"Error: Output directory does not exist: {out_dir}", file=sys.stderr)
return 1
analyzer = SpectraldomPostAnalyzer(out_dir, post_dir, k_value=getattr(args, "k_value", None), viewer=getattr(args, "viewer", None))
rc = analyzer.run()
if rc == 0:
print(f"Post-analysis complete. Files saved to: {post_dir}")
else:
print(
f"Post-analysis finished with issues. Check output for details.",
file=sys.stderr,
)
return rc
if __name__ == "__main__":
sys.exit(main())


Step1: Preparing update_area_flags.txt file. This optional file lists flags to expose in the updatePanel, which parameterize the post‑analysis step to update the outputs.

The following is the update_area_flags.txt file for the plugin sbl_spectraldom from the package Spectral_domain_explorer-package:

-k, K Value, K Value corresponds to different clustering results.

Generating the plugin code


Step 2: Generating the plugin formal specification JSON file. Once layout.ui, intervor_abw_atomic_plugin_post_analysis.py, selected_flags.txt, and update_area_flags.txt are ready, generate platform‑specific code via running the bash script run_generator.sh in the plugins folder:

./run_generator.sh --compress all

The above process call the main generator script sbl-gui-generator.py,

sbl-gui-generator.py \
--ui layout.ui \
--exe sbl-intervor-abw-atomic.exe \
--flags selected_flags.txt \
--post-script intervor_abw_atomic_plugin_post_analysis.py \
--update-flags update_area_flags.txt \
--format pyqt tkinter panel-ngljs \
--gui-output step3_generated_code/

This first produces the formal specification JSON file intervor-ABW-atomic_gui.json, which will finally located in the folder Applications/ <AppName>/plugins/step2_formal_spec.


Step 3: Generating the plugin code. Then it produces the platform-specific plugin code based on the formal specification JSON file. This creates the three GUIs: VMD, PyMOL, and Web. The generated code is located under the folder Applications/ <AppName>/plugins/step3_generated_code as vmd.tar.gz, pymol.tar.gz, and web.tar.gz.

(Advanced) Formal specifications: details

The used defined files layout.ui and selected_flags.txt and update_area_flags.txt are converted to a JSON specification that records widget types, geometry, and metadata.

In the following, we present the types and syntax used for this conversion.

Types

The following widget types in JSON currently includes:

  • Input widgets (5): "Label", "Frame", "Entry", "Button", "Checkbox".
  • Output widgets (4): "TextArea", "ImageView", "TableView", "HtmlView".

The JSON file consists of four sections–the first three being derived from the ui file:


Input panel section. Based on selected_flags.txt, we populate the children of inputPanel: flags with parameters from the CLI become an Entry (file/directory entries are paired with a Button to open a selector) followed by a tooltip Label that shows the help text on hover; boolean flags become a Checkbox plus a tooltip Label. Each flag’s controls are grouped in a Frame. An additional free–form Entry accepts extra CLI options. Finally, a Run Button is added with a tooltip showing the CLI header.


Output panel section. This section declares the widgets that present artifacts produced by the post-analysis step after the CLI finishes. Concretely, output panels are a set of typed widgets: TextArea, ImageView, TableView, each with a file pattern and refresh policy. After a run, the generator calls refresh_output_panel method: it scans output_dir for the newest files matching the source glob of each widget and updates the views accordingly.

  • TextArea: shows parsed text information from the CLI log and outputs.
  • ImageView: shows figures written by the post script (e.g., .png). (If a sidecar data file .dat exists with the same basename, the generator upgrades the view to an interactive plot (matplotlib in Tkinter/PyQt; Plotly in Panel) with pan/zoom and save-as.)
  • TableView: loads tabular outputs (.csv) into a sortable, filterable table (QTableWidget in PyQt, ttk/Tabulator in Tkinter/Panel).
  • HtmlView: renders standalone HTML outputs (.html) in an embedded browser (QWebEngineView in PyQt6, tkinterweb in Tkinter, native Panel HTML pane).


Update panel section. This optional section declares widgets that control the post-analysis step. Based on post_analysis_flags.txt, these controls mirror input widgets but are not passed to the CLI; instead, they parameterize the post‑analysis. Changing any of these parameters and clicking the Update button triggers a re‑run of the post‑analysis and selectively refreshes the affected output widgets and/or the 3D view.

All output widgets are read‑only and refresh automatically after a successful run or when the Update area triggers a refresh.


Metadata section. Includes a metadata block (e.g., exe_name, post_script).

Mapping JSON to backends

As already discussed, we automatically generated code for the targeted platform from the formal specification (Fig. fig-plugin-generation). The mapping between formal types and those used by the platforms is as follows:

Mapping between JSON widget types to types used by the backends.

(Advanced) Workflow and associated modules

We detail the implement of the sbl-gui-generator method here.

Workflow

The main entry point is $\text{\texttt{\$SBL\_DIR/Applications/Plugin\_manager/scripts/sbl-gui-generator.py}}$.

A convenience script, $\text{\texttt{run\_generator.sh}}$, in the same directory orchestrates the generation of all plugins; it delegates to each application’s own $\text{\texttt{plugins/run\_generator.sh}}$.

To generate a concrete plugin for an application, the generator copies the appropriate templates and injects application–specific pieces into $\text{\texttt{mvp/config.py}}$ and $\text{\texttt{mvp/ui/widget\_builders.py}}$.

Plugin manager modules. (A) Design phase. Using a layout editor, the designer (i) arranges the relative positions and sizes of widgets for the Input and Output areas; (ii) selects the CLI options (flags and arguments) to expose in the Input area; and (iii) specifies post–analysis parameters to surface in the optional Update area, whose changes selectively refresh the Output area and/or the 3D display. (B)Generation of the formal specification. A formal specification of the layout for the Input and Output areas is automatically generated. Plugin generation. (C) The python code of plugins is automatically generated. From the JSON, we synthesize frontend and backend code for the GUI libraries targeted (PyQt6, tkinter, or Panel). Widget types are mapped to their platform–specific counterparts and the generated backend logic constructs the CLI command, executes it, runs the post–analysis (if any), refreshes outputs, and displays results in the molecule viewer.

Modules

The previously described workflow is implemented by the following modules (Fig. Code modules); each has a clear responsibility and can be combined to target different GUI frameworks:

  1. $\text{\texttt{scripts/sbl-gui-generator.py}}$: entry point that invokes SBL::gui_generator_manager::GUIGeneratorManager.
  2. SBL::gui_generator_manager::GUIGeneratorManager ( $\text{\texttt{python/SBL/gui\_generator\_manager.py}}$): orchestrates the pipeline:
  3. $\text{\texttt{python/SBL/gui\_json\_schema.py}}$: JSON schema, dataclasses, and validation helpers.
  4. $\text{\texttt{python/SBL/gui\_ui2json.py}}$ and $\text{\texttt{gui\_ui2json\_*.py}}$: UI parsing and helpers for building the formal specification.
  5. $\text{\texttt{python/SBL/gui\_codegen.py}}$: dispatch to backends. Backends include:
  6. $\text{\texttt{gui\_panels\_generator\_*.py}}$ and $\text{\texttt{gui\_widgets\_generator\_*.py}}$: code‑emission helpers per framework.
  7. $\text{\texttt{gui\_codegen\_utils.py}}$: shared utilities for code generation.

Layout geometry

For PyQt6 and Tkinter, absolute positions and sizes from the $\text{\texttt{.ui}}$ file are stored in JSON for codes generation.

For Panel, which is row/column–based, we quantize absolute widget coordinates onto a fixed $5,px \times 5,px$ logical grid. Coordinates are translated so that the minimum top‑left corner defines the origin $(\min x, \min y)$.

The grid size is $\lceil(\max x -\min x)/5 \rceil$ columns by $\lceil(\max y -\min y)/5 \rceil$ rows.

A widget with bounding box $(x, y, \text{width}, \text{height})$ is mapped to 1‑based, inclusive indices: col_start = floor((x − min_x)/5) + 1; col_end = floor((x + width − 1 − min_x)/5) + 1; row_start = floor((y − min_y)/5) + 1; row_end = floor((y + height − 1 − min_y)/5) + 1.

Indices are clamped to the grid bounds. An optional overlap resolver relocates later widgets (row‑major scan) to the first free slot that accommodates their span; if no slot exists, new rows are appended at the bottom. The final indices are stored in JSON for Panel code generation. Widths/heights smaller than one pixel are treated as $1,px$ to ensure each widget occupies at least one grid cell.

For PyQt6 and tkinter, absolute positions and sizes from the .ui file are used directly. For Panel, which is row/column–based, we assign grid coordinates from the absolute widget positions.

Templates and MVP layout (VMD, PyMOL, Web)

Templates root. Target–agnostic templates live under $SBL_DIR/Applications/Plugin_manager/template_files/ with three subfolders: vmd/, pymol/, and web-ngljs/, web-threejs.

VMD (Tkinter). Each VMD plugin template provides gui.py, pkgIndex.tcl, and sbl_pluginname.tcl, plus an mvp/ subtree with: config.py, presenter.py, services/, and ui/.

PyMOL (PyQt6). Same mvp/ structure as VMD (no Tcl files), with PyQt6–based UI code.

Web-NGL (Panel). Mirrors the same mvp/ layout and includes an ngl_viewer/ directory for NGL static assets.

Web-Three.js (Panel). Mirrors the same mvp/ layout and includes a threejs_viewer/ directory for Three.js static assets.

NGL viewer assets. The NGL static assets are developed in $SBL_DIR/Applications/Plugin_manager/viewer_app/ (TypeScript). Build them with:

cd $SBL_DIR/Applications/Plugin_manager/viewer_app/
npm install
npm run build

The build outputs to $SBL_DIR/Applications/Plugin_manager/template_files/web/ngl_viewer/.

(Advanced) Web apps and Panel

The PANEL framework

PANEL provides a unified framework to build dashboards and interactive applications in Python, leveraging the PyData ecosystem (e.g., Pandas, Matplotlib, Plotly). In our workflow, GUI-generation outputs are translated into Panel widgets and layout primitives. A typical launch command is:

panel serve app.py

While suitable for prototyping, this mode lacks production features such as HTTPS, traffic routing, process supervision and standard web port exposure. These limitations are addressed via our deployment stack.

NGL viewer integration

Our Panel-based web GUIs embed advanced 3D viewers - for example NGL Viewer (molecular structures) or Three.js (geometry) — via iframes. Data (PDB/JSON) are exported by the post-analysis routine, the viewer is re-loaded with a cache-busting query parameter, and the rendering is handled entirely client-side. This separation of execution (server) and rendering (browser) simplifies deployment under web security policies. A schematic is shown in Fig. fig-panel-nglviewer-workflow .

Panel–NGL/Three.js integration workflow. The Panel-based web GUI embeds a dedicated viewer via an <iframe>; structural and geometric data are exported to JSON and PDB files, and the viewer is reloaded with a cache-busting query string to fetch updated content.

Deployment Stack

Since the default panel serve app.py mode is intended for development rather than production, our deployment uses a robust production stack (Fig. fig-panel-deployment: the Panel app (via Bokeh server) is managed by the OS service manager (e.g., systemd), and sits behind Nginx which handles TLS termination and proxies HTTP/WebSocket traffic. Multiple apps can be hosted via URL prefixes.

Production deployment architecture for Panel apps. The Panel‐based web application (Bokeh server) listens on a local port (e.g., 5006) and is managed via systemd, while Nginx handles public access (ports 80/443), TLS termination, and forwards HTTP/WebSocket traffic to the app.