Design Hub's real time plugins display information about a chemical structure, such as predicted properties, compound availability or patentability information, by connecting to databases or calling RESTful JSON web services. There are 2 technical approaches to defining and loading plugins:
NodeJS modules, stored in a folder set by Design Hub'sconfiguration file (servicesDirectory
)
REST API implementing microservices, loaded through URLs defined in Design Hub's configuration file (remoteServices
)
As described below in the specification, the 2 approaches follow the same concepts, and internally are managed by the same service, so outgoing call arguments are the same regardless of the technical choice, and your plugin's configuration will have identical behaviour in the application regardless of the API.
These real time plugins are meant to quickly display relevant, summary information about a chemical structure in a given topic. A chemical structure is typically optimized taking a dozen different attributes into account, which doesn’t allow a lot of details into any single one, but a summary level of detail is useful to prevent mistakes and provide options for further insight on demand. A summary of a topic should consist of a few key numbers, a few important category names, a single structure image, identifiers or hit counts. Further information can be provided as a link, which the users could follow and review later.
Plugins provide good default configurations to the users, but optionally can be reconfigured using checkboxes, dropdowns or text field inputs.
Design Hub scans the service definitions find all real time plugins and generates a GUI element to enable or disable them. When a plugin is enabled, its window is displayed, and that subsequent structure editing can refresh the calculation results. This is done by calling the update()
function or /update
endpoint of all enabled plugins with the MRV formatted source of that structure. When the promise of this update is resolved or rejected, the results or error message appears for the users.
an instance of Design Hub available for development purposes, i.e.: the ability to stop and start it, to try different configuration options
for the NodeJS module API: familiarity with JavaScript, NodeJS and its module system and good understanding of Promises / async await operations
for the REST API: familiarity with REST API implementing frameworks in your toolkit's programming language (such as Spring Boot for Java, or fastAPI for Python)
{info} NodeJS introduction material: https://www.youtube.com/watch?v=_l96hPlqzcI (78m), https://www.youtube.com/watch?v=hKQr2DGJjUQ (19m), https://www.youtube.com/watch?v=cJVXP1bU68Y (48m)
NodeJS module description: https://nodejs.org/api/modules.htmlPromise introduction: https://www.html5rocks.com/en/tutorials/es6/promises/#toc-async, https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function
Templating basics in Angular JS: https://docs.angularjs.org/tutorial/step_02
Real time plugins are NodeJS modules , denoted by their filename: *.realtime.js
and location in the services directory as configured during installation.
A real time plugin exports the following properties:
Name | Type | Required | Description |
---|---|---|---|
update |
async function | yes | The main function of the plugin, called when the sketcher is used, once for each change. The function must return a Promise of the results / be declared as an async function with NodeJS v8. The results are broadcasted by the application.Arguments: mrvSource (string) MRV formatted chemical structure of the editor pinnedStructure (string) MRV formatted chemical structure of the (optionally) pinned structure used for comparisons * this includes domain and settings for the current callReturn value: Promise The return value must be a JS Object with a client property containing the data to be linked to the template and a report property with the data needed for the client template and the data needed for the report respectively. Please see the tutorial below. |
name |
string | yes | Unique identifier of the plugin, used by Design Hub for identification and internal communication. If multiple plugins use the same identifier, the last one to be loaded overrides the others. |
label |
string | yes | Human readable name of the plugin, used by Design Hub to display GUI elements related to this plugin: as menu entry in the menu to enable the plugin, as title of the panel displaying the results. |
template |
string | one of template or templateFile |
The plugin template is an HTML fragment that’s injected into the room’s interface as a panel. The templating language is Angular JS, which should allow interpolating formatted numbers or easily enumerating a list. The result of the update call is made available as the client variable inside the template fragment. |
templateFile |
string | one of template or templateFile |
Relative path to an HTML file that contains the template. |
domains |
array of strings | yes | List of domains where this plugin may be used, when authentication is enabled in Design Hub. Use * to allow any domain. If no authentication is setup, this option has no effect. To query the configured domains, send a GET request to /domains or open /domains in your browser. |
sortOrder |
number | no | Sorting order of the plugin as it appears on the GUI. Sorting is ascending. If no number is specified, plugins are sorted by name .Default: 9999 |
settings |
array of objects | no | Configuration options exposed to a chemist in a generated UI component of the plugin. Values selected are passed in this to subsequent update() calls. A valid setting object has the following properties: label , type , default , and values .Default: none |
settings[*].label |
string | yes | Human friendly name of the setting. |
settings[*].type |
string | yes | One of: boolean, string, number, enum. |
settings[*].default |
any | no | Default value of the setting. |
settings[*].values |
array of strings | no / yes for enum type |
Picklist contents for enum type setting. |
docs |
string | no | Text describing technical details of this plugin. URLs will be automatically made clickable. When specified, an icon will be rendered on the plugin's GUI panel. |
contact |
string | no | Text describing ways to contact to owner of this plugin. URLs and email addresses will be automatically made clickable. When specified, an icon will be rendered on the plugin's GUI panel. |
Note: you may use _development
authentication type to test aspects of your plugin specific to a domain. This authentication type accepts any username, password combination, where the 2 field string match.
Available from v20.3.1, Design Hub plugins are single-purpose microservice endpoints that describe the plugin and provide a calculation endpoint to be called as user activity demands. These are implemented by 2 JSON endpoints specified below.
Method: GET
Path: /
Purpose: Provides metadata about the plugin.
Required : yes
Request parameters : None
Response content-type: application/json
Response body: JSON object with the following properties:
Name | Type | Required | Description |
---|---|---|---|
type |
string | yes | The type property should be realtime for realtime plugins. |
name |
string | yes | Unique identifier of the plugin, used by Design Hub for identification and internal communication. If multiple plugins use the same identifier, the last one to be loaded overrides the others. |
label |
string | yes | Human readable name of the plugin, used by Design Hub to display GUI elements related to this plugin: as menu entry in the menu to enable the plugin, as title of the panel displaying the results. |
template |
string | yes | The plugin template is an HTML fragment that’s injected into the Compound creation interface as a panel. The templating language is Angular JS, which should allow interpolating formatted numbers or easily enumerating a list. The result of the update call is made available as the client variable inside the template fragment. |
domains |
array of strings | yes | List of domains where this plugin may be used, when authentication is enabled in Design Hub. Use * to allow any domain. |
sortOrder |
number | no | Sorting order of the plugin as it appears on the GUI. Sorting is ascending. If no number is specified, plugins are sorted by name .Default: 9999 |
settings |
array of objects | no | Configuration options exposed to a chemist in a generated UI component of the plugin. Values selected are passed in the settings object to subsequent POST /update calls. A valid setting object has the following properties: label , type , default , and values .Default: none |
settings[*].label |
string | yes | Human friendly name of the setting. |
settings[*].type |
string | yes | One of: boolean, string, number, enum. |
settings[*].default |
any | no | Default value of the setting. |
settings[*].values |
array of strings | no / yes for enum type |
Picklist contents for enum type setting. |
docs |
string | no | Text describing important usage details of this plugin. URLs will be automatically made clickable. When specified, an icon will be rendered on the plugin's GUI panel. |
contact |
string | no | Text describing ways to contact to owner of this plugin. URLs and email addresses will be automatically made clickable. When specified, an icon will be rendered on the plugin's GUI panel. |
Method: POST
Path: /update
Purpose: Called once for each compound change to obtain calculation results.
Required: yes
Request content-type: application/json
Request body:
Name | Type | Description |
---|---|---|
structure |
string | MRV formatted chemical structure of the editor |
pinnedStructure |
string | MRV formatted chemical structure of the (optionally) pinned structure used for comparisons |
user |
JSON object | user information about the caller if available |
domain |
string | domain name from the originating Design Hub domain |
settings |
JSON object | key-value pair of configured plugin settings, where keys will match configured the settings label and values will match selected setting values |
Response content-type : application/json
Response body : a JSON object including the following properties:
Name | Type | Required | Description |
---|---|---|---|
client |
JSON object | yes | any data structure to be linked to the plugin template. Please see the tutorial below. |
report |
JSON object | no | A list of key-value pairs denoting the results in an easily filterable / sortable fashion. |
Templates provide a rich option set for realtime plugins so there's a dedicated page describing the available options and components made available through the application. Be sure to check out the examples below as well!
variable interpolation
iteration and conditional blocks
styling
<diff>
<larger>
<smaller>
<pager>
[structure]
<threedee>
<protein>
<ligand>
For details and examples - read more in the template guide.
First, create a services directory to store all your plugins and add it to docker-compose.yml
as the /services mount
version: '2'
services:
design-hub:
image: hub.chemaxon.com/cxn-docker-release/chemaxon/dh:latest
restart: always
ports:
- "8888:8888"
volumes:
- "/data/config.json:/config/config.json:ro"
- "/data/services/:/services"
- "/data/license/:/license:ro"
Next, in this directory, create a new npm module to keep track of your plugins and their dependencies and to ensure others using this code have an easy time with it.
user:/data/services$ npm init If you follow the prompts, you’ll get a new package.json file, which describes the plugins. Later, this file can be used to upgrade dependencies - npm outdated and npm update .
More importantly, when you migrate plugins from this development environment to your production server, you can easily install all dependencies - some of which may be OS dependent - with npm install
, just by copying your plugin file and package.json
.