Python

Some things to take into account before deploying:

  • When you run your app locally, everything happens in the same Python session. When you deploy your app, the deployment server may use multiple Python sessions (workers) to process the requests. So, make sure that information that must persist between events is stored in the submission data or is cached.
  • Note that deployment environments may reuse Python instances to respond to requests, potentially from multiple users, faster. Therefore, do not use constructs that rely on objects being deleted and recreated between requests.
  • It is recommended to fix your dependencies to specific versions to enforce that the exact same versions are installed when a new Python environment is created on the deployment server. This ensures your deployed app runs with tested dependencies and reduces the risk of error or incorrect results.

Deployment process

Deployment of web apps created with Simian GUI generally consists of the following steps:

  1. Prepare the environment for the deployment of a new web app.
  2. Add simian-gui to your dependencies to ensure it will be available in the deployed Python environment.
    • To install from our PyPi server use the pip option --extra-index-url https://pypiserver.monkeyproofsolutions.nl/simple/
    • For testing with the Ball Thrower example, add simian-examples to the dependencies of your deployed Python environment.
  3. Ensure that requests to the deployed code are going to the entrypoint module. (Examples below)
  4. The output from the entrypoint module needs to be returned as a response (with status code 200). In case of an error in the backend, the output contains an 'error' field with a message that will be shown in the GUI (see the Ball Thrower for an example).
  5. Deploy the web app code to the deployment environment.
  6. Configure your Simian Portal to add a link to the deployed web app for the users. This is documented in the Simian Portal Administration Guide available from the Simian Web apps documentation website.

The files that need to be deployed on the server are:

  • Web app definition file(s)
  • Model/back-end. (Alternatively API calls can be used to connect with a model on a different server.)
  • Deployment target specific entry_point_deploy wrapper function. (Examples below)
    • To connect to your own web app, replace the "simian.examples.ballthrower" name with its fully qualified module name.

Since there is no standard method for deploying Python code, a number of potential methods are discussed in the following sections:

Other deployment targets should also be possible, but they will require their own version of what is described below.

To test whether the deployed web apps work, send a POST request with json body ["config", {}, {}] to the deployment host and port. You should get a response with a stringified json dictionary containing a session_id and some other fields.

Azure Functions

GUIs created with Simian GUI can be deployed as Azure functions:

  1. Create an Azure Functions project.

    Include simian-gui (and optionally simian-examples) in the Azure Functions requirements file to ensure that the required modules for Simian are installed in the Azure environment.

  2. Put all the necessary files as described above in the project folder.

  3. In the Azure Functions v2 programming model's function_app.py file, the Azure Functions HttpRequests need to be processed and Responses need to be created. See the example code below on how to make Azure Functions communicate with Simian GUI. For your own GUIs ensure that the fully qualified name of your own GUI is used.

    To ensure all Simian GUI and GUI definition files can be found and used they need to be on the Python path.

  4. Publish the project on Azure and deploy to the Function App.

# Use back-end type `python_azure_functions_v2` in the portal configuration.
import json
import azure.functions as func
from simian.entrypoint import entry_point_deploy

app = func.FunctionApp(http_auth_level=func.AuthLevel.ANONYMOUS)

@app.route(route="httpTrigger")
def httpTrigger(req: func.HttpRequest) -> func.HttpResponse:
    request_data = req.get_json()
    response = entry_point_deploy("simian.examples.ballthrower", request_data)

    return func.HttpResponse(json.dumps(response), status_code=200)

ownR

GUIs created with Simian GUI can be deployed as ownR applications:

  1. Create a new ownR application as documented on the Functional Analytics wiki (account required).

  2. Put the necessary files as described above into the repository of the ownR application.

    Ensure the requirements.txt file of Simian GUI is on the root level and add simian-gui (and optionally simian-examples) to it. This will ensure that ownR can use it to install the required modules in the Python environment.

  3. ownR requires a module to exist at the root level that has the same name as the application. In this module import Simian GUI's entrypoint module and route the requests from the ownR environment to Simian GUI's entry_point_deploy function as illustrated below. For your own GUIs ensure that the fully qualified name of your own GUI is used.

    To ensure all Simian GUI and GUI definition files can be found and used they need to be on the Python path.

  4. Commit and push the changes to the repository. This will trigger a rebuild of the application and your changes to become available.

# Use back-end type `python_ownr` in the portal configuration.

from simian.entrypoint import entry_point_deploy

def entry_point(operation: str, meta_data: dict, payload_in: dict) -> dict:
    """Route the request to the entrypoint module."""
    return entry_point_deploy(
        "simian.examples.ballthrower",
        operation=operation,
        meta_data=meta_data,
        payload_in=payload_in
    )

FastAPI - uvicorn

GUIs created with Simian GUI can be deployed with FastAPI and uvicorn.

  1. Install simian-gui, fastapi, and uvicorn in your Python environment.

  2. Put all the necessary files as described above in a folder.

  3. Create a fastapi_deploy.py file as shown below. For your own GUIs ensure that the fully qualified name of your own GUI is used.

  4. You can use the procedure as described on the uvicorn quickstart page to run your app.
    Hosting the app with multiple workers is supported with gunicorn.

# Use back-end type `python_fastapi` in the portal configuration.
from fastapi import Body, FastAPI
from fastapi.responses import JSONResponse
from simian.entrypoint import entry_point_deploy

app = FastAPI()

@app.post("/apps/ballthrower", response_class=JSONResponse)
def route_app_requests(request_data: list = Body()) -> dict:
    """Route requests to ballthrower GUI and return the response."""
    return entry_point_deploy("simian.examples.ballthrower", request_data)

Flask

GUIs created with Simian GUI can be deployed with Flask. Note that Flask is not recommended to be used for production.

  1. Install Flask in your Python environment.

  2. Put all the necessary files as described above in a folder.

  3. Create a flask_hosting.py file as shown below. For your own GUIs modify the secret key (or store it elsewhere) and ensure that the fully qualified name of your own GUI is used.

  4. You can use the procedure as described on the Flask website to run Flask.

# Use back-end type `python_flask_v2` in the portal configuration.
from flask import Flask, request
from simian.entrypoint import entry_point_deploy


def create_app() -> Flask:
    """Create Flask App for hosting a webGUI."""
    # create and configure the app
    app = Flask(__name__)

    # Store secret key elsewhere.
    app.secret_key = b'_8#h3S"T7U9z\n\xec]/'

    @app.route('/apps/ballthrower', methods=('POST', ))
    def route_app_requests() -> dict:
        return entry_point_deploy("simian.examples.ballthrower", request.data)

    return app