Madhav Kannan has been a superstar in Tableau’s APAC region for a few years now, but he’s really outdone himself with an improved technique for embedding the Web Edit functionality of Tableau Server smoothly into another web application, without requiring anything additional be added to the Tableau Server. I highly recommend you check out his blog post if you are looking to embed Web Edit!
The trend toward wrapping together data and security filtering into RESTful web services has only increased in the past few years, and for a lot of good reasons. If the REST API is optimized to return very quickly based on a set of filtering parameters, the performance alone can justify the architecture. However, Tableau is planning to do more with the result set than simply display it directly — Tableau is ready to do deep analysis and discover new insights. Because of this, Tableau’s VizQL engine needs something it can query in many different ways as the basis for a data source connection.
How can we bridge the gap between a JSON (or XML, if anyone still does that) object response and a relational query engine?
What if I told you THIS was all that was necessary on the Tableau Desktop side to build a data source that acts as a “live” connection to a web service?:
Accessing the PL/Python Function in Tableau
Connect to the PostgreSQL database in Tableau Desktop using whatever credentials you created for an end user.
Then on the Data Connection screen, you’ll find on New Custom SQL on the left:
If you drag that out, then the dialog to define the Custom SQL query appears:
As you can see, the query is just SELECT * FROM function_name( arguments ), with whatever parameters you want to attach. You can create new parameters right from this dialog box, then put them in place. Make sure to give sensible defaults, and probably most should default to an empty string so that someone can only access if they have the right tokens / etc.
How is this possible?
There’s a whole lot of setup on the PostgreSQL side, but the payoff is the simplicity of the setup in Tableau.
The solution is based on the architecture originally laid out here, but I’ve put together a Dockerfile which builds out a PostgreSQL database ready for your custom set of functions which will dynamically call a RESTful Web Service based on Tableau’s parameters.
Just in time for 2020, tableau_tools has gone a thorough upgrade to bring it into the Python 3 era. While the 4 series of tableau_tools was Python 3 compatible, tableau_tools 5.0 and beyond are Python 3 native, dropping support for 2.7 entirely. It also drops support for any version of Tableau before 10.3, which matches Tableau’s official support policy at this point.
In the process, the source has also been completely refactored for anyone who wants to join in and help with the project or just is tracking down a bug or strange behavior. It’s far easier now to find where everything is implemented, understand the logic of it, and make suggestions or changes.
Update to Python 3.6 or better, and then use PIP to install the latest version from PyPi. For all the good details, read more…
The Tableau Hyper API is an amazingly powerful tool for building out Extracts that, for whatever reason, cannot be built or maintained using the standard Tableau Server extract refresh process. You can publish a Hyper file directly to a Tableau Server, but there are several drawbacks:
- Tableau Server will build out an automatic TDS file, taking a rough guess at any type of metadata categorization (Measure vs. Dimensions, Hierarchies, Geographic info, etc.)
- The only use for this data source will be creating Ad Hoc reports using Web Edit (or hoping someone in Desktop now knows that it exists). You can’t integrate it easily in an existing Workbook
- It only works with Single-Table Extracts, and in older versions of Tableau, the single table must be named “Extract” or you will encounter errors.
What is missing is a TDS file to pair up with the Hyper file, describing the exact metadata that you want to go along with the Extracted data. In this article, I’ll describe a workflow that result in a fully controlled TDSX file with a newly generated Hyper file.
As of 2020.2, the Tableau Server REST API has two mechanisms for logging in: username/password or a Personal Access Token (PAT) . There is no direct way to directly start a REST API session using a SSO mechanism (SAML, JWT, etc.). Even if you were able to, you might still want to restrict the user to only do certain actions (for example, enabling Querying methods but not Updates or Deletes).
The best practice for working around this is to wrap the Tableau REST API in another REST API service of your own design. Then within that wrapper, use a Server Administrator level account to log in to the Tableau Server REST API. In this article, we’ll discuss how to achieve this using tableau_tools, with both a simple and a more complex but efficient design pattern.
This pattern only works with an Server Admin account that has logged in using Username/Password. PATs do not allow an admin to Impersonate into a regular user’s session at this time. This is our best practice recommendation for using the Tableau REST API out to a web application embedding Tableau Server views.
One of the least mentioned, but incredibly useful APIs in Tableau is the Extract API, which allows you to programmatically create an Extract file (Hyper files starting in 10.5, previously TDE files). The main use case is for data sources that require programmatic access (as opposed to using the one of the native connectors in Tableau). Some situations where this would be useful:
- Data coming from a Web Service/ RESTful API with an object response
- ODBC / JDBC drivers that Tableau cannot use
- Additional programmatic modeling / statistical analysis against a whole data set
This post is focused mostly on first use case, where you are trying to make data available from some type of Web Service / RESTful API. In particular, if you need to provide only a subset from a very flexible set of possible fields for “ad hoc” analysis, this technique is the most functional solution to the problem.
When should I build a Flexible Extract Generator?
- Know the structure of your web service responses
- The amount of total fields is reasonably sized
- The web service responses will not change frequently
- Workbooks are fully built out and will not allow web editing
- Data Source structure can be reused across multiple reports (and possibly customers)
then the better solution for Web Service/REST API based data sources is “Live” Web Services Connections in Tableau.
If instead you want to provide a selection screen to generate an Extract that will power a Web Edit session, then it makes sense to build a Flexible Extract Generator process. This is particularly useful when the set of fields could change drastically from extract to extract, or if other processing (such as machine learning) needs to be applied based on differing parameters prior to its use by the end user (that said, if the actual output columns are consistent, the “Live” Web Services solution could still work).
Many organizations have begun standardizing on a “Web Services” layer for access to reporting data, often with a restriction on directly connecting to the underlying data stores that power the Web Service responses. In the majority of cases, the result is a set of RESTful endpoints returning JSON object data, but for the purposes of this article, any variation that involves HTTP requests and responses in a “web-friendly” response format (JSON / XML) will be referred to as “Web Services”.
There are many reasons for adopting this architecture, and I’m here neither to recommend or pass judgement. There is one major implication to this architectural decision though — BI systems that expect a relational model and SQL-compliant querying capabilities do not have a native, natural way to handle these data responses. Tableau falls in this category (I don’t care about any others, but it’s not an issue exclusive to Tableau).
Tableau provides a Web Data Connector technology which helps individual analysts retrieve data from Web Service Data Sources, but current design does not account for data sets to vary depending on the user looking at the workbook, something essential for scalable and secure Tableau Server reports.
However, Tableau’s ability to connect live to a wide range of relational data sources allows us to construct an alternate architecture for accessing Web Services responses “live”:
Tableau’s behavior for saving content when using Web Edit follows these rules:
- If you are the Content Owner, you can Save or Save As
- If you are not the Content Owner, you can Save As
Save As is only allowed to Projects where you (or the groups you belong to) have a Save permission set to “Allow”.
Since a newly Saved Workbook will take the Default Permissions of the Project it saves into, if other people also have permissions for that same Project, they will also be able to access that content. This leads to several different strategies for controlling the privacy of content created through Save As.
- A Project Per Team / Group
- A Project Per User
- A REST API script that “fixes” Permissions
- Publishing a New Copy rather than Save As
Starting in Tableau 2018.3+:
- The design for row level security will be the same in both live connections and extracts
- Extract files with security will create much faster
- Best practices for entitlements tables are now feasible in Extracts
Let’s dig into the essentials and how we can make this work for effective Row Level Security.