Understanding Back End Code

The custom_data folder contains all data required by the optiSLang project as well as custom Python scripts that can be triggered from the front end. Each script must contain a top-level function named app that takes arguments passed from the front end. A script may return an object containing values that can be used in the calling function on the front-end side.

The first use case is generic Python script execution with the /python_command request. This is useful to parse and fetch information from the wizard’s custom_data directory.

Example 2: First Use Case

def app(n):
    f0, f1 = 0, 1
    seq = [f0, f1]
    for i in range(2, n):
        seq.append(seq[i-1] + seq[i-2]) 
    return {"fibonacci_sequence": seq}

The second use case is starting the optiSLang project with the /start_project request. The Python script must configure and start the optiSLang project in batch mode. When the server runs the script, it provides listener_id and listener_port as global variables. These must be passed as options to the optiSLang batch command so the server is notified when the project has been started successfully.

Example 3: Second Use Case

import subprocess
import os
from socket import getfqdn, gethostbyname_ex
 
def app(project_path, remote_location, settings):
 
    # determine optislang executable
    if os.name == "posix":
        cmd = os.path.join(optislang_home, "optislang")
    else:
        cmd = os.path.join(optislang_home, "optislang.com")
 
    # determine host addresses this machine can be reached on
    host_addresses = gethostbyname_ex(getfqdn())[2]
 
    # assemble optiSLang start arguments
    cmd_argv = [
            cmd,
            project_path,
            "-b",
            "--force",
            "--restore",
            "--reset",
            "--enable-tcp-server",
            "--dump-project-state=../project_state.json",
            "--shutdown-on-finished"
            ]
 
    cmd_argv.append("--register-multi-tcp-listeners")
 
    for host_address in host_addresses:
        cmd_argv.append("{}:{}+{}".format(host_address, listener_port, listener_id))
 
    # create log files containing optiSLang stderr/stdout output
    std_out_filename = "stdout.txt"
    std_err_filename = "stderr.txt"
 
    std_out_file_path = os.path.join(os.path.dirname(project_path), 
    std_out_filename)
    std_err_file_path = os.path.join(os.path.dirname(project_path), 
    std_err_filename)
 
    # Run optiSLang
    with open(std_out_file_path,"wb") as out, open(std_err_file_path,"wb") as err:
        subprocess.Popen(cmd_argv, stdout=out, stderr=err,
                         cwd=os.path.dirname(project_path))
 
    return {
        'original_working_dir': os.path.dirname(project_path),
        'log_file': std_out_filename,
        'error_log_file': std_err_filename
    }

This example script executes optiSLang in batch mode directly on the machine where optiSLang Web Service is running. Many other execution scenarios are possible, including using in-house queuing systems or submission to compute nodes using SSH. The additional --register-multi-tcp-listeners command line argument tells optiSLang to report back to optiSLang Web Service once it has started on any machine.

The values in the returned object are optional. See Project Starter Scripts for more information on return values.