Republishing Extracts from One Site (or Server) to Another with tableau_tools

Imagine you have a Data Source (in a workbook or outside of one) which is an extract, refreshing on a schedule. But that same data could be used on a different site, or a different server. There are lots of reasons to have logical partitions that basically need a copy of data, particularly related to security. You might have an internal server that connects to data sources allowing the refresh, but want to push that content to a server that eventually connects to the public Internet.

The REST API allow for this fairly easily — you simply download the first workbook, then republish to a different site with the Save Credentials options set to “False”. No credentials means the extract can’t update, but that’s exactly the idea behind this exercise — you want no way to access the database.

Note: The Tableau workbook and data source files will still contain some information about the original live data source that the extract was created from, but no passwords (no credentials are passed to the second site/server). If you need complete lock-down security, I can try and explore how much you can blank out of the XML while still publishing successfully.

This is very easily accomplished via tableau_tools:

# -*- coding: utf-8 -*-

from tableau_tools.tableau_rest_api import *
from tableau_tools import *
import time

o_server = u'http://'
o_username = u''
o_password = u''
o_site_content_url = u''

logger = Logger(u'move.log')

d_server = u'http://'
d_username = u''
d_password = u''
d_site_content_url = u''

t = TableauRestApiConnection26(o_server, o_username, o_password, o_site_content_url)
downloaded_filename = u'File Name'
wb_name_on_server = u'WB Name on Server'
proj_name = u'Default'
t.download_workbook(wb_name_on_server, downloaded_filename, proj_name_or_luid=proj_name)

d = TableauRestApiConnection26(d_server, d_username, d_password, d_site_content_url)
proj = d.query_project(u'Default')
d.publish_workbook(u'{}.twbx'.format(downloaded_filename), wb_name_on_server, proj, save_credentials=False, overwrite=True)




Killing a Tableau Server Session

Within an embedded application, it can be difficult to make sure that sign-out is achieved in both the application and Tableau Server. Tableau Server supports SAML signout commands, but for all sorts of reasons, this might not always work.

Luckily, it is possible to use the REST API to kill any session programmatically, but you need the session identifier from the Tableau Repository. The question is, how do you know what session belongs to a user? There is a sessions view, but you need a little bit more to get filtering down to the username level:

sessions.shared_vizql_write, AS user_name,
FROM sessions
JOIN users ON sessions.user_id =
JOIN system_users ON users.system_user_id =
WHERE = '{username}'

Once you have the session ID, you can send a REST API sign out command.

tableau_tools has both of these commands wrapped in a simple interface.

server = ''
username = ''
password = ''
readonly_user_password = ""
d = TableauRestApiConnection25(server, username, password)
tab_rep = TableauRepository(server, readonly_user_password)
uname = 'some_username'
sessions_cur = tab_rep.query_sessions(username=uname)
for row in sessions_cur:
    d.token = row[0]

The token property of the TableauRestApiConnection uses the REST API session token on when you do the signin() method, but you can replace the token with any session ID from the repository and then the signout() method will be sending the correct method to sign-out.

tableau_tools version 4.2.0 released – now Python 3 compatible!

Update: Hot on the heels of 4.1.0, tableau_tools 4.2.0 is now available with full Python 3 compatibility!

The version 4.0 series of tableau_tools was always intended to allow for Python 3 compatibility, and with version 4.2.0, installing from PyPi (or invokes automatic 2to3 conversion that should work without any additional changes. The short lived 4.1.0 release moved from urllib2 to requests as the library for making the actual HTTP calls in the backend, and 4.2.0 finishes off the work by moving everything to Unicode internally, while writing all text files out in UTF-8 encoding.

This means there is now a requirement for the requests library, but since every other Python package in the world now uses requests, I don’t think it should cause anyone any harm. Please do report any bugs that you see, as there might be a few quirky corner cases where something that was necessary before requests is causing an issue.

The Tableau SDK itself is only Python 2.7 compatible, so the TDE Extract Generation / Conversion from TDS to TDSX functionality won’t work in Python 3, but everything else should be completely compatible.


tableau_tools 4.0.0 is released!

I’m very excited to announce the release of tableau_tools 4.0.0, available now on GitHub and PyPi! tableau_tools is a single library to make administrating a Tableau Server and the content on that server as simple as possible. It is written in Python 2.7 with the aim to eventually become compatible with Python 3. It is also intended to server all versions of Tableau Server from 9.0 – current release.

The 4.0 release is almost a complete rewrite, with a focus on full implementation of the Tableau Server REST API through API Version 2.6, simplification of methods throughout, and advanced capabilities for publishing from templates. The capabilities of tableau_tools are beyond the current capabilities of the Tableau Server-Client Library and Document API, and I recommend you use it over them at this time.

4.0 is different enough from the previous versions that all previous versions of tableau_tools are now deprecated, and I will be removing their documentation from the website to remove any confusion.

There are plenty of example scripts included in the package, which you can see at GitHub…

The README is a full guide to using the library, and should be read when beginning. As before, tableau_tools was programmed using PyCharm and is designed to provide optimal code completion when using PyCharm. Your life will be a lot easier if you do.

tableau_tools README

A list of all the major changes, which won’t matter if you are just getting started:


Changing Parameters in Workbook XML

Parameters allow for a lot of awesome Tableau functionality. When working with template publishing, it makes sense that you might want to do variations on the display names for a parameter, or even set the options arbitrarily for each site you will publish to. However, despite looking like part of a data source, Parameters are actually stored as their own data source within a workbook. This means we’ll need to consider how to insert and modify them in each workbook.


Triggering Extract Refreshes with tableau_tools

If you have ETL processes that must run before your extracts can generate, it may make more sense to trigger an extract refresh (or the schedules) to run after the ETL has finished, rather than setting the extracts on a schedule. It maximizes your backgrounder processes by feeding their queues immediately when data is ready, and saves wasted effort if the ETL process fails.

As of Tableau Server version 10.0, there are no REST API commands to do this triggering, but tabcmd does have commands that can accomplish this. The tableau_tools Python library  has a Tabcmd class that wraps the most common tabcmd commands, including those for extract refreshes. Together with the tableau_rest_api sub-package, you can trigger off extract refreshes.

Note: Please use the latest version of tableau_tools (3.1.0+) to do the following.