Skip to content

Commit

Permalink
Updating samples to reflect new realities. Updating README to clarify…
Browse files Browse the repository at this point in the history
… the new syntax for imports
  • Loading branch information
Bryant Howell committed Dec 7, 2019
1 parent 8fb5a35 commit 648496c
Show file tree
Hide file tree
Showing 9 changed files with 93 additions and 170 deletions.
15 changes: 11 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -187,13 +187,20 @@ tableau_tools
* tableau_http
* tableau_emailer (legacy, unsupported)

#### 0.0.1 Examples
Within the installed package, there is an examples sub-directory with a bunch of functional examples as well as ones that start with "test_suite" that show how to use almost any method in the library.

### 0.1 Importing tableau_tools library
It is recommended that you import everything from the tableau_tools package like:
It may be easier just to find them all on GitHub at https://github.com/bryantbhowell/tableau_tools/tree/5.0.0/examples , and then download them to your own local directories and start trying them out.

### 0.1 Importing tableau_tools library into your scripts
If you just import tableau_tools per the following, you will have access to the tableau_rest_api sub-package:

from tableau_tools import *
from tableau_tools.tableau_rest_api import *
from tableau_tools.tableau_documents import *

If you need to use tableau_documents, use the following import statements:

from tableau_tools import *
from tableau_documents import *

### 0.2 Logger class
The Logger class implements useful and verbose logging to a plain text file that all of the other objects can use. You declare a single Logger object, then pass it to the other objects, resulting in a single continuous log file of all actions.
Expand Down
22 changes: 11 additions & 11 deletions examples/archive_site.py
Original file line number Diff line number Diff line change
@@ -1,44 +1,44 @@
# -*- coding: utf-8 -*-

from tableau_tools.tableau_rest_api import *
# from tableau_tools.tableau_rest_api import *
from tableau_tools import *
import os


def archive_tableau_site(save_to_directory, server, username, password, site_content_url):
# The last two digits of this constructor match to the version of API available on the Tableau Server
t = TableauRestApiConnection30(server=server, username=username,
t = TableauServerRest33(server=server, username=username,
password=password, site_content_url=site_content_url)
t.signin()
all_projects = t.query_projects()
all_projects = t.projects.query_projects()
all_projects_dict = t.convert_xml_list_to_name_id_dict(all_projects)

# This gives you the Project name; the values of the dict are the LUIDs
for project in all_projects_dict:
# Create directory for projects
try:
print(('Making directory {}'.format(project)))
print('Making directory {}'.format(project))
os.mkdir('{}/{}'.format(save_to_directory, project))
except OSError as e:
print('Directory already exists')

print(('Downloading datasources for project {}'.format(project)))
print('Downloading datasources for project {}'.format(project))
# Get All Data sources
dses_in_project = t.query_datasources(project_name_or_luid=all_projects_dict[project])
dses_in_project = t.datasources.query_datasources(project_name_or_luid=all_projects_dict[project])
for ds in dses_in_project:
ds_luid = ds.get('id')
ds_content_url = ds.get('contentUrl')
print(('Downloading datasource {}'.format(ds_content_url)))
t.download_datasource(ds_name_or_luid=ds_luid,
print('Downloading datasource {}'.format(ds_content_url))
t.datasources.download_datasource(ds_name_or_luid=ds_luid,
filename_no_extension="{}/{}/{}".format(save_to_directory, project, ds_content_url),
include_extract=False)

print(('Downloading workbooks for project {}'.format(project)))
wbs_in_project = t.query_workbooks_in_project(project_name_or_luid=all_projects_dict[project])
print('Downloading workbooks for project {}'.format(project))
wbs_in_project = t.workbooks.query_workbooks_in_project(project_name_or_luid=all_projects_dict[project])
for wb in wbs_in_project:
wb_luid = wb.get('id')
wb_content_url = wb.get('contentUrl')
print(('Downloading workbook {}'.format(wb_content_url)))
t.download_workbook(wb_name_or_luid=wb_luid,
t.workbooks.download_workbook(wb_name_or_luid=wb_luid,
filename_no_extension="{}/{}/{}".format(save_to_directory, project, wb_content_url),
include_extract=False)
3 changes: 1 addition & 2 deletions examples/create_site_sample.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# -*- coding: utf-8 -*-

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

server = 'http://127.0.0.1'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
# -*- coding: utf-8 -*-
from tableau_tools import *
from tableau_tools.tableau_rest_api import *
from tableau_documents import *
from tableau_tools.tableau_documents.hyper_file_generator import HyperFileGenerator
from tableau_tools.tableau_documents.tableau_file import TableauFile
from tableau_tools.tableau_documents.tableau_datasource import TableauDatasource, TableauConnection

import pyodbc
import sys

Expand Down
15 changes: 9 additions & 6 deletions examples/move_extracts_from_server_to_server.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# -*- coding: utf-8 -*-

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

Expand All @@ -22,16 +21,20 @@
d_password = ''
d_site_content_url = ''

t = TableauRestApiConnection28(o_server, o_username, o_password, o_site_content_url)

t = TableauServerRest28(server=o_server, username=o_username, password=o_password, site_content_url=o_site_content_url)
t.signin()
t.enable_logging(logger)
downloaded_filename = 'File Name'
wb_name_on_server = 'WB Name on Server'
proj_name = 'Default'
t.download_workbook('WB Name on Server', downloaded_filename, proj_name_or_luid=proj_name)
t.workbooks.download_workbook(wb_name_or_luid='WB Name on Server', filename_no_extension=downloaded_filename,
proj_name_or_luid=proj_name)

d = TableauRestApiConnection28(d_server, d_username, d_password, d_site_content_url)
d = TableauServerRest28(d_server, d_username, d_password, d_site_content_url)
d.signin()
d.enable_logging(logger)
proj = d.query_project('Default')
d.publish_workbook('{}.twbx'.format(downloaded_filename), wb_name_on_server, proj, save_credentials=False, overwrite=True)
proj = d.projects.query_project('Default')
d.workbooks.publish_workbook(workbook_filename='{}.twbx'.format(downloaded_filename),
workbook_name=wb_name_on_server, project_obj=proj,
save_credentials=False, overwrite=True)
8 changes: 3 additions & 5 deletions examples/permissions_auditing.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
# -*- coding: utf-8 -*-
from tableau_tools.tableau_rest_api import *
from tableau_tools import *
import csv

# There are differences between Python 2.7 and Python 3, so this may not run on Python 3 yet

username = ''
password = ''
server = 'http://localhost'

logger = Logger('permissions.log')
default = TableauRestApiConnection25(server, username, password)
default = TableauRestApiConnection28(server=server, username=username, password=password)
default.enable_logging(logger)
default.signin()

Expand Down Expand Up @@ -38,7 +35,8 @@
output_writer.writerow(headers)

for site_content_url in site_content_urls:
t = TableauRestApiConnection28(server, username, password, site_content_url)
t = TableauRestApiConnection28(server=server, username=username, password=password,
site_content_url=site_content_url)
t.enable_logging(logger)
t.signin()
projects = t.query_projects()
Expand Down
104 changes: 0 additions & 104 deletions examples/permissions_changing.py

This file was deleted.

46 changes: 20 additions & 26 deletions examples/user_sync_sample.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import psycopg2.extensions
import psycopg2

from tableau_rest_api.tableau_rest_api_connection import *

# This is example code showing a sync process from a database with users in it
# It uses psycopg2 to connect to a PostgreSQL database
# You can substitute in any source of the usernames and groups
# The essential logic is that you do a full comparison on who should exist and who doesn't, and both add and remove


import psycopg2.extensions
import psycopg2

from tableau_tools import *

psycopg2.extensions.register_type(psycopg2.extensions.UNICODE)
psycopg2.extensions.register_type(psycopg2.extensions.UNICODEARRAY)

Expand All @@ -18,7 +19,7 @@
password = ''
server = 'http://'

t = TableauRestApiConnection28(server=server, username=username, password=password, site_content_url='default')
t = TableauServerRest33(server=server, username=username, password=password, site_content_url='default')
t.enable_logging(logger)
t.signin()

Expand All @@ -36,8 +37,8 @@
# Loop through the results
for row in cur:
if row[0] not in groups_dict:
print(('Creating group {}'.format(row[0])))
luid = t.create_group(group_name=row[0])
print('Creating group {}'.format(row[0]))
luid = t.groups.create_group(group_name=row[0])
groups_dict[row[0]] = luid

print(groups_dict)
Expand All @@ -49,21 +50,21 @@
cur.execute(sql_statement)

# Get all the users on the site
users = t.query_users()
users = t.users.query_users()
users_dict = t.convert_xml_list_to_name_id_dict(users)

# Loop through users, make sure they exist
for row in cur:
if row[0] not in users_dict:
print(('Creating user {}'.format(row[0].encode('utf8'))))
luid = t.add_user(username=row[0], fullname=row[1], site_role='Publisher')
print('Creating user {}'.format(row[0].encode('utf8')))
luid = t.users.add_user(username=row[0], fullname=row[1], site_role='Publisher')
users_dict[row[0]] = luid

print(users_dict)

# Create projects for each user
for user in users_dict:
proj_obj = t.create_project("My Saved Reports - {}".format(user))
proj_obj = t.projects.create_project("My Saved Reports - {}".format(user))
user_luid = users_dict[user]
perms_obj = proj_obj.create_project_permissions_object_for_user(username_or_luid=user_luid, role='Publisher')
proj_obj.set_permissions_by_permissions_obj_list([perms_obj, ])
Expand All @@ -89,23 +90,23 @@
groups_and_users[group_luid] = []
groups_and_users[group_luid].append(user_luid)

print(('Adding user {} to group {}'.format(row[0].encode('utf8'), row[2].encode('utf8'))))
t.add_users_to_group(username_or_luid_s=user_luid, group_name_or_luid=group_luid)
print('Adding user {} to group {}'.format(row[0].encode('utf8'), row[2].encode('utf8')))
t.groups.add_users_to_group(username_or_luid_s=user_luid, group_name_or_luid=group_luid)

# Determine if any users are in a group who do not belong, then remove them
for group_luid in groups_and_users:
if group_luid == groups_dict['All Users']:
continue
users_in_group_on_server = t.query_users_in_group(group_luid)
users_in_group_on_server = t.groups.query_users_in_group(group_luid)
users_in_group_on_server_dict = t.convert_xml_list_to_name_id_dict(users_in_group_on_server)
# values() are the LUIDs in these dicts
for user_luid in list(users_in_group_on_server_dict.values()):
if user_luid not in groups_and_users[group_luid]:
print(('Removing user {} from group {}'.format(user_luid, group_luid)))
t.remove_users_from_group(username_or_luid_s=user_luid, group_name_or_luid=group_luid)
print('Removing user {} from group {}'.format(user_luid, group_luid))
t.groups.remove_users_from_group(username_or_luid_s=user_luid, group_name_or_luid=group_luid)

# Determine if there are any users who are in the system and not in the database, set them to unlicsened
users_on_server = t.query_users()
users_on_server = t.users.query_users()
for user_on_server in users_on_server:
# Skip the guest user
if user_on_server.get("name") == 'guest':
Expand All @@ -114,11 +115,4 @@
if user_on_server.get("siteRole") not in ['ServerAdministrator', 'SiteAdministrator']:
print(('User on server {} not found in security table, set to Unlicensed'.format(user_on_server.get("name").encode('utf8'))))
# Just set them to 'Unlicensed'
t.update_user(username_or_luid=user_on_server.get("name"), site_role='Unlicensed')


# You can check that content permissions all match their project permissions if necessary
# projects = t.query_projects()
# projects_dict = t.convert_xml_list_to_name_id_dict(projects)
# for proj_luid in projects_dict.values():
# t.sync_project_permissions_to_contents(proj_luid)
t.users.update_user(username_or_luid=user_on_server.get("name"), site_role='Unlicensed')
Loading

0 comments on commit 648496c

Please sign in to comment.