Getting Started with the TABLEAU_REST_API library

This is the first post on how to actually use the tableau_rest_api Python library. The library handles most of the difficult things for you, but there are still some concepts that are worth getting a hang of. I highly recommend using an IDE, such as PyCharm, so you can easily see all the parameters of each of the methods.

Initial setup

Once the library is installed, you can import it into your scripts and get going. We’re going to create a TableauRestApi object to handle our requests, and a Logger object that can be shared between any TableauRestApi objects we create. Except for the initial sign-in action, all REST API calls are made when logged in to a particular site, so if you are doing actions across multiple sites, you’ll have to create a new TableauRestApi object for each site. You can log them all in the same file by passing the same Logger object, or pass separate ones to keep your logs separated.

We do a full import of ‘tableau_rest_api.tableau_rest_api’ because there are also some Exception classes we may want to reference when we do exception handling later. urllib2 is imported for its Exceptions as well. There are some actions that shouldn’t be done too quickly, so the standard ‘time’ package is also convenient to have available for its sleep function.


from tableau_rest_api.tableau_rest_api import *
import urllib2
import time

server = 'http://127.0.0.1'
username = 'my_username'
password = 'my_password'
tab_srv = TableauRestApi(server, username, password, site_content_url='default')
logger = Logger('rest_test.log')
tab_srv.enable_logging(logger)

tab_srv.signin()

LUIDs

As mentioned in a previous post on the REST API, all content / objects on the Tableau Server are referenced via local unique IDs (LUIDs), which are all alphanumeric codes that never change for that particular object. The library has many methods built in for getting the specific LUID of an object, and ‘create’ and ‘publish’ methods will return the LUID of the newly created/published content.

For example, let’s say we want to create a new user and then add them to an existing group called “Sandbox Users”.


try:
    group_luid = tab_srv.query_project_luid_by_name('Sandbox Users')
    # add_user actually adds and updates everything about the user
    # add_user(username, fullname, site_role='Unlicensed', password=None, email=None):
    new_user_luid = new_user_luid = tab_srv_3.add_user('newuser1', 'New User 1',
                                                       'Interactor', 'password', 'newuser1@nowhere.com')
    # Alternatively, you could do add_user_by_username(self, username, site_role='Unlicensed')
    # This does not define any of the additional properties

    # The methods that have plurals (like add_users) can take a single string or a list of luids
    tab_srv.add_users_to_group_by_luid(new_user_luid, group_luid)
except NoMatchFoundException as e:
    print e.msg

You’ll notice some of the style of the library methods — they are verbose and specify what type of input they are looking for:  ‘_by_luid’ ends almost all of the ‘baseline’ methods that directly do actions, while ‘by_name’ methods do look ups to find a match. ‘by_name’ methods also can throw NoMatchFoundException class Exceptions, and then you can decide what to do from there.

Iterating through lists

The ‘query’ methods that end in a plural, like ‘query_groups()’ and ‘query_projects()’ return iterable lxml objects based on every item that came back. The REST API actually returns paginated results when the lists get large enough, but the library paginates through for you automatically and combines them into a single lxml object. You can then do any of the regular ElementTree or lxml methods to work with these objects, for example .xpath() for very specific querying.

There is also a static method of the TableauRestApi class which takes any of these lxml objects and converts it to a standard Python dict using { name : luid } as a pattern. This gives you an easily iterable dict that you can loop through to do mass changes.


groups = tab_srv.query_groups()

groups_dict = tab_srv.convert_xml_list_to_name_id_dict(groups)
for group in groups_dict:
    print "Group named {} is LUID {}".format(group, groups_dict.get(group))

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s