Blog

Automating a Tableau Prep Flow

Ever used Tableau Prep? Tableau Prep is a brand new application as part of the Tableau Platform built to help you run light and heavy ETL (data transformations) so that you can more easily wrangle your data.  Essentially, Tableau Prep lets you transform, clean, join, blend, pivot, alter and update your data in a way that makes is it MUCH easier than it ever has.

The ability for you to run a Tableau Prep Flow automatically can be very critical to making this a stable application that you use as part of your production application set. Leveraging this tool is something that you will find valuable as you go forward in your analytics journey. This step by step guide will help you break down just how to run this Prep Flow.

Step 1 – Create a Prep Flow

This can only be done with Tableau Prep. There are a ton of resources online to help you learn how to use Tableau Prep.  Just one of them is here.

Here is an example of a Tableau Prep Flow:

p1

Step 2 – Find the CLI Bat File

You will need to run the CLI (Command Line Interface) application to kick things off. You can find it in the program file folder typically:

Program Files\Tableau\Tableau Prep 2018.3\scripts

Step 3 – Run the Flow Using This Command

We can now run our flow with a simple command line execution.

tableau-prep-cli -t “C:\\Healthy – Condition List.tfl

For more information about what you can do with the command line, follow this link

Step 4 – Schedule It!

You can use a variety of tools that will work to schedule this bat file. My favorite is Windows Task scheduler. You can go to a basic application server and run the .bat file at a specified time.  Here is an example of creating that schedule using Task Scheduler

I have used this in many occasions at customer sites. This has proved very valuable when trying to automate data preparation applications.

I hope this post is useful for you and please feel free to leave a comment at any point and ask a question or leave a general comment!

Building the Ticket Tape Extension

With the advent of the new extensions API, we are seeing some exciting new ways to use tableau and the data that use in your dashboards.  One of things that I have heard over and over again is that we’d like to see new interesting ways to display data and information.  The extensions API give us exciting new ways to use that data in our dashboards.  In this post, I will show you how to create moving ticker type like functionality for use in your Tableau dashboard.  The end result should look something like this:

image05

Step 1

Create your typical .trex file.  If you are unfamiliar with this, see documentation by Tableau for additional details

Step 2

Build your index file that enables the rest of your application.  This should look something like this:

image1

In this case I have nothing but an unsorted list to start out with.  We will programmatically build additional list items here.   These will be data points that we will later capture with our JavaScript.

Step 3

Use this handy dandy css to make the fonts look appealing.  The CSS file is something helps out overall application look and feel more professional.  we have a number of different ways we shape our containers.  You can check it out here.

Step 4

Build out the JavaScript to enable the functionality.  In this file the first thing we do is initialize out extension:

image1.5

The next thing that we want to do I run our core code.  That is the populateDataTable() function listed here.  This will begin the loop to get the data from the sheet we are interested.

image3

The next piece to this is that we want to populate a list.  Once we have the list populated we can start the workflow.

image2

This will then create our list items from the data that we recently received.  We will then call the function that puts this list in motion in a scrolling manner.  To find the code for this please see this file on github.

Step 5

Run the code and see if it works!  Let’s now see this in action in or dashboard.  The final output of all of the code is listed on github if you’d like to take it down, mix it up and make it your own!  As always, please visit the Tableau Professional Services page to find many people who can help you with your extension based projects.

 

 

Deploying a Tableau Extension for External use using Python Flask Web Framework

With the release of Tableau 2018.2, the extensions API has already made a big splash with all of its fantastic new capability. Check out the Tableau extensions gallery to get a glimpse of a few of the awesome applications that have already been created. However, the real intention of this feature is give our community even further flexibility in what they can do with the Tableau Dashboard. And with great power, comes great learning opportunity. This post is designed to give you the ability see first-hand how you design, build and publish an extension of your own, so that YOU can also help build amazing extension for the Tableau community.

Initialization

Stand up a VM that can be made accessible by the public internet. These days it is extremely efficient and inexpensive to have web server in the cloud. In this tutorial I will be using a google cloud Compute Instance but you can use anything you want, AWS, Azure or even a VM in your own apartment (as long as you make it public). I will doing a part 2 on creating a server less architecture of this application with Google cloud in the future.

Step 1- Build a simple flask application

Flask is a great web framework that enables your python code to act as web pages. By doing this you can effectively run Python code on data that you’ve requested as part of an Ajax call or other API call. I will quickly walk through building a simple Flask application.

The first thing to do once you’ve set up your VM is to install flask:

PIP install flask

Next, you’ll most likely have a few dependencies packages that need to get installed as well. In my case, I was requiring. A great way to do this is to create a requirements file that installs all of your applications dependencies quickly and efficiently. For this application we need certain python libraries such as alpha_vantage, pandas, and numpy. Here is an example of what my requirements.txt looks like:

Flask==1.0.2
google-cloud-datastore==1.4.0
google-cloud-storage==1.7.0
google-cloud-logging==1.4.0
google-cloud-error_reporting==0.29.0
gunicorn==19.7.1
oauth2client==4.1.2
Flask-SQLAlchemy==2.3.2
PyMySQL==0.8.0
Flask-PyMongo==0.5.1
PyMongo==3.6.0
six==1.11.0
requests[security]==2.18.4
honcho==1.0.1
psq==0.7.0
alpha-vantage==2.1.0
psycopg2==2.7.5
pandas==0.23.4
tinynumpy==1.2.1

you can install these like so:

pip install -r requirements.txt

Then you are ready to write your initial flask application.  Mine looks something like this:


from flask import Flask, render_template, request, jsonify
from Get_Data import get_data, build_connection, run_sql
import random
import string
from OpenSSL import SSL

#First, create a flask class object we use to run our program
app = Flask(__name__)

##This section defiles my SSL certs so that I correctlty can run HTTPS on my site.

context = SSL.Context(SSL.SSLv23_METHOD)
cer = 'fireanalytics-dev.crt'
key = 'testcert.key'


#set the route to the first place you go. So when I go to the site http://0.0.0.0:500 I will render my Index.html template
@app.route('/')
def index():
return render_template('Index.html')

### This is another page in my web application. it will get used when some clicks the button in my application.


@app.route('/_add_numbers')
def add_numbers():
a = request.args.get('a', 0, type=str)
hashvalue = ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(6))
#r = test_1()
#print r
data = get_data(a, hashvalue)
data = [tuple(x) for x in data.to_records(index=True)]
cur, conn = build_connection();
run_sql(cur, conn, data);
print jsonify(result=hashvalue)
return jsonify(result=hashvalue)


if __name__=="__main__":
context = (cer,key)
app.run(host='0.0.0.0', port=5000, ssl_context=context)
# app.run()
# app.run(host='0.0.0.0', port=5000)

Now you have the basic framework of the application, and now we’ll need to implement the HTML and JavaScript to our application and user interface. Flask will look for template files when we call the Render template function as we do in return render_template(‘Index.html’) So you will need to place this in a templates directory in the application folder(see flask documentation for this: http://flask.pocoo.org/docs/1.0/quickstart/.

Here is what our Index.html file looks like. It will be first place to render your extension.

pic1

Here you’ll notice a few things. We are using sources from both javascriptButtons.js and tableau-extensions-1.latest.js. The first is a custom .js file that has the logic of what to do when a button gets pushed. The second, is the extensions library that allows us to interact with the objects in the dashboard. Tableau has done a fantastic job with explaining how this all works here:

https://tableau.github.io/extensions-api/docs/index.html

To see what our custom .js file does in specific, take a look at this:


// load the page first. We need to wait for the entire page to load first then we can start to interact with it.
window.onload = function() {
// load tableau extension
tableau.extensions.initializeAsync()
//Get the button
var button = document.getElementById('button1')
// 2. Append somewhere
var body = document.getElementsByTagName("body")[0];
body.appendChild(button);
// 3. Add event handler
button.addEventListener ("click", function() {
// Do some visual FX things to wait for things to load up.
$('#spinner').show();
$('#sam').hide();

//get request to page where python is located//
$.getJSON('http://localhost:5000/_add_numbers', {
// Gets the inputted value
a: $('input[name="a"]').val()
}, function(data) {
// If succesful executes these commands
$('#spinner').hide();
$("#sam").text(data.result);
const param = tableau.extensions.dashboardContent.dashboard.getParametersAsync().then (function (sum) {
const sam = sum[0].changeValueAsync(data.result)
});
// show the value at this piont in the juncture
$('#sam').show();
});
return false;
});
}

So as you can see, there are three primary components to our extension.  We have:

1.     A flask application(written in python) that directs us to certain pages
2.     We have an HTML file that displays our application
3.     We have a JS file allows us to interact with the HTML.

Step 2 Build the components of the extensions API necessary

Tableau’s extension API is a wonderful way to embed flexibility into your dashboards that once was never even possible. Tableau’s Extension API uses a JavaScript Library to get gain access to the dashboard’s object model then perform actions on these objects. The feature is very well documented here and this tutorial touch a small part of the overall capability.
You should have noticed in the javascriptButtons file that there were a few places were the extensions API was used. They were:

// load tableau extension
tableau.extensions.initializeAsync()

AND

const param = tableau.extensions.dashboardContent.dashboard.getParametersAsync().then (function (sum) {
const sam = sum[0].changeValueAsync(data.result)

The first initializes our code to let it know that we’d like to utilize the extensions API attributes. This will ALWAYS need to be there in any extensions API application you develop. The second piece, simply looks at which parameter is present in the dashboard and then changes the value. You can see the details on the documentation that’s linked above.

Step 3 Enable for SSL

The extension API requires a very secure environment. This means that in order to host your extension somewhere you need to run your entire application over HTTPS. To do this you’ll need to get an SSL certificate to authorize your domain to run over HTTPS. SSL is means to encrypt all of the traffic running from your dashboard to extensions. It’s important to keep your data safe even when your extension is hosted inside your firewall.

Here are the steps I took to get my SSL working on my VM.

  1. Create s CSR and private key using openSSL. Make sure to use the FQDN that the internet recognizes is your computer.
  2. Send this CSR to CA like go daddy, comodo or something else. You can potentially do this for free.
  3. They will send you back a .CRT file you can use to have the public internet trust your server. This way you can use HTTPS as people access your server.
  4. Finally, when you start your web server make sure to include your newly gotten .CRT file and the private key you initially created in step 1.

I will demonstrate how it this was done in our application. All we do is bind these .CRT and .key files when we start our webserver. Flask will automatically recognize this as HTTPS:

from OpenSSL import SSL ##we make sure to import the necessary Library
context = SSL.Context(SSL.SSLv23_METHOD) # we initialize the context
cer = 'fireanalytics-dev.crt' # we point to where our .crt file is located
key = 'testcert.key' #we point to where our .key file is located

Then, we need to feed these as options when we start the web server, like this:

if __name__=="__main__":
context = (cer,key)
app.run(host='0.0.0.0', port=5000, ssl_context=context)

Step 4 Build the rest of the application

At this point you have been given the main components necessary to host your application online. The rest of our application will do the following:

1.    Make a call to an API to get data
2.    Transform the data how we’d like it.
3.    Update the database to reflect new API call data
4.    Pass a token into the database that makes those records unique.
5.    Update the parameter to only view those records that we want.

You can get the entire application here at GITHUB if you’re interested!

Step 5 Test it out!

  1. Go to GITHUB and download the application files. Since you’ll be running it locally, you won’t need SSL for this extension.
  2. Update the necessary areas of the code for your environment.
  3. Start your web server by something like >> python myflask.py
  4. Use the .trex in your workbook. (Make sure that the .trex file points to your web server so it render the page correctly!

It has been please learning all of this information and I hope you find this walk-through useful to you.

Until next time!

Unpivot Data in Tableau Prep

Tableau Prep is the fantastic new product from Tableau. It has already been a success in numerous customers that I’ve visited. One powerful thing particular that is possible is the ability to UNPIVOT data. For our purposes this means taking rows of data and making them columns of data.

For example:

1

You’d like to make it look like this:

2

There are many reasons someone would want to do this but for our purposes it made it much easier to visual how Actual Value was comparing to Budget Value within Tableau.
So now that we understand why we’d like to do this let’s talk about how to actually do it!

Step 1 – Add a step and create a calculated field

This will look at each record with this value and populates the value in a new column.

3

Step 2 – Do this for each Metric or Row

In this case, we’d create 3 more calculated fields for Budget, Goal, and plan.
Step 3 – Aggregate

We then need to aggregate the new calculated fields by the dimensions we are NOT pivoting, in this case Country and Region. The aggregation will simply skip over the null values and get us the values that we want.

4

Step 4 – Create a hyper file and connect with Tableau Desktop

As you can see we now have a column called actual value and a column called Goal Value. This now exactly what we were interested in getting.

5

Step 5 – Build a cool visualization with Tableau

6

And there you have it. This is an excellent way to visualize this newly created data. I have seen this question many times and this is a great way to help you do this. For more questions like and additional services, please reach out our Tableau support group for details.