How to run Prep Flows on Tableau Server/Online using Tableau REST API

Pietro Gentini
Tableau Server Insights Blog
4 min readMar 10, 2021

--

Starting from version 2020.4.1 the Data Management Add-on is no longer required to publish your flows to Tableau Server or Tableau Online or run flows manually on the web. However you need Tableau Data Management Add-on with Tableau Prep Conductor enabled to run your flows on a schedule o using Rest API (https://help.tableau.com/current/prep/en-us/prep_conductor_overview.htm).

How to run Flows on Tableau Server/Online using Tableau Server Client (Python) without Data Management Add-on

If you have at least a Creator role, you can edit or publish flows on Tableau Server or Tableau Online and run flows manually, only one flow at a time.
With Tableau Data Management you have Tableau Prep Conductor to run flows on a schedule. But you have also the capability to orchestrate your Prep flows execution using Tableau REST APIs.

Install Tableau Server Client (TSC)

In this story we’ll use the Tableau Server Client (TSC), a Python library for the Tableau Server REST API, to achive this.

Documentation and software about TSC are available here:

TSC requires Python 3.5 or later to run and we can install TSC using pip from command line.
This command install (or upgrade) the latest stable version of TSC:

pip install --upgrade tableauserverclient

Authenticate using a Personal Access Token (PAT)

To connect securely to Tableau Server or Tableau Online by Rest APIs, the best practice is to use a Personal Access Token (PAT), avoiding to insert your username and password in the Python code.
Under your Tableau account settings, create a new Personal Access Token with Token Name TSC and copy the Token Secret to clipboard.

Create a sample Python App to refresh the flow

Using the tableauserverclient, create a connection to your Tableau Server. Remember to use the attribute use_server_version=True to make sure to use the latest version of the REST API supported by the instance of Tableau Server or Tableau Online you are connecting to Flow methods are supported with API version 3.3 and later).

import tableauserverclient as TSC

server = TSC.Server('https://mytableauserver.com',use_server_version=True)
print("Rest API version:", server.version)

Initialize a PersonalAccessTokenAuth instance using the Token Name, the Token Secret and the site_id you want to connect, where the site_id is the portion of the URL that follows the /site/ string. For the default site on Tableau Server you can use an empty string '' (with single quotes, no spaces).

tableau_auth = TSC.PersonalAccessTokenAuth('TSC', 'oe4S0kYrQfaVAatBFupHVg==:DmCHTwgrTqhkiWnU0yW2EURhNBhZmKkE', 'DemoSite')

Use the server.auth.sign_in() method to authenticate, and the server.flows.get() method to get the flow names and ids list (this method maps the Rest API endpoint Query Flows for a site https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref_flow.htm#query_flows_for_site)

with server.auth.sign_in(tableau_auth):
all_flow_items, pagination_item = server.flows.get()
print("There are {} flows on site:" .format(pagination_item.total_available))
print([[flow.id, flow.name] for flow in all_flow_items])

My Tableau Server has two demo flows in this site, the result will be:

Rest API version: 3.10
There are 2 flows on site:
[[‘13636115–5f03–4d53-aa23-be8b20b6c9cc’, ‘flow demo’], [‘0c101e08-e3af-4fda-bbe1-b75d8d6ed997’, ‘flow demo 2’]]

To execute every flow in list, create a loop and use the server.flows.refresh() method (this method maps the Rest API endpoint Run Flow Now https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref_flow.htm#run_flow_now)

for flow in all_flow_items:
print('Run Flow', flow.name, 'Now')
# run the flow and get the JobItem
job = server.flows.refresh(flow)

You can monitor every job execution using, for example, a polling utility to wait for a function to return when the specified condition is met.
In this example we use the Python polling2 utility, to test every 30 seconds (step=30) the finish_code attribute of the JobItem instance returned by the method server.jobs.get_by_id(job.id).
finish_code indicates the current status of the job and may assume the value: -1 for pending/in progress, 0 for success, 1 for error or 2 for cancelled.
The polling execution will ends with finish_code different from -1.

# job completion status types
job_status = ["Success", "Failed", "Cancelled"]
# loop until job is in pending/in progress status
polling2.poll(lambda: server.jobs.get_by_id(job.id).finish_code != -1, step=30, poll_forever=True)
# print the completion status
print('Job finished with status: ' + job_status[int(server.jobs.get_by_id(job.id).finish_code)])

If successful the result will be:

Run Flow “flow demo” Now
Job finished with status: Success
Run Flow “flow demo 2” Now
Job finished with status: Success

At this point, you should have everything you need to run and monitor programmatically your Tableau Prep flows execution.

Conclusion

If you extensively use Tableau Prep to manage data preparation processes in your organization, the adoption of Tableau Data Management Add-on is recommended to orchestrate your flows on a schedule.
But if you need to run Prep Flows programmatically, e.g. after data loading or in a service integration flow, you can create a script to run and monitor your flows. Using Tableau Server Client you need only few lines of Python code but, obviously, you can use REST APIs with any other programming language or integration service platform.

If you need further info just reach out to me on LinkedIn.

--

--

Pietro Gentini
Tableau Server Insights Blog

Head of BI Solutions at Ecoh Media, Italian Tableau Partner since 2012. Tableau Certified Architect, Trainer, Consultant and #RomaTUG co-leader.