Skip to content

Publishing the workflow as an app

You can make your workflow available to other users by publishing it as a web app to a shared workspace in AppsHub.

  1. Go into your workflow's folder in the Explorer sidebar.
  2. Generate the stock app UI for your workflow: from the menu in Explorer, select Workflow app Reset to stock app UI v10.
  3. Publish the worfklow: from the same menu, select Workflow app Publish to AppsHub....

The last command opens the publish dialog, where you can select the workspace where your app will be available and set up the app's appearance.

Once you publish the app, its description and thumbnail are saved to APP.md and APP.png in the workflow folder. The publication dialog finds those files when they exist, so it will load the description and thumbnail from them if you decide to re-publish the app.

To test your app, select Personal in the dropdown - then only you will see the published app in AppsHub. If you select another workspace, your app will be available to the users who have access to that workspace. User access to workspaces is controlled by administrator.

Public workspace and publish permissions

Admins can set up publishing in such a way that there is a single shared workspace (commonly named Public), where everyone can publish and run apps.

In other cases, the dropdown only displays the workspaces where you have the "Publish apps" permission enabled by administrator.

Optionally, you can also publish your source workflow with the app. If you select "Allow other users to copy workflows from your app" in the publish dialog, anyone with access to your app will be able to obtain a copy of the app's workflow. They can then edit, configure, and run the copied workflow. This is safe to your app because changes made by other users apply only to their personal copies of the workflow, which no longer have any connections with your app.

Stock app UI

The stock app UI is a simple generic web app UI available in pSeven Enterprise by default. It provides for entering parameters, uploading input files, running the app, viewing and downloading the run log, viewing the results, downloading output files and so on.

Preview the app UI

While preparing to publish a workflow, you can preview its app UI: click on the workflow edit toolbar or select the Open app UI command from the menu on that toolbar.

The stock app UI consists of the main page, where the user configures a new run, and a page for each run, which displays the run progress and results.

Main page:

  • The main page header displays the app name and the stock UI version. The Run launch button is on the right; when you start a new run, the UI reloads to display the run page.
  • Below the header is the app description you've added when publishing.
  • The Parameters area displays all the workflow input parameters.
  • The Files area is where you can upload the input files, if they are required to run the app.

Run page:

  • The run page header displays the app name, UI version, and the run state.
  • The app description follows below the header.
  • The Parameters area displays the input parameter values you've set for this run.
  • The Results area displays the outputs of the app's workflow.
  • The Report area displays the run report, if your workflow provides one.

The AppsHub sidebar on the left complements the stock app UI:

  • The Runs tab lets you navigate and manage the app's runs.
  • In the Logs tab, you can view and download the run logs.
  • The Files tab displays the files created by the workflow (the result files) and lets you download them.

Result files

By default, all files created by the app during a run are displayed in the Files tab in the left sidebar, where the app users can download any file.

To block access to certain files from your app, set the file access rules prior to publishing the app:

  1. Go to Studio and open the source workflow folder in the Explorer sidebar.
  2. From the in Explorer, select Workflow app App result files... This command opens the file access list for viewing. The app can only access the files included into that list. All other files will be inaccessible in the app UI and will be hidden from the Files tab.
  3. Click Edit at the bottom of the viewer and edit the rules. For example, to deny access to all files except result.dat, replace the default rules with the following:

    # This file will be available in the app.
    result.dat
    # These files are required by the stock app UI.
    # Do not remove them from the access list, otherwise the UI won't load.
    .ui/
    REPORT.html
    @run.log
    
    # Any other file not included into this list will be inaccessible to the app.
    

    For details about the rules syntax, see the comments in the default access list.

  4. Click Save to close the dialog, then publish your app.

Note that the rules you've set up will apply only to the app version you're publishing or updating. If you support multiple versions of one app, set up the file access rules for each version.

Run report

The stock app UI can display and update a report while the app runs. To implement such a report, your workflow should periodically update the REPORT.html file in the run directory root. The stock app UI repeatedly reloads that REPORT.html and displays its contents in the Report area of the run page. If your workflow writes the report to another file, you can edit the report file path variable in the stock app UI so it loads that file.

Workflows contain an empty REPORT.html file by default. If you are not going to use it, you can safely delete REPORT.html or leave it empty - in either case, the Report area will be hidden on the app's run page.

To update REPORT.html, you can use a Python script block. In your script, use api.rundir to compose the report path:

# Work with REPORT.html in the current run directory root.
import api
report = api.rundir / 'REPORT.html'

# Generate the report contents.
report_data = """<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
  </head>
  <body>
    <p>Report text and other contents.</p>
  </body>
</html>
"""

# Write the report contents.
report.write_text(report_data, encoding='utf-8')

To load your report from a non-default file, specify RUN_REPORT_PATH in the run page script, .ui/run.js.

  1. In Studio, open your workflow folder in the Explorer sidebar. Use the Ctrl+Alt+H hotkey to show the hidden stock app UI files.
  2. Edit run.js in the hidden .ui folder: change RUN_REPORT_PATH to your custom report file path, relative to the run directory root. For example, to load the interactive report created by a Design space exploration block:

    // const RUN_REPORT_PATH = "REPORT.html";
    const RUN_REPORT_PATH = "🏠.Design space exploration/Designs.html";
    
  3. Publish the app with your UI edits.

Working with app versions

AppsHub allows multiple versions of a workflow to be published within a single app. Accordingly, each app in AppsHub can have one or more versions, with a separate workflow for each version. It is also possible to modify a previously published version by replacing its workflow with an updated one - to track such updates, each app version also has a revision number. For example: "ToySolver v2r5" is the fifth revision of the second version of the ToySolver app.

When using your app from the AppsHub web interface or through the REST API, app users can specify the desired app version. This is not required - if they do not specify an app version, they are going to use its default version. You select which version of your app is the default. You can change this selection at any time in your app's settings, or when you publish an update for your app.

AppsHub does not ensure the backward compatibility of your apps

As app developer, you should bear in mind that pSeven Enterprise does not check in any way the compatibility of your app updates with the existing REST clients.

If you designate a different default version, all clients that do not specify the app version get switched automatically to the version you have designated. Such a switch may cause failures in client operation due to incompatibility with the workflow of that app version. When you change the default version selection, you must ensure compatibility with existing app clients.

The same applies to the situation where you publish a new revision of an existing version: you must ensure that the new revision is compatible with the REST clients that specify the version you are updating.

Some typical cases of using app versions:

  • You want to update the app with a new workflow but some of its users (REST clients) can only work with a previously published workflow. In this case, publish the new workflow as a new version of your app. The clients that specify the app version will continue to use that version of the app.
  • You want to update the app and to direct all users and clients to this update by default. In this case, publish the update as a new app version and make the new version default. If the update breaks app compatibility with REST clients, you will be able to revert the default version setting. If you find that the update did not create compatibility issues, and you no longer the backup of the previously default app version, you can delete that version in your app's settings.
  • You want to update a certain version of your app, and you are sure that the update does not break compatibility with the existing REST clients - for example, it contains only bugfixes, or updates the app UI only. In this case, publish the workflow with the existing version number. That version's revision number will be automatically incremented by one.

The workflow publish dialog also allows you to publish the workflow as a previously deleted version of the app, thus restoring that app version. In this case, the revision numbering does not reset - for example, if you delete app v2r5 and restore afterwards, it becomes v2r6.

On the app info page, which opens by clicking the app thumbnail in AppsHub, app users can work with different app versions:

  • Select the app version. Most commands on the page work with the currently selected version.
  • Open the selected app version.
  • View run results of the selected version.
  • Get the workflow of the selected app version, if you have allowed this when publishing the workflow.
  • Get the default API URL, which points to the final revision of the app version that you have designated as the default version.
  • Get the API URL of the selected version, which always points to the final revision of this specific version.

You, as app developer, can perform a number of additional operations on the app info page:

  • Designate the selected app version as the default one.
  • Delete the selected app version.
  • Entirely delete the app and all its versions.

Custom app UI

You can customize the app UI in your workflow, add features to the stock app UI or replace it entirely with your own, tailored to a specific app. Your custom app UI implementation must contain the @app.html and @run.html files - the main app page and the run page. They will replace the stock UI pages but the AppsHub sidebar with its common functions will stay. Therefore run management, run logs, file download in your custom app UI will work the same as in the stock app UI - there is no need to re-implement them.

  • The @app.html page:
    • Loads once the app user begins setting up a new run - for example, clicks New run in AppsHub.
    • Must get the input parameter values from the user and pass them to the app's workflow on launch.
    • Can access the files that you've loaded into the workflow folder, although only those included into the access list - the same one that sets the rules for the result files. The workflow files are accessible by relative URLs, which are the same as the file paths relative to the workflow folder.
  • The @run.html page:
    • Loads once your UI sends the app launch command to pSeven Enterprise.
    • Must display the run progress and results to the user.
    • Can access the files that your workflow creates in the run folder, provided that you've included those files into the access list. The run files are accessible by relative URLs, which are the same as the file paths relative to the run folder.

To exchange data with the app's workflow - pass the input parameters, get the results - your UI must use the JavaScript API for apps. Using the API is explained in comments in the stock app UI implementation. To generate the stock app UI in your workflow, open its folder in the Explorer sidebar, open the in Explorer, and select Workflow app Reset to stock app UI v10. The stock app UI also serves as a development template for custom UIs.

Most of the stock app UI files are hidden by default. To show them in Explorer, use the Ctrl+Alt+H hotkey.

├── @app.html
├── @run.html
├── @appresults
├── APP.md
├── APP.png
├── REPORT.html
└── .ui
    ├── app.js
    ├── files-form.js
    ├── lib
    │   ├── bootstrap.min.css
    │   ├── marked.esm.min.js
    │   └── vue.esm-browser.prod.min.js
    ├── run.js
    └── style.css
  • @app.html - The main app page, where the user prepares a run. This file is required.
  • @run.html - The run page, the one that displays an ongoing run. This file is required.
  • @appresults - The file access list; required.
  • APP.md, APP.png - The app description and thumbnail; optional.
  • REPORT.html - The run report placeholder. Optional: you can remove this file or use another report file.
  • .ui folder - UI components. Optional; you can place your custom UI components anywhere inside the workflow folder.
    • app.js - The main page script.
    • run.js - The run page script.
    • files-form.js - The component implementing an auto-expanding list of type="file" inputs (for file upload).
    • styles.css - The UI styles.
    • lib - Third-party libraries.

Note before you begin developing your custom app UI:

  • The @app.html, @run.html, @appresults files are required and must be placed to the workflow folder root. You cannot change the names of those files. There are no more requirements for the UI file names and locations.
  • The rules in @appresults must allow access to all files and folders used by your app UI implementation - otherwise the app will be unable to load the UI.
  • The workflow must be set up to copy @run.html and any other file used by the run page UI to the run directory. In AppsHub, the run page UI loads specifically from the run directory, separately for each run. Make sure that in Explorer all of the run page UI files are displayed in white font - the files that are grayed out are not copied to runs.
  • The stock app UI implementation uses Vue.js, which is not a requirement. Feel free to use any UI frameworks you need.

JavaScript API

To interact with the workflow and pSeven Enterprise, your app UI must use the Javacript API for apps, @api.js. Load it in your @app.html and @run.html:

<head>
    <script src="@api.js" defer></script>
</head>

Deferred loading (defer) is required.

Do not call any of the API functions until your UI is done loading.

Once loaded, @api.js adds several pSeven Enterprise functions.

  • Base functions:
  • Parameter editing functions - xSeven.valueeditor methods:
  • Messaging functions - exchange data with an app run in progress; useful only if the app's workflow contains blocks that use the messaging API:

Main functions

xSeven.data()

Get the app or run representation to read and set its parameters.

Parameters: none

Call xSeven.data() from @app.html to get a Promise with AppEntity. Call it from @run.html to get a Promise with RunEntity.

xSeven.run(parameters, files, options)

Launch a new run from the app and go to the run page, or launch in the background.

Parameters:

  • parameters (Parameter[]) The app parameter settings for this run.
  • files (FormData) The files to upload into this run.
  • options ({ navigateToRun: boolean }) Run options.
    • navigateToRun: true (default) - redirect the user to the run page on launch; false - launch the run in the background, stay on the app page

Returns a Promise with RunEntity of the newly created run.

Parameter handling

The AppEntity property parameters is a Parameter[] array, which you present to the user in your UI as a number of input fields. You get new values input by the user, update the parameter values in the array, and finally pass the updated parameters to xSeven.run().

Iterate the array, check which parameters allow inline editing, and which of them require calling the value editor dialog; display their initial values:

// pseudo code, for illustration purposes only!
for (const prm of parameters) {
    if (!xSeven.valueeditor.inlineEditable(prm.value, prm.default, prm.schemas)) {
        // this parameter prohibits inline editing
        <HTMLInputElement of this prm>.setAttribute("readonly", true);
    }
    <HTMLInputElement of this prm>.value = xSeven.valueeditor.inlineDisplay(prm.value);
    <HTMLInputElement of this prm>.addEventListener("change", (event) => {
        prm.value = xSeven.valueeditor.inlineApply(event.target.value, prm.value, prm.default, prm.schemas);
    });
}

For the parameters that prohibit inline editing, use the value editor dialog:

// pseudo code, for illustration purposes only!
newValue = xSeven.valueeditor.edit(prm.value, prm.schemas, prm.default)
if (newValue !== undefined) {  // handle the case when the user cancels editing
    prm.value = newValue;
}
xSeven.valueeditor.edit(value, jsonschemas, defaultValue, readonly, droppable)

Present the value editor modal dialog to the user. To edit an app parameter, pass the value, schemas, and default of that parameter to edit().

Parameters:

  • value (Value) The initial value to display in the dialog. Set it to the current value of the parameter that's being edited (its value).
  • jsonschemas (Schema[]) The value schemas that the user can select in the dialog; the possible data types of this value, from the user's point of view. Set it to the schemas of the parameter being edited (its schemas).
  • defaultValue (Value) (optional) The value's default. Set it to the default value of the parameter being edited (its default).
  • readonly (Boolean) (optional, default: false) Switch the editor to viewer mode: if true, the user can't edit the value.
  • droppable (Boolean) (optional, default: true) If true, the user can unset the parameter they edit (the "Drop value" button in the dialog is enabled). If false, that button is disabled, so only the "Cancel" and "Save" options are available to the user.

Returns a Promise with the Value entered by the user in the dialog; null if the user clicks "Drop value"; undefined if the user clicks "Cancel".

xSeven.valueeditor.preview(value)

Get the short and long text previews of the value to display in input fields or UI tooltips.

Parameters:

  • value (Value or Value[]) The value or the array of those to preview.

Returns a Promise with Preview - or with a Preview[] array, if the value argument is an array.

xSeven.valueeditor.validate(value)

Check that the value contains valid data.

Parameters:

  • value (Value or Value[]) The value or the array of those to validate.

Returns a Promise with ValidationResult - or with a ValidationResult[] array, if the value argument is an array.

xSeven.valueeditor.inlineEditable(value, defaultValue, schemas)

Check if a parameter allows inline editing.

Parameters:

  • value (Value) The current value of the parameter (its value).
  • defaultValue (Value) (optional) The parameter's default (its default).
  • schemas (Schema[]) (optional) The parameter's schemas (its schemas).

Returns a Boolean, true if inline editing is allowed.

xSeven.valueeditor.inlineDisplay(value)

Get the display value (text) of an inline-editable parameter.

  • value (Value) The current value of the parameter (its value).

Returns the string to display.

xSeven.valueeditor.inlineApply(input, value, defaultValue, schemas)

Set an inline-editable parameter to the value entered by user.

Parameters:

  • input (string) The user's input.
  • value (Value) The current value of the parameter (its value).
  • defaultValue (Value) (optional) The parameter's default (its default).
  • schemas (Schema[]) (optional) The parameter's schemas (its schemas).

Returns the new Value.

Messaging

xSeven.pop() and xSeven.push() are the app-side counterparts of the api.message_push() and api.message_pop() methods of the block Python API. Blocks in the app's workflow can exchange messages with the app UI using one or more channels. Each channel is a pair of message queues:

  • workflow-to-app, where blocks push (send) messages, and the UI pops (fetches) them
  • app-to-workflow, where the UI pushes messages, and blocks fetch

The messaging functions are only usable in @run.html and only while the run state is "RUNNING".

xSeven.pop(options)

Get the oldest message from the workflow-to-app queue and remove that message from the queue.

Parameters:

  • options ({ channel: string }) Receiver options.
    • channel (string): the name of the channel to use; you can omit this to use the default unnamed channel

Returns a Promise with the message string, or with null if the channel's workflow-to-app queue is empty at the moment.

xSeven.push(message, options)

Add the message into the app-to-workflow queue.

Parameters:

  • message (string) The message text.
  • options ({ channel: string }) Sender options.
    • channel (string): the name of the channel to use; omit this to use the default unnamed channel

Types

Schema (Object)

JSON schema of a pSeven Enterprise value. Defines the value type, data structure, constraints, and other properties.

Properties:

  • $schema (string or undefined) The JSON dialect for which this schema is developed.
  • $id (string or undefined) The ID of this schema.
  • $ref (string or undefined) Base (parent) schema reference.
  • title (string or undefined) The title of this schema. The app UI commonly uses this title as the name of the value's data type when displaying the value details to the user.
  • definitions (Object or undefined) Inline subschemas to be used in the schema.
  • type (string or undefined) The data type in this schema.
  • properties (Object or undefined) Additional object properties; type-specific key:value pairs.
  • allOf (Schema[] or undefined) Schema composition.
  • oneOf (Schema[] or undefined) Schema composition.
Preview (Object)

String preview of a pSeven Enterprise value.

Properties:

  • long (string) Long preview, suitable for tooltips.
  • short (string) Short preview, for inline use.
ValidationResult (Object)

Value validation result.

Properties:

  • valid (Boolean) The outcome, true if the value is valid.
  • errorMessages (string[]) Validation errors, if any.
Value (Object)

pSeven Enterprise value.

Properties:

  • schema (Schema or undefined) The JSON schema of this value.
  • props (Object or undefined) (reserved) Value properties.
  • data (any or undefined) Full value data.
  • preview (Preview) The preview of this value.
Parameter (Object)

App parameter - a certain named input or output, and its assigned value.

Properties:

  • name (string) The parameter's name.
  • description (string) The parameter's description.
  • schemas (Schema[]) Value schemas accepted by this parameter.
  • value (Value or null) The current value of this parameter.
  • default (Value or null) The parameter's default value.
AppEntity (Object)

App representation.

Properties:

  • id (string) The ID of this app.
  • name (string) The name of this app.
  • description (string) This app's description.
  • parameters (Parameter[]) This app's inputs.
  • results (Parameter[]) This app's outputs.
RunEntity (Object)

App run representation.

Properties:

  • id (string) The ID of this run.
  • name (string) The name of this run.
  • description (string) This run's description.
  • parameters (Parameter[]) The input parameters of this run and their values.
  • results (Parameter[]) The output parameters of this run and their values.
  • state (string or undefined) The current run state.

App URL parameters

To pass parameter values to the UI when the user opens the app, create a link to the main UI page of your app, adding the parameters to the URL query string. The main page scripts can get those parameters from window.location. Thus you can handle the parameters from URL in your UI scripts: set the initial values of parameters on the app page that URL opens, pass the parameter values from URL to xSeven.run(), and so on.

The app UI URL looks like this:

https://{pSeven Enterprise address}/appshub/app/{app ID}/ui?@version={number}

Given an app UI URL with more query string parameters following after the version number (...?@version=5&param1=value1&param2=...), pSeven Enterprise passes all those additional parameters to the app. The names of URL parameters can be any - they are not required to match the names of workflow parameters. In the following example, weight and area are URL parameters:

https://pseven.online/appshub/app/f402cc22395442e2a330812027103bb4/ui?@version=5&weight=12&area=169

You get the values from URL parameters and assign those values to variables in your script:

const queryString = window.location.search;
console.log(queryString); // prints '?weight=12&area=169'

Note that all parameter names and values in URLs must be URL-encoded. For example, if the parameter is named run mode, and its value is mode #N:

.../ui?@version=5&run%20mode=mode%20%23N

The app UI URL is not the same as the app API URL

The app UI URL used to pass parameters to the app is the app's web UI URL for the end users.

The app API URL referenced in the REST API guide is the URL of the programming interface. The API URL is used to access the app REST API endpoints and does not support URL parameters.

Migrating from UI v8 to UI v10

pSeven Enterprise supports the deprecated app UI v8 for compatibility with the apps developed for earlier versions, which use the stock app UI v8 or a custom one based on UI v8. By default, such apps are labeled "deprecated" in AppsHub; admins can also block the use of deprecated apps (1) because it is a security risk. Update the deprecated apps as soon as possible: in future, pSeven Enterprise will stop supporting them.

  1. deprecatedApps in values.yaml

To update an app with the stock app UI v8, reset its source workflow to the stock app UI v10 and re-publish it. When publishing, copy the app description from README.md to the publish dialog - this will save the description to APP.md; UI v10 no longer uses README.md, allowing you to save different descriptions for the workflow and the app. If you support multiple versions of an app, update all versions to UI v10.

Updating a custom app UI from v8 to v10 requires some refactoring - the implementation of UI v10 is different. The key points are listed below. Note that with UI v10 you will no longer have to implement common functions, which were missing in UI v8: logging, file download, run stop command. Those functions are provided by the AppsHub sidebar, which is automatically available in all apps using UI v10.

  • UI v10 no longer uses REST API; it can only use the app JavaScript API.
    • Replace all REST API requests with JavaScript API function calls. To get the workflow parameters and their values, call xSeven.data() once. See Parameter handling for further guidelines.
    • You no longer need the authorization token. The JavaScript API authorizes itself as the app user.
    • Do not sen HTTP or REST requests to pSeven Enterprise. Your app can access pSeven Enterprise only via the JavaScript API.
  • UI v10 requires the separate main page (@app.html) and run page (@run.html).
    • Split your index.html from UI v8 into the @app.html and @run.html parts. See the stock app UI v10 for an example.
    • The UI v10 pages are easier to implement than index.html in UI v8 was. pSeven Enterprise redirects the user to @run.html once you call xSeven.run() in the main page script, so you won't need to implement such transitions. To get the run state, just call xSeven.data() again from the run page script.
  • Several functions that you had to implement in UI v8 are provided to UI v10 by the AppsHub sidebar, for free.
    • The run logs are available in the Logs tab in the sidebar and can be downloaded from there.
    • The result files are available in the Files tab.
    • To interupt a run, there is the Stop button, which appears on mouseover in the Runs tab.
  • The value editor functions, which are available since the early versions of the app JavaScript API, were renamed, but their parameters did not change. Just replace the da.p7.valueeditor.v1.* function names with the xSeven.valueeditor.* names.
  • UI v10 loads into an <iframe> with the sandbox attribute, which applies several restrictions. In particular, your scripts can't access document.cookie and window.top. Note however that the URL query string parameters are available to the UI via window.location - pSeven Enterprise handles this.
  • All your UI files must be included into the file access list (@appresults), otherwise they won't load in your app.
  • The source workflow must be set up to copy @run.html and any other file used by the run page UI to the run directory. In AppsHub, the run page UI loads specifically from the run directory, separately for each run.