Follow

Getting Started with App publishing

 

Domino’s app publishing feature allows data scientists to easily publish analytical web-based applications and interactive dashboards, enabling seamless data and information-sharing with even non-technical team members or stakeholders.

Overview

With Domino, you can integrate tools like Flask or Shiny to create analytical tools that facilitate “what-if” scenario exploration, the results of which can then be used as the basis for business decisions.

For example, a data scientist may use Shiny to develop an analytical app that is intended to illustrate the results of a financial analysis conducted in R. This app might provide a UI that enables the user to change any number of variables (time frame, dollar amounts, interest rates, etc) using intuitive graphic tools. This app can then be shared with and used by an entire department.

Project requirements

Structurally, a project that includes a published app looks just like any other Domino project, with one exception: the bootstrap file.

This bootstrap file is the key to the entire app publishing process. If you’ve included code for an app in your project but did not include the bootstrap file, your app will not publish. In order for your app to publish, the bootstrap file must be named app.sh and must be present in the root directory of your project.

Your app.sh file will start a run which instructs a host machine to start, listen on port 8888, and bind to host 0.0.0.0. The file’s contents will generally be straightforward. For a Shiny app, the contents of the file may look like this:

R -e 'shiny::runApp("./", port=8888, host="0.0.0.0")'

If you are publishing a Flask app, it may look like this instead:

#!/usr/bin/env bash
export FLASK_APP=app.py
export FLASK_DEBUG=1
python -m flask run --host=0.0.0.0 --port=8888

If there is no app.sh file already present in your project’s root directory, create one and upload it before continuing.

Note: The above enables debug mode on the server.  This should not be used in production. For more information on debugging and error handling check the official Flask resource.

Examples

Two of the most common application frameworks used by Domino customers are Shiny and Flask. However, Domino is not limited to these two frameworks, and can publish apps created in others as well.

Shiny apps and R

Shiny is a framework for quickly building interactive web applications based on analyses conducted in R. Domino allows you to include Shiny apps in your projects. For more information on Shiny, visit http://shiny.rstudio.com/.  

A Shiny app can consist of a single file, though more complex apps will naturally have more. The following code block shows an example of a simple Shiny app. You can explore this project for yourself here: https://trial.dominodatalab.com/u/earino/shiny_app.

app.R example:

server <- function(input, output) {
output$distPlot <- renderPlot({
hist(rnorm(input$obs), col = 'darkgray', border = 'white')})
}

ui <- fluidPage(
sidebarLayout(
sidebarPanel(
sliderInput("obs", "Number of observations:", min = 10, max = 500, value = 100)
),
mainPanel(plotOutput("distPlot"))
)
)
shinyApp(ui = ui, server = server)
 

All files containing app code should also be placed in your project’s root directory, alongside the app.sh file.

Flask apps and Python

Flask is a microframework for Python that can be used for developing web apps. Domino allows you to include Flask apps in your projects. For more information on Flask, visit http://flask.pocoo.org/.

A Flask app can consist of a single file, though more complex apps will naturally have more. The following code block shows an example of a sample Flask app. You can explore this project for yourself here: https://trial.dominodatalab.com/u/earino/flask_app.

app.py example:

from flask import Flask, url_for, redirect
class ReverseProxied(object):
  def __init__(self, app):
      self.app = app
  def __call__(self, environ, start_response):
      script_name = environ.get('HTTP_X_SCRIPT_NAME', '')
      if script_name:
          environ['SCRIPT_NAME'] = script_name
          path_info = environ['PATH_INFO']
          if path_info.startswith(script_name):
              environ['PATH_INFO'] = path_info[len(script_name):]
      return self.app(environ, start_response)

app = Flask(__name__)
app.wsgi_app = ReverseProxied(app.wsgi_app)

@app.route('/') def index_page(): msg = "Domino apps and notebooks run within an iframe. The location you see in your browser above (containing 'embeddedNotebook') is a link to Domino's web frontend that generates the iframe with the blue Domino pullout on the right. Changing that URL always results in 404 as the new route doesn't exist in Domino's web application." + \ "If you examine the source of the page, you will see that the iframe points to a URL containing 'r/notebookSession'. This URL leads directly to your application." + \ "Any navigation within your Flask app while in an iframe (with the blue Domino pullout panel) will not result in a change of your browser's address." + \ "(*) If you want to test direct access, you need to get the 'r/notebookSession' URL from the source and paste it into your browser's address bar." + \ "The links below will work either when you click them (navigation within the iframe, check the page source), or if you append the component ('another_page', 'redirect_test_fail', etc) to the URL after you did (*) above." + \ "A call to flask's url_for('another_page') returns " + url_for('another_page') + " (which has the 'r/notebookSession' component)." + \ "A link to a redirect 'redirect_test' which then goes to url_for('another_page'): " + url_for('redirect_test') + "." return msg
@app.route('/redirect_test') def redirect_test(): return redirect( url_for('another_page') )
@app.route('/another_page') def another_page(): msg = "You made it with redirect( url_for('another_page') )." + \ "A call to flask's url_for('index_page') returns " + url_for('index_page') + "." return msg

 

A general note about @app.route Flask decorators: A route decorator allows you to specify a relative URL route along with a defined function and a return of a partial URL. More advanced usage is possible, such as variable insertion e.g. insert a UID or other state info into the route:

@app.route('/user/id/')

General info on this subject is available here. In particular, if you are using base templates which are then inherited by other templates, you may need to explicitly reference your desired routing in those child templates.

In the example shown above, the app.route called "/redirect_test" calls its function, which then calls "url_for" yet another app.route definition, whose definition is shown next.

 

Publishing your app

Once your app has been coded and uploaded to your project’s files, and your app.sh file has been included in the project, you are ready to publish your app.

To publish your app, go to the left-hand sidebar in your browser and click Publish.

The Publish page should now be visible in your browser. Click the App tab.Your screen should now look something like this.

 

 

Click the 'Publish' button to publish your app.

Domino will run your app.sh file, start the server and connect you directly with your app. Your app will be accessible from the link Domino provides in the App tab on the Publish page. This link can be copied and shared, and will always follow the naming convention of http://HOST/USER/PROJECT/APP. For example, http://dominodatalab.com/spencerfleury/weather-machine/app would be a properly-formatted link to a published app.

Domino supports the publication of one app per project.

 


This is an example of a published Shiny app. It can be used by anyone with access to the project.

Was this article helpful?
1 out of 1 found this helpful

Comments