### Example: Managing Tableau Schedules Source: https://github.com/bryanthowell-tableau/tableau_tools/blob/6.0.0/README.md A Python example demonstrating the creation of various schedule types, deletion of a subscription schedule, and updating of a weekly schedule, including error handling for pre-existing schedules. ```python try: t.log('Creating a daily extract schedule') t.create_daily_extract_schedule('Afternoon Delight', start_time='13:00:00') t.log('Creating a monthly subscription schedule') new_monthly_luid = t.create_monthly_subscription_schedule('First of the Month', '1', start_time='03:00:00', parallel_or_serial='Serial') t.log('Creating a monthly extract schedule') t.create_monthly_extract_schedule('Last Day of Month', 'LastDay', start_time='03:00:00', priority=25) t.log('Creating a monthly extract schedule') weekly_luid = t.create_weekly_subscription_schedule('Mon Wed Fri', ['Monday', 'Wednesday', 'Friday'], start_time='05:00:00') time.sleep(4) t.log('Deleting monthly subscription schedule LUID {}'.format(new_monthly_luid)) t.delete_schedule(new_monthly_luid) t.log('Updating schedule with LUID {}'.format(weekly_luid)) t.update_schedule(weekly_luid, new_name='Wed Fri', interval_value_s=['Wednesday', 'Friday']) except AlreadyExistsException as e: t.log('Skipping the add since it already exists') ``` -------------------------------- ### Example: Query Groups and Convert to Dictionary Source: https://github.com/bryanthowell-tableau/tableau_tools/blob/6.0.0/README.md Demonstrates a practical example of connecting to Tableau Server, signing in, querying for all groups using the XML method, and then converting the resulting XML object into a dictionary for easy access to group names and their LUIDs. ```python default = TableauServerRest34("http://127.0.0.1", "admin", "adminsp@ssw0rd") default.signin() groups = default.query_groups() groups_dict = default.convert_xml_list_to_name_id_dict(groups) for group_name in groups_dict: print "Group name {} is LUID {}".format(group_name, groups_dict[group_name]) ``` -------------------------------- ### Install tableau_tools using pip Source: https://github.com/bryanthowell-tableau/tableau_tools/blob/6.0.0/README.md This command installs or upgrades the tableau_tools library from PyPi. For Linux/macOS, sudo may be required. For Windows users, ensure Python and pip are in your PATH. ```bash pip install tableau_tools ``` ```bash pip install tableau_tools --upgrade ``` -------------------------------- ### Install tableau_tools with Proxy and Trusted Host Configuration Source: https://github.com/bryanthowell-tableau/tableau_tools/blob/6.0.0/README.md This command sequence is used when installing tableau_tools on Windows with a corporate proxy or SSL certificate issues. It sets environment variables to use Fiddler's proxy and bypass SSL verification for pypi.python.org. ```batch set http_proxy=127.0.0.1:8888 pip install --proxy 127.0.0.1:8888 --trusted-host pypi.python.org tableau_tools ``` -------------------------------- ### Create Daily Subscription Schedule in Tableau Source: https://github.com/bryanthowell-tableau/tableau_tools/blob/6.0.0/README.md Creates a daily subscription schedule on Tableau Server. Requires a name and start time, with optional parameters for priority and parallelism. ```python TableauServerRest.schedules.create_daily_subscription_schedule(name, start_time, priority=1, parallel_or_serial='Parallel') ``` -------------------------------- ### Query Projects with Filters - Python Source: https://github.com/bryanthowell-tableau/tableau_tools/blob/6.0.0/README.md Example of querying projects using the `TableauServerRest` library, demonstrating the use of optional filter parameters for name, owner, and creation/update times. These filters improve query performance by reducing the data returned. ```python from TableauServerRest import TableauServerRest t = TableauServerRest(server='', username='', password='') projects = t.projects.query_projects(name_filter='MyProject', updated_at_filter='gte', created_at_filter='2023-01-01T00:00:00Z') ``` -------------------------------- ### Example: Saving New Tableau XML Files Source: https://github.com/bryanthowell-tableau/tableau_tools/blob/6.0.0/README.md Demonstrates how the save_new_file method handles existing filenames by appending numbers. This example shows the output of saving files with the same base name multiple times. ```python tf = TableauFileOpener('A Workbook.twb') file_1 = tf.save_new_file('A Workbook') file_2 = tf.save_new_file('A Workbook') print(file_1) # 'A Workbook (1).twb' print(file_2) # 'A Workbook (2).twb' ``` -------------------------------- ### Create Weekly Subscription Schedule in Tableau Source: https://github.com/bryanthowell-tableau/tableau_tools/blob/6.0.0/README.md Creates a weekly subscription schedule on Tableau Server. Requires a name, start time, and a list of weekdays. Optional parameters include priority and parallelism. ```python TableauServerRest.schedules.create_weekly_subscription_schedule(name, weekday_s, start_time, priority=1, parallel_or_serial='Parallel') ``` -------------------------------- ### Querying Resources with query_resource() (Python) Source: https://github.com/bryanthowell-tableau/tableau_tools/blob/6.0.0/README.md The base method for most 'query' or 'get' operations. It constructs a URL, performs an HTTP GET request, and returns an ElementTree XML object. It handles URL building and direct API interaction. Dependencies include the `TableauServerRest` object and its internal `_request` object. ```Python def query_resource(self, url_ending: str, args: dict = None) -> ET.Element: self.start_log_block() # ... (URL building logic) ... api_url = self.build_api_url(url_ending) xml_response = self._request.get(api_url, params=args) self.end_log_block() return xml_response ``` ```Python def query_users_in_group(self, group_name_or_luid: str) -> ET.Element: self.start_log_block() luid = self.query_group_luid(group_name_or_luid) users = self.query_resource("groups/{}/users".format(luid)) self.end_log_block() return users ``` -------------------------------- ### Initialize Tabcmd Wrapper in Python Source: https://github.com/bryanthowell-tableau/tableau_tools/blob/6.0.0/README.md This snippet demonstrates how to initialize the Tabcmd class, a wrapper for the tabcmd program, allowing for easier scripting of Tableau Server commands. It requires specifying the tabcmd installation directory, server URL, username, and password. ```python tabcmd_dir = "C:\\tabcmd\\Command Line Utility\\" tabc_config_location = 'C:\\Users\\{\\\\}AppData\\\\Local\\\\Tableau\\\\Tabcmd\\\' server = 'http://127.0.0.1' site_content_url = 'default' username = '{}' password = '{}' tabcmd = Tabcmd(tabcmd_dir, server, username, password, site=site_content_url, tabcmd_config_location=tababc_config_location) ``` -------------------------------- ### Setting Permissions via get_permissions_obj Source: https://github.com/bryanthowell-tableau/tableau_tools/blob/6.0.0/README.md Example of retrieving and modifying permissions for a specific group or user on a published content object. Demonstrates setting capabilities to allow or deny, and applying changes. ```python proj_obj = t.projects.query_project('My Project') wb_perms_1 = proj_obj.workbook_defaults.get_permissions_obj(group_name_or_luid='My Favorite Group') wb_perms_1.set_all_to_allow() wb_perms_1.set_capability_to_deny('Download Full Data') proj_obj.workbook_defaults.set_permissions(permissions=[wb_perms_1, ]) ``` -------------------------------- ### Create Daily Extract Schedule in Tableau Source: https://github.com/bryanthowell-tableau/tableau_tools/blob/6.0.0/README.md Creates a daily extract schedule on Tableau Server. Requires a name and start time, with optional parameters for priority and parallelism. ```python TableauServerRest.schedules.create_daily_extract_schedule(name, start_time, priority=1, parallel_or_serial='Parallel') ``` -------------------------------- ### Create Hourly Subscription Schedule in Tableau Source: https://github.com/bryanthowell-tableau/tableau_tools/blob/6.0.0/README.md Creates an hourly subscription schedule on Tableau Server. Requires a name, interval (hours or minutes), interval value, start time, and end time. Optional parameters include priority and parallelism. ```python TableauServerRest.schedules.create_hourly_subscription_schedule(name, interval_hours_or_minutes, interval, start_time, end_time, priority=1, parallel_or_serial='Parallel') ``` -------------------------------- ### Create Monthly Subscription Schedule in Tableau Source: https://github.com/bryanthowell-tableau/tableau_tools/blob/6.0.0/README.md Creates a monthly subscription schedule on Tableau Server. Requires a name, day of the month, and start time. Optional parameters include priority and parallelism. 'LastDay' can be used for the day of the month. ```python TableauServerRest.schedules.create_monthly_subscription_schedule(name, day_of_month, start_time, priority=1, parallel_or_serial='Parallel') ``` -------------------------------- ### Swap Tableau Session Token Source: https://github.com/bryanthowell-tableau/tableau_tools/blob/6.0.0/README.md Provides an example of swapping the current session token with another token to impersonate a different user or site. This is useful for RESTful web services that need to perform actions as multiple users without recreating objects. ```python t = TableauServerRest(server='http://127.0.0.1', username='usrnm', password='nowthatsabigpass', site_content_url='some_site') t.signin() first_site_luid = t.site_luid first_user_luid = t.user_luid first_token = t.token t2 = TableauServerRest(server='http://127.0.0.1', username='a.nother', password='passittotheleft', site_content_url='some_site_other_site') t2.signin() t2.swap_token(site_luid=first_site_luid, user_luid=first_user_luid, token=first_token) ``` -------------------------------- ### Setting Custom SQL Query Source: https://github.com/bryanthowell-tableau/tableau_tools/blob/6.0.0/README.md This example demonstrates how to identify datasources that use custom SQL and how to set or update the custom SQL query associated with them. The `is_custom_sql` property is used for identification. ```python from tableau_tools.datasources.manager import TableauFileManager tab_file = TableauFileManager('template_file.tds') dses = tab_file.datasources for ds in dses: if ds.is_custom_sql: ds.tables.main_custom_sql = 'SELECT * FROM my_cool_table' print(f"Updated custom SQL for '{ds.name}'.") ``` -------------------------------- ### Create Weekly Extract Schedule in Tableau Source: https://github.com/bryanthowell-tableau/tableau_tools/blob/6.0.0/README.md Creates a weekly extract schedule on Tableau Server. Requires a name, start time, and a list of weekdays. Optional parameters include priority and parallelism. ```python TableauServerRest.schedules.create_weekly_extract_schedule(name, weekday_s, start_time, priority=1, parallel_or_serial='Parallel') ``` -------------------------------- ### Get Project XML Object Source: https://github.com/bryanthowell-tableau/tableau_tools/blob/6.0.0/README.md Provides a method to obtain the XML representation of a project. This is useful if you only need to inspect the XML data directly without creating a full `Project` object. It can be called directly or from an existing `Project` object. ```python TableauServerRest.projects.query_project_xml_object(project_name_or_luid( ``` ```python Project.get_xml_obj() ``` -------------------------------- ### Sending Binary GET Requests (Python) Source: https://github.com/bryanthowell-tableau/tableau_tools/blob/6.0.0/README.md Designed for retrieving binary content such as files, images, PDFs, or CSVs from the Tableau Server. Unlike other query methods, it does not process the response as XML or JSON but returns the raw content from the `requests.Response.content` property. This allows the response to be saved to disk or processed as raw data. ```Python def send_binary_get_request(self, url_ending: str, args: dict = None) -> bytes: self.start_log_block() api_url = self.build_api_url(url_ending) # _request.get is aliased to request_from_api() which can return raw response raw_response = self._request.get(api_url, params=args) self.end_log_block() return raw_response ``` ```Python def _query_data_file(self, url_ending: str, file_path: str, args: dict = None): # ... (implementation wrapping send_binary_get_request) ... pass ``` -------------------------------- ### Create Hourly Extract Schedule in Tableau Source: https://github.com/bryanthowell-tableau/tableau_tools/blob/6.0.0/README.md Creates an hourly extract schedule on Tableau Server. Requires a name, interval (hours or minutes), interval value, start time, and end time. Optional parameters include priority and parallelism. ```python TableauServerRest.schedules.create_hourly_extract_schedule(name, interval_hours_or_minutes, interval, start_time, end_time, priority=1, parallel_or_serial='Parallel') ``` -------------------------------- ### Connecting to Multiple Sites Source: https://github.com/bryanthowell-tableau/tableau_tools/blob/6.0.0/README.md Demonstrates how to query all available site content URLs and establish sessions for each site. ```APIDOC ## Connecting to Multiple Sites ### Description To interact with multiple sites on Tableau Server, you need to establish separate sessions for each. This process involves first signing into a default site to retrieve a list of all available `site_content_url` values, and then creating new TableauServerRest objects for each site to sign in. ### Method Python functions ### Endpoint N/A (Client-side logic) ### Parameters N/A ### Request Example ```python def query_and_connect_to_all_sites(server_url, username, password): default = TableauServerRest34(server_url, username, password) default.signin() site_content_urls = default.query_all_site_content_urls() site_connections = [] for site_content_url in site_content_urls: t = TableauServerRest34(server_url, username, password, site_content_url=site_content_url) t.signin() site_connections.append(t) return site_connections ``` ### Response #### Success Response - `site_connections` (list) - A list of `TableauServerRest34` objects, each signed into a different site. ``` -------------------------------- ### Create and Delete Site Pattern in TableauServerRest (Python) Source: https://github.com/bryanthowell-tableau/tableau_tools/blob/6.0.0/README.md Demonstrates a common pattern for testing site creation. It attempts to create a new site, and if it already exists, it deletes the existing site before attempting creation again. Requires TableauServerRest library and authentication credentials. ```python d = TableauServerRest(server, username, password, site_content_url='default') d.signin() d.enable_logging(logger) new_site_content_url = "my_site_name" try: print("Attempting to create site {}".format(new_site_content_url)) d.sites.create_site(new_site_content_url, new_site_content_url) except AlreadyExistsException: print("Site replica already exists, deleting bad replica") t = TableauServerRest(server, username, password, site_content_url=new_site_content_url) t.enable_logging(logger) t.signin() t.sites.delete_current_site() d.signin() d.sites.create_site(new_site_content_url, new_site_content_url) print("Logging into {} site".format(new_site_content_url)) t = TableauServerRest(server, username, password, site_content_url=new_site_content_url) t.signin() t.enable_logging(logger) ``` -------------------------------- ### Sign In with Username/Password (Python) Source: https://github.com/bryanthowell-tableau/tableau_tools/blob/6.0.0/README.md Illustrates the process of signing into a Tableau Server site using the TableauServerRest object with username and password credentials. The sign-in call establishes a session and retrieves session state. ```python t = TableauServerRest33("http://127.0.0.1", "admin", "adminsp@ssw0rd", site_content_url="site1") t.signin() logger = Logger("log_file.txt") t.enable_logging(logger) ``` -------------------------------- ### Connect to Multiple Tableau Sites Source: https://github.com/bryanthowell-tableau/tableau_tools/blob/6.0.0/README.md Demonstrates how to connect to and perform actions across multiple Tableau sites. It involves signing into a default site, querying for all site content URLs, and then establishing new connections for each site to perform operations. ```python default = TableauServerRest34("http://127.0.0.1", "admin", "adminsp@ssw0rd") default.signin() site_content_urls = default.query_all_site_content_urls() for site_content_url in site_content_urls: t = TableauServerRest34("http://127.0.0.1", "admin", "adminsp@ssw0rd", site_content_url=site_content_url) t.signin() ... ``` -------------------------------- ### Python File Initialization and Saving Logic Source: https://github.com/bryanthowell-tableau/tableau_tools/blob/6.0.0/README.md Illustrates the core methods for handling Tableau files within the tableau_tools library. `_open_file_and_initialize` details how files are opened, validated, and parsed into in-memory objects, with specific logic for packaged files like TWBX. `save_new_file` outlines the process for saving both un-packaged (TWB, TDS) and packaged (TWBX, TDSX) files, including the substitution of internal files for packaged archives. ```python import zipfile import xml.etree.ElementTree as ET # Assume presence of TableauFileManager, TWB, TDS, TWBX, TDSX classes # and their respective initialization and saving methods. class TableauFileManager: def __init__(self, file_path): self.file_path = file_path # Factory logic to return correct object type (TDS, TWB, TDSX, TWBX) self.tableau_file = self._create_tableau_file_object() def _create_tableau_file_object(self): # Placeholder for factory logic if self.file_path.endswith('.twb'): return TWB(self.file_path) elif self.file_path.endswith('.tds'): return TDS(self.file_path) elif self.file_path.endswith('.twbx'): return TWBX(self.file_path) elif self.file_path.endswith('.tdsx'): return TDSX(self.file_path) else: raise ValueError("Unsupported Tableau file type") def get_datasources(self): return self.tableau_file.datasources() def save_new_file(self, filename): self.tableau_file.save_new_file(filename) class TWB(TableauXmlFile): def __init__(self, file_path): self.file_path = file_path self._open_file_and_initialize() def _open_file_and_initialize(self): with open(self.file_path, 'r', encoding='utf-8') as f: xml_content = f.read() self.tree = ET.fromstring(xml_content) # Simplified: In reality, this parses datasources section self.datasources_xml = self._extract_datasources_xml(self.tree) # Further object creation based on datasources_xml def _extract_datasources_xml(self, tree): # Placeholder for actual XML parsing logic datasources_section = tree.find('.//datasources') if datasources_section is not None: return ET.tostring(datasources_section, encoding='unicode') return "" @property def tableau_document(self): # Returns the ElementTree object or similar representation return self.tree # Simplified def datasources(self) -> List[TableauDatasource]: # Placeholder for creating TableauDatasource objects return [] def get_xml_string(self) -> str: # Placeholder for serializing the modified tree back to XML string return ET.tostring(self.tree, encoding='unicode') def save_new_file(self, filename): xml_string = self.get_xml_string() with open(filename, 'w', encoding='utf-8') as f: f.write(xml_string) class TWBX(TableauPackagedFile): def __init__(self, file_path): self.file_path = file_path self._open_file_and_initialize() def _open_file_and_initialize(self): with zipfile.ZipFile(self.file_path, 'r') as zip_ref: twb_file = zip_ref.read('workbook.twb') # Assumes workbook.twb is the standard name self.twb_object = TWB(io.BytesIO(twb_file)) # Pass content to TWB init # Store other files if necessary @property def tableau_xml_file(self) -> TableauXmlFile: return self.twb_object @property def tableau_document(self): return self.twb_object.tableau_document def datasources(self) -> List[TableauDatasource]: return self.twb_object.datasources() def save_new_file(self, filename): # Logic to create a new zip file, substitute files (e.g., Hyper) # and include the updated .twb content. with zipfile.ZipFile(self.file_path, 'r') as infile, zipfile.ZipFile(filename, 'w') as outfile: # Copy all files except the main .twb for item in infile.infolist(): if not item.filename.endswith('.twb'): outfile.writestr(item, infile.read(item.filename)) # Write the modified .twb content modified_twb_content = self.twb_object.get_xml_string() outfile.writestr('workbook.twb', modified_twb_content) # Note: This is a simplified representation. Real implementation would # handle potential replacements like Hyper files more robustly. # Placeholder classes for TDS, TDSX class TDS(TableauXmlFile): pass class TDSX(TableauPackagedFile): pass import io # Needed for BytesIO example ``` -------------------------------- ### TableauServerRest Constructor and build_api_url() Method Source: https://github.com/bryanthowell-tableau/tableau_tools/blob/6.0.0/README.md Demonstrates the constructor for the TableauServerRest object, which initializes a session with the Tableau REST API by taking server details, username, password, site content URL, and API version. It also shows the build_api_url() method, a fundamental building block for constructing REST API call URLs by incorporating server and site information. ```python def __init__(self, server: str, username: str, password: str, site_content_url: Optional[str] = "", api_version: str = "3.2"): ... def build_api_url(self, call: str, server_level: bool = False, url_parameters: Optional[str] = None): ... ``` -------------------------------- ### Get Published Content Objects with TableauServerRest Source: https://github.com/bryanthowell-tableau/tableau_tools/blob/6.0.0/README.md Factory methods to retrieve specific published content objects (Project, Datasource, Workbook) from Tableau Server. These methods require an active Tableau API connection. ```python t.projects.get_published_project_object(project_name_or_luid) t.projects.get_published_datasource_object(datasource_name_or_luid, project_name_or_luid) t.projects.get_published_workbook_object(workbook_name_or_luid, project_name_or_luid) ``` -------------------------------- ### Instantiate TableauServerRest Class (Python) Source: https://github.com/bryanthowell-tableau/tableau_tools/blob/6.0.0/README.md Demonstrates how to instantiate the TableauServerRest class with a specific API version (3.6) using a Personal Access Token for authentication. Requires server URL, PAT name, PAT secret, and site content URL. ```python t = TableauServerRest36(server="http://127.0.0.1", pat_name="ripFatPat", pat_secret="qlE1g9MMh9vbrjjg==:rZTHhPpP2tUW1kfn4tjg8", site_content_url="fifth_ward") ``` -------------------------------- ### Query Tableau Groups and Print XML Response Source: https://github.com/bryanthowell-tableau/tableau_tools/blob/6.0.0/README.md Demonstrates how to sign in to Tableau Server, query for groups, and print the raw XML response using ElementTree. This requires the tableau_tools library and an active Tableau Server connection. ```python import xml.etree.ElementTree as ET from tableau_tools.rest_api import TableauServerRest t = TableauServerRest("http://127.0.0.1", "admin", "adminsp@ssw0rd", site_content_url="site1") t.signin() groups = t.groups.query_groups() print(ET.tostring(groups)) ``` -------------------------------- ### Initialize and Use TableauDatasource Objects Source: https://github.com/bryanthowell-tableau/tableau_tools/blob/6.0.0/README.md Demonstrates how to initialize a `TableauDatasource` object, either from scratch or by accessing existing datasources within Tableau file types (TWB, TWBX, TDS, TDSX). It shows how to iterate through datasources and their connections. ```python from tableau_tools.data_source.tableau_datasource import TableauDatasource from tableau_tools.logger import Logger from tableau_tools.file_manager import TableauFileManager from tableau_tools.datasources.datasource_file_interface import DatasourceFileInterface # Initialize a new datasource from scratch logger = Logger('ds_log.txt') new_ds = TableauDatasource(logger_obj=logger) print(f"Created new datasource: {new_ds}") # Accessing datasources from existing files list_o_files = ['A Twb.twb', 'A TDSX.tdsx', 'An TWBX.twbx', 'This here TDS.tds'] for file in list_o_files: t_file = TableauFileManager.open(filename=file, logger_obj=logger) if isinstance(t_file, DatasourceFileInterface): datasources = t_file.datasources for ds in datasources: print(f"Processing datasource: {ds.name}") for conn in ds.connections: print(f" Connection: {conn.name}") ``` -------------------------------- ### Create Monthly Extract Schedule in Tableau Source: https://github.com/bryanthowell-tableau/tableau_tools/blob/6.0.0/README.md Creates a monthly extract schedule on Tableau Server. Requires a name, day of the month, and start time. Optional parameters include priority and parallelism. 'LastDay' can be used for the day of the month. ```python TableauServerRest.schedules.create_monthly_extract_schedule(name, day_of_month, start_time, priority=1, parallel_or_serial='Parallel') ``` -------------------------------- ### Signout, Killing Other Sessions, and Swapping Tokens Source: https://github.com/bryanthowell-tableau/tableau_tools/blob/6.0.0/README.md Explains how to sign out of the current session, sign out other sessions using a session token, and swap authentication tokens between sessions. ```APIDOC ## Signout, Killing Other Sessions, and Swapping Tokens ### Description This section covers session management, including signing out of the current session, terminating other sessions using a provided session token, and swapping the authentication token of a session to impersonate another. ### Method Python functions: `signout()`, `swap_token()` ### Endpoint N/A (Client-side logic) ### Parameters #### Signout Parameters - `session_token` (str) - Optional. The token of the session to sign out. If not provided, the current session is signed out. #### Swap Token Parameters - `site_luid` (str) - Required. The LUID of the target site. - `user_luid` (str) - Required. The LUID of the target user. - `token` (str) - Required. The authentication token of the target session. ### Request Example ```python # Sign out of the current session t.signout() # Sign out a specific session t.signout(session_token='buerojh8b4L2-b208guDSVD!--038bSVE') # Swap token to impersonate another user/site session t = TableauServerRest(server='http://127.0.0.1', username='usrnm', password='nowthatsabigpass', site_content_url='some_site') t.signin() first_site_luid = t.site_luid first_user_luid = t.user_luid first_token = t.token t2 = TableauServerRest(server='http://127.0.0.1', username='a.nother', password='passittotheleft', site_content_url='some_site_other_site') t2.signin() t2.swap_token(site_luid=first_site_luid, user_luid=first_user_luid, token=first_token) ``` ### Response #### Success Response - **Signout**: No explicit return value, session is terminated. - **Swap Token**: No explicit return value, the session token of the current object is updated. ``` -------------------------------- ### Impersonate Sign In (Python) Source: https://github.com/bryanthowell-tableau/tableau_tools/blob/6.0.0/README.md Demonstrates how to sign in as another user using impersonation. This involves first querying the target user's LUID and then using that LUID in the sign-in method of a separate TableauServerRest object. ```python t = TableauServerRest("http://127.0.0.1", "admin", "adminsp@ssw0rd", site_content_url="site1") t.signin() user_luid = t.query_user_luid('a.user') t2 = TableauServerRest("http://127.0.0.1", "admin", "adminsp@ssw0rd", site_content_url="site1") t2.signin(user_luid_to_impersonate=user_luid) ``` -------------------------------- ### Duplicate Site Content using XML Requests Source: https://github.com/bryanthowell-tableau/tableau_tools/blob/6.0.0/README.md Demonstrates how to duplicate content from one Tableau site to another using `direct_xml_request` and `build_request_from_response`. This process involves fetching content from a source site, converting its response XML to a request XML, and then using that request to create the content on a target site. ```python t = TableauServerRest("http://127.0.0.1", "admin", "adminsp@ssw0rd", site_content_url="site1") t.signin() t2 = TableauServerRest("http://127.0.0.1", "admin", "adminsp@ssw0rd", site_content_url="duplicate_site1") t2.signin() o_groups = t.groups.query_groups() for group in groups: new_group_request = t.build_request_from_response(group) new_group_luid = t2.groups.create_group(direct_xml_request=new_group_request) ``` -------------------------------- ### Add Dimension Data Source Filters to Tableau Source: https://github.com/bryanthowell-tableau/tableau_tools/blob/6.0.0/README.md Demonstrates how to add dimension-based filters to an existing Tableau data source. This is useful for customer-specific filtering when publishing data sources. Requires a TableauFile object and provides examples for including and excluding values. ```python existing_tableau_file = TableauFile('Desktop DS.tds') doc = existing_tableau_file.tableau_document # This syntax gets you correct type hinting dses = doc.datasources #type: list[TableauDatasource] ds = dses[0] ds.add_dimension_datasource_filter(column_name="call_category", values=["Account Status", "Make Payment"]) ds.add_dimension_datasource_filter(column_name="customer_name", values=["Customer A", ]) ds.add_dimension_datasource_filter(column_name="state", values=["Hawaii", "Alaska"], include_or_exclude='exclude') mod_filename = existing_tableau_file.save_new_file('Modified from Desktop') ``` -------------------------------- ### Download and Save Methods Source: https://github.com/bryanthowell-tableau/tableau_tools/blob/6.0.0/README.md Details methods for downloading or saving published content like workbooks and datasources, as well as preview images and thumbnails. These methods often require a filename and may optionally take a project name. ```APIDOC ## Download and Save Methods ### Description Methods for downloading the content of published items such as workbooks and datasources, or saving preview images. These methods require a filename to save the content. For workbooks and datasources, a project name may be optionally provided to specify the location. ### Methods - `TableauServerRest.workbooks.save_workbook_preview_image(wb_name_or_luid, filename)` - `TableauServerRest.workbooks.save_workbook_view_preview_image_by_luid(wb_name_or_luid, view_name_or_luid, filename)` - `TableauServerRest.datasources.download_datasource(ds_name_or_luid, filename_no_extension, proj_name_or_luid=None)` - `TableauServerRest.workbooks.download_workbook(wb_name_or_luid, filename_no_extension, proj_name_or_luid=None)` ### Endpoint Not applicable (These are class methods). ### Parameters #### Path Parameters - **wb_name_or_luid** (string) - Required - The name or LUID of the workbook. - **filename** (string) - Required - The name of the file to save the preview image to. - **view_name_or_luid** (string) - Required - The name or LUID of the view within the workbook. - **ds_name_or_luid** (string) - Required - The name or LUID of the datasource. - **filename_no_extension** (string) - Required - The base name for the downloaded file (extension will be added automatically). - **proj_name_or_luid** (string) - Optional - The name or LUID of the project containing the datasource or workbook. ### Request Example ```python # Save a workbook preview image TableauServerRest.workbooks.save_workbook_preview_image('MyWorkbook', 'workbook_preview.png') # Download a datasource TableauServerRest.datasources.download_datasource('MyDatasource', 'my_datasource_file', proj_name_or_luid='MyProject') ``` ### Response #### Success Response (200) - The file content is saved to the specified filename. ``` -------------------------------- ### Iterate Through Groups and Get Attributes Source: https://github.com/bryanthowell-tableau/tableau_tools/blob/6.0.0/README.md Shows how to iterate through a collection of group elements obtained from the Tableau REST API and extract specific attributes like 'id' and 'name' using the `.get()` method. This assumes a pre-existing ElementTree object representing groups. ```python import xml.etree.ElementTree as ET # Assuming 'groups' is an ElementTree object obtained from a query # Example: groups = t.groups.query_groups() for group in groups: print(ET.tostring(group)) group_luid = group.get('id') group_name = group.get('name') # Further processing with group_luid and group_name ``` -------------------------------- ### Create Tableau Subscription to View Source: https://github.com/bryanthowell-tableau/tableau_tools/blob/6.0.0/README.md Creates a subscription for a user to a specific view on a defined schedule. Requires view name/LUID, schedule name/LUID, and username/LUID. Optional workbook name/LUID and project name/LUID can also be provided. ```python TableauServerRest.subscriptions.create_subscription_to_view(subscription_subject, view_name_or_luid, schedule_name_or_luid, username_or_luid, wb_name_or_luid=None, project_name_or_luid=None) ``` -------------------------------- ### Query and Kill Tableau Sessions using Python Source: https://github.com/bryanthowell-tableau/tableau_tools/blob/6.0.0/README.md This example demonstrates how to query active Tableau Server sessions by username using the TableauRepository class and then subsequently kill a session using its session ID. This requires both TableauRepository and a connection object like TableauRestApiConnection. ```python t = TableauRestApiConnection27(server, username, password, site_content_url) t_rep = TableauRepository(server, repository_password=rep_pw) sessions_for_username = t_rep.query_sessions(username='some_username') for row in sessions_for_username: t.signout(row[0]) ``` -------------------------------- ### Download Datasource without Extension Source: https://github.com/bryanthowell-tableau/tableau_tools/blob/6.0.0/README.md Illustrates downloading a datasource. The `filename_no_extension` parameter is crucial, as the file extension will be appended automatically. This method also allows specifying the project for clarity. ```python TableauServerRest.datasources.download_datasource(ds_name_or_luid, filename_no_extension, proj_name_or_luid=None) ``` -------------------------------- ### Query Group LUID by Name Source: https://github.com/bryanthowell-tableau/tableau_tools/blob/6.0.0/README.md Provides an example of how to find the LUID (Logical Unique Identifier) for a group using its name. This is a utility method often used when another action requires the group's LUID. It's part of the main `TableauServerRest` class. ```python TableauServerRest.query_group_luid(name) ``` -------------------------------- ### Get Datasource Revisions using TableauServerRest Source: https://github.com/bryanthowell-tableau/tableau_tools/blob/6.0.0/README.md Retrieves a list of revisions for a specified data source on Tableau Server. This method requires the data source's name or LUID and optionally accepts a project name or LUID. It helps in tracking the version history of data sources. ```python from tableau_tools.tableau_server_rest_api.tableau_server_rest import TableauServerRest # Assuming 'tsr' is an authenticated TableauServerRest client instance # Assuming 'logger' is defined elsewhere for enable_logging # tsr.enable_logging(logger) datasource_name_or_luid = 'MyDataSource' project_name_or_luid = 'Default' datasource_revisions = tsr.revisions.get_datasource_revisions(datasource_name_or_luid, project_name_or_luid=project_name_or_luid) print(datasource_revisions) ``` -------------------------------- ### Create Tableau Subscription to Workbook Source: https://github.com/bryanthowell-tableau/tableau_tools/blob/6.0.0/README.md Creates a subscription for a user to a specific workbook on a defined schedule. Requires workbook name/LUID, schedule name/LUID, and username/LUID. An optional project name/LUID can also be provided. ```python TableauServerRest.subscriptions.create_subscription_to_workbook(subscription_subject, wb_name_or_luid, schedule_name_or_luid, username_or_luid, project_name_or_luid=None) ``` -------------------------------- ### Get Workbook Revisions using TableauServerRest Source: https://github.com/bryanthowell-tableau/tableau_tools/blob/6.0.0/README.md Retrieves a list of revisions for a given workbook on Tableau Server. This method requires the workbook's name or LUID and optionally accepts username/LUID and project name/LUID to scope the search. It's useful for auditing or understanding the version history of a workbook. ```python from tableau_tools.tableau_server_rest_api.tableau_server_rest import TableauServerRest # Assuming 'tsr' is an authenticated TableauServerRest client instance # Assuming 'logger' is defined elsewhere for enable_logging # tsr.enable_logging(logger) workbook_name_or_luid = 'MyWorkbook' project_name_or_luid = 'Default' username_or_luid = None # Or a specific user's name/LUID workbook_revisions = tsr.revisions.get_workbook_revisions(workbook_name_or_luid, username_or_luid=username_or_luid, project_name_or_luid=project_name_or_luid) print(workbook_revisions) ``` -------------------------------- ### Publishing a Datasource to Tableau Server Source: https://github.com/bryanthowell-tableau/tableau_tools/blob/6.0.0/README.md This Python code demonstrates publishing a data source to Tableau Server using the `TableauServerRest.datasources.publish_datasource` method. It takes the data source filename, desired name, and the target project object as parameters. You can specify whether to overwrite an existing data source and manage connection credentials. The data source file must be saved locally before publishing. ```python TableauServerRest.datasources.publish_datasource(ds_filename, ds_name, project_obj, overwrite=False, connection_username=None, connection_password=None, save_credentials=True) ``` -------------------------------- ### Translate Tableau Column Captions Source: https://github.com/bryanthowell-tableau/tableau_tools/blob/6.0.0/README.md This example shows how to use the `translate_captions` method to modify column aliases within Tableau datasources. It takes a dictionary mapping original captions to new ones, facilitating tasks like language translation. The code iterates through datasources and applies the translations, saving separate files for different language versions. ```python english_dict = { '{token1}': 'category', '{token2}': 'sub-category'} german_dict = { '{token1}': 'Kategorie', '{token2}': 'Unterkategorie'} tab_file = TableauFileManager('template_file.tds') dses = tab_file.datasources for ds in dses: ds.columns.translate_captions(english_dict) new_eng_filename = tab_file.save_new_file('English Version') # Reload template again tab_file = TableauFileManager('template_file.tds') dses = tab_file.datasources for ds in dses: ds.columns.translate_captions(german_dict) new_ger_filename = tab_file.save_new_file('German Version') ``` -------------------------------- ### Query Tableau Server Resources (Python) Source: https://github.com/bryanthowell-tableau/tableau_tools/blob/6.0.0/README.md The `query_resource` method sends an HTTP GET request to a Tableau Server endpoint and returns an XML Element. It can be used to fetch data for new endpoints not yet supported by dedicated library methods. It supports optional parameters for filtering, sorting, and specifying fields. A similar method, `query_resource_json`, returns a JSON response. ```Python xml = t.query_resource(url_ending="newthings") # or xml = t.query_resource(url_ending="newserverlevelthings", server_level=True) ``` -------------------------------- ### Query Workbooks and Find Project Element Source: https://github.com/bryanthowell-tableau/tableau_tools/blob/6.0.0/README.md Illustrates how to query workbooks from Tableau Server and then iterate through their elements to find and extract information from the nested 'project' element. It highlights the need to handle XML namespaces using `.find()`. ```python import xml.etree.ElementTree as ET from tableau_tools.rest_api import TableauServerRest # Assuming 't' is an initialized TableauServerRest object # Example: t = TableauServerRest(...) # t.signin() wbs = t.workbooks.query_workbooks() for wb in wbs: print(ET.tostring(wb)) for elem in wb: # Only want the project element inside if elem.tag.find('project') != -1: proj_luid = elem.get('id') # Further processing with proj_luid ``` -------------------------------- ### Download Workbook without Extension Source: https://github.com/bryanthowell-tableau/tableau_tools/blob/6.0.0/README.md Demonstrates downloading a workbook. Similar to datasource downloads, provide the filename without an extension, and the library handles the rest. The project name or LUID can also be specified. ```python TableauServerRest.workbooks.download_workbook(wb_name_or_luid, filename_no_extension, proj_name_or_luid=None) ``` -------------------------------- ### Applying Multiple Filters and Sorting - Python Source: https://github.com/bryanthowell-tableau/tableau_tools/blob/6.0.0/README.md Shows how to apply multiple filters (e.g., owner name, tags, creation date) and sorting to a `query_workbooks` call using `TableauServerRest`. This allows for precise data retrieval based on complex criteria. ```python import datetime from TableauServerRest import TableauServerRest t = TableauServerRest(server='', username='', password='') bryant_filter = t.url_filters.get_owner_name_filter('Bryant') t_filter = t.url_filters.get_tags_filter(['sales', 'sandbox']) now = datetime.datetime.now() offset_time = datetime.timedelta(days=1) time_to_filter_by = now - offset_time ca_filter = t.url_filters.get_created_at_filter('gte', time_to_filter_by) s = t.sorts.Ascending('name') t.workbooks.query_workbooks(owner_name_filter=bryant_filter, tags_filter=t_filter, created_at_filter=ca_filter, sorts=[s,]) ``` -------------------------------- ### Enable Logging for TableauServerRest (Python) Source: https://github.com/bryanthowell-tableau/tableau_tools/blob/6.0.0/README.md Shows how to enable logging for the TableauServerRest object by creating a Logger instance and passing it to the `enable_logging` method. This helps in debugging API interactions. ```python logger = Logger("log_file.txt") TableauServerRest.enable_logging(logger) ``` -------------------------------- ### Replicating Permissions Between Tableau Sites Source: https://github.com/bryanthowell-tableau/tableau_tools/blob/6.0.0/README.md This Python code demonstrates how to replicate permissions from one Tableau site to another using the `PublishedContent.convert_permissions_obj_list_from_orig_site_to_current_site` method. It shows how to copy project, workbook default, and data source default permissions. Ensure you have authenticated connections to both the originating and target sites. ```python orig_proj = o.projects.query_project(proj_name) new_proj = n.projects.query_project(proj_name) # Clear everything on the new one new_proj.clear_all_permissions() # Project Permissions o_perms_obj_list = orig_proj.current_perms_obj_list n_perms_obj_list = new_proj.convert_permissions_obj_list_from_orig_site_to_current_site(o_perms_obj_list, o) new_proj.set_permissions_by_permissions_obj_list(n_perms_obj_list) # Workbook Defaults o_perms_obj_list = orig_proj.workbook_defaults.current_perms_obj_list n_perms_obj_list = new_proj.workbook_defaults.convert_permissions_obj_list_from_orig_site_to_current_site(o_perms_obj_list, o) new_proj.workbook_defaults.set_permissions_by_permissions_obj_list(n_perms_obj_list) # Datasource Defaults o_perms_obj_list = orig_proj.datasource_defaults.current_perms_obj_list n_perms_obj_list = new_proj.datasource_defaults.convert_permissions_obj_list_from_orig_site_to_current_site(o_perms_obj_list, o) new_proj.datasource_defaults.set_permissions_by_permissions_obj_list(n_perms_obj_list) ``` -------------------------------- ### Import tableau_tools Library Source: https://github.com/bryanthowell-tableau/tableau_tools/blob/6.0.0/README.md Demonstrates how to import the tableau_tools library to access its functionalities. The basic import grants access to the tableau_rest_api sub-package, while additional imports are needed for tableau_documents. ```python from tableau_tools import * from tableau_tools.tableau_documents import * ``` -------------------------------- ### Publishing a Workbook to Tableau Server Source: https://github.com/bryanthowell-tableau/tableau_tools/blob/6.0.0/README.md This Python code shows how to publish a workbook to Tableau Server using the `TableauServerRest.workbooks.publish_workbook` method. It requires the workbook's filename, desired name, and the target project object. Options for overwriting, credentials, and handling published data sources are available. Ensure the workbook is saved locally before publishing. ```python TableauServerRest.workbooks.publish_workbook(workbook_filename, workbook_name, project_obj, overwrite=False, connection_username=None, connection_password=None, save_credentials=True, show_tabs=True, check_published_ds=True) ```