def query_view(authentication, name, workbook_id): """ Gets the workbook info and stores it :param authentication: authentication object that grants user access to API calls and holds any signin info :param name: the name of the workbook :return: """ url = authentication.server + "/api/{0}/sites/{1}/workbooks/{2}/views?includeUsageStatistics=true".format( Tools.VERSION, authentication.site_id, workbook_id) server_response = authentication.session.get( url, headers={'x-tableau-auth': authentication.get_token()}) Tools.check_status(server_response, 200) xml_response = ET.fromstring(Tools.encode_for_display( server_response.text)) views = xml_response.findall('.//t:view', namespaces=Tools.XMLNS) for v in views: if v.get('name') == name: # source_workbook_id = v.find('.//t:workbook', namespaces=Tools.XMLNS).get('id') # source_owner_id = v.find('.//t:owner', namespaces=Tools.XMLNS).get('id') # source_view_count = v.find('.//t:usage', namespaces=Tools.XMLNS).get('totalViewCount') view = View(v.get('name'), v.get('id'), v.get('contentUrl'), workbook_id) # source_owner_id, source_view_count) return view error = "View named '{0}' not found.".format(name) raise LookupError(error)
def get_workgroup_id(self, session, repos_url=""): """ for use with the vizportal API the repository(workgroup) id is required, this function gets said id. :param session: :param repos_url: :return: """ if repos_url: url = repos_url + "/vizportal/api/web/v1/setExtractTasksSchedule" else: url = self.authentication.server + "/vizportal/api/web/v1/setExtractTasksSchedule" payload = "{\"method\":\"getExtractTasks\",\"params\":{\"filter\":{\"operator\":\"and\",\"clauses\":[{\"operator\":\"eq\",\"field\":\"siteId\",\"value\":\"4\"}]},\"order\":[{\"field\":\"targetName\",\"ascending\":true}],\"page\":{\"startIndex\":0,\"maxItems\":1000}}}" xsrf_token = self.authentication.get_viz_token() # Make the request to server server_response = session.post(url, headers={ 'content-type': "application/json;charset=UTF-8", 'accept': "application/json, text/plain, */*", 'cache-control': "no-cache", 'X-XSRF-TOKEN': xsrf_token }, data=payload) response_json = json.loads(server_response.text) returned_task = response_json["result"]["tasks"] for s in returned_tasks: if s['name'] == self.name: # Todo not sure any frame of validation here, task id is the only consistent which this is identifying. self.workgroup_id = (s['id']) print(server_response) Tools.check_status(server_response, 200) # ASCII encode server response to enable displaying to console server_response = Tools.encode_for_display(server_response.text)
def get_workgroup_id(self, session, repos_url=""): if repos_url: url = repos_url + "/vizportal/api/web/v1/getSchedules" else: url = self.authentication.server + "/vizportal/api/web/v1/getSchedules" payload = "{\"method\":\"getSchedules\",\"params\":{\"filter\":{\"operator\":\"and\",\"clauses\":[{\"operator\":\"eq\", \"field\":\"siteId\", \"value\":\"4\"}]},\"order\":[{\"field\":\"name\",\"ascending\":true}],\"page\":{\"startIndex\":0,\"maxItems\":1000}}}" xsrf_token = self.authentication.get_viz_token() # Make the request to server server_response = session.post(url, headers={ 'content-type': "application/json;charset=UTF-8", 'accept': "application/json, text/plain, */*", 'cache-control': "no-cache", 'X-XSRF-TOKEN': xsrf_token }, data=payload) response_json = json.loads(server_response.text) returned_schedules = response_json["result"]["schedules"] for s in returned_schedules: if s['name'] == self.name: self.set_workgroup_id(s['id']) Tools.check_status(server_response, 200) # ASCII encode server response to enable displaying to console server_response = Tools.encode_for_display(server_response.text)
def set_task_schedule(self, task_id, schedule_id, session, repos_url=""): """ Again built using the vizportal API which is not recommended. :param task_id: :param schedule_id: :param session: :param repos_url: :return: """ if repos_url: url = repos_url + "/vizportal/api/web/v1/setExtractTasksSchedule" else: url = self.authentication.server + "/vizportal/api/web/v1/setExtractTasksSchedule" payload = "{\"method\":\"setExtractTasksSchedule\",\"params\":{\"ids\":[\"%s\"], \"scheduleId\":\"%s\"}}" % ( task_id, schedule_id) xsrf_token = self.authentication.get_viz_token() # Make the request to server server_response = session.post(url, headers={ 'content-type': "application/json;charset=UTF-8", 'accept': "application/json, text/plain, */*", 'cache-control': "no-cache", 'X-XSRF-TOKEN': xsrf_token }, data=payload) Tools.check_status(server_response, 200) # ASCII encode server response to enable displaying to console server_response = Tools.encode_for_display(server_response.text)
def query(authentication, log, name=""): """ Returns Project(s) from Tableau Server. :param authentication: <authentication obj> :class Auth: :param log: <logging obj> :param name: if not stated will return all projects on specified server. :return: """ logger = log done = False page_size = 100 page_number = 1 total_returned = 0 output_projects = [] if name == "": logger.debug("No name specified, pulling all projects") while not (done): url = authentication.server + "/api/{0}/sites/{1}/projects".format( Tools.VERSION, authentication.site_id) url += "?pageSize={0}&pageNumber={1}".format(page_size, page_number) server_response = authentication.session.get( url, headers={'x-tableau-auth': authentication.get_token()}) Tools.check_status(server_response, 200) xml_response = ET.fromstring( Tools.encode_for_display(server_response.text)) # Get total number of records from the <pagination> element total_available = xml_response.find('.//t:pagination', namespaces={ 't': "http://tableau.com/api" }).attrib['totalAvailable'] # Note! Need to convert "total_available" to integer total_available = int(total_available) page_number += 1 total_returned += page_size projects = xml_response.findall('.//t:project', namespaces=Tools.XMLNS) for p in projects: if name == "": project = Project(p.get('id'), p.get('name'), p.get('description'), p.get('contentPermission')) output_projects.append(project) elif p.get('name') == name: project = Project(p.get('id'), p.get('name'), p.get('description'), p.get('contentPermission')) return project if total_returned >= total_available: done = True if name == "": return output_projects error = "Project named '{0}' not found.".format(name) raise LookupError(error)
def get_project_id(server, project_name, auth_token, site_id): """ Returns the project ID for the project on the Tableau server. 'server' specified server address 'auth_token' authentication token that grants user access to API calls 'site_id' ID of the site that the user is signed into """ page_num, page_size = 1, 1000 # Default paginating values # Builds the request url = server + "/api/{0}/sites/{1}/projects".format(Tools.VERSION, site_id) paged_url = url + "?pageSize={0}&pageNumber={1}".format( page_size, page_num) server_response = requests.get(paged_url, headers={'x-tableau-auth': auth_token}) Tools.check_status(server_response, 200) xml_response = ET.fromstring(Tools.encode_for_display( server_response.text)) # Used to determine if more requests are required to find all projects on server total_projects = int( xml_response.find('t:pagination', namespaces=Tools.XMLNS).get('totalAvailable')) max_page = int(math.ceil(total_projects / page_size)) projects = xml_response.findall('.//t:project', namespaces=Tools.XMLNS) # Continue querying if more projects exist on the server for page in range(2, max_page + 1): paged_url = url + "?pageSize={0}&pageNumber={1}".format( page_size, page) server_response = requests.get(paged_url, headers={'x-tableau-auth': auth_token}) Tools.check_status(server_response, 200) xml_response = ET.fromstring( Tools.encode_for_display(server_response.text)) projects.extend( xml_response.findall('.//t:project', namespaces=Tools.XMLNS)) # Look through all projects to find the 'default' one for project in projects: if project.get('name') == project_name: # .replace(" ", ""): return project.get('id') raise LookupError("Project was not found on server")
def query_group(authentication, log, name=''): """ Returns group(s) from Tableau Server. :param authentication: <authentication obj> :class Auth: :param log: <logging obj> :param name: if not stated will return all groups on specified server. :return: <Group Obj> or list<Group Obj> """ logger = log done = False page_size = 100 page_number = 1 total_returned = 0 returned_groups = [] while not (done): url = authentication.server + "/api/{0}/sites/{1}/groups".format( Tools.VERSION, authentication.site_id) url += "?pageSize={0}&pageNumber={1}".format(page_size, page_number) server_response = authentication.session.get( url, headers={'x-tableau-auth': authentication.get_token()}) Tools.check_status(server_response, 200) xml_response = ET.fromstring( Tools.encode_for_display(server_response.text)) # Get total number of records from the <pagination> element total_available = xml_response.find('.//t:pagination', namespaces={ 't': "http://tableau.com/api" }).attrib['totalAvailable'] # Note! Need to convert "total_available" to integer total_available = int(total_available) page_number += 1 total_returned += page_size groups = xml_response.findall('.//t:group', namespaces=Tools.XMLNS) for g in groups: if name == '': domain_name = g.find('.//t:domain', namespaces=Tools.XMLNS).get('name') group = Group(g.get('id'), g.get('name'), domain_name, logger) returned_groups.append(group) elif g.get('name') == name: domain_name = g.find('.//t:domain', namespaces=Tools.XMLNS).get('name') group = Group(g.get('id'), g.get('name'), domain_name, logger) return group if total_returned >= total_available: done = True if name == "": return returned_groups error = "Group named '{0}' not found.".format(name) raise LookupError(error)
def query_user(authentication, log, name=""): """ Returns users(s) from Tableau Server. :param authentication: <authentication obj> :class Auth: :param log: <logging obj> :param name: if not stated will return all users on specified server. :return: <User Obj> or list<User Obj> """ logger = log done = False page_size = 100 page_number = 1 total_returned = 0 return_users = [] while not (done): url = authentication.server + "/api/{0}/sites/{1}/users".format( Tools.VERSION, authentication.site_id) url += "?pageSize={0}&pageNumber={1}".format(page_size, page_number) server_response = authentication.session.get( url, headers={'x-tableau-auth': authentication.get_token()}) Tools.check_status(server_response, 200) xml_response = ET.fromstring( Tools.encode_for_display(server_response.text)) # Get total number of records from the <pagination> element total_available = xml_response.find('.//t:pagination', namespaces={ 't': "http://tableau.com/api" }).attrib['totalAvailable'] # Note! Need to convert "total_available" to integer total_available = int(total_available) page_number += 1 total_returned += page_size users = xml_response.findall('.//t:user', namespaces=Tools.XMLNS) for u in users: if name != "": if u.get('name').upper() == name.upper(): user = User(u.get('id'), u.get('name'), u.get('siteRole'), u.get('lastLogin')) return user else: user = User(u.get('id'), u.get('name'), u.get('siteRole'), u.get('lastLogin')) return_users.append(user) if total_returned >= total_available: done = True if name == "": return return_users error = "User named '{0}' not found.".format(name) raise LookupError(error)
def create(self, type, start_time, frequency, interval="", end_time="", execution_order="Parallel", priority="50"): url = self.authentication.server + "/api/{0}/schedules".format( Tools.VERSION) # Builds the request xml_payload = ET.Element('tsRequest') schedule_element = ET.SubElement(xml_payload, 'schedule', name=self.name, priority=priority, type=type, frequency=frequency, executionOrder=execution_order) fd = ET.SubElement(schedule_element, 'frequencyDetails', start=start_time, end=end_time) if frequency != "Daily": intervals_element = ET.SubElement(fd, 'intervals') if frequency == "Hourly": ET.SubElement(intervals_element, 'interval', hours=interval, minutes=interval) elif frequency == "Weekly": ET.SubElement(intervals_element, 'interval', weekDay=interval) elif frequency == "Monthly": ET.SubElement(intervals_element, 'interval', monthDay=interval) xml_payload = ET.tostring(xml_payload) # Make the request to server server_response = requests.post( url, headers={'x-tableau-auth': self.authentication.get_token()}, data=xml_payload) Tools.check_status(server_response, 201) # ASCII encode server response to enable displaying to console server_response = Tools.encode_for_display(server_response.text) # Reads and parses the response parsed_response = ET.fromstring(server_response)
def start_upload_session(server, auth_token, site_id): """ Creates a POST request that initiates a file upload session. 'server' specified server address 'auth_token' authentication token that grants user access to API calls 'site_id' ID of the site that the user is signed into Returns a session ID that is used by subsequent functions to identify the upload session. """ url = server + "/api/{0}/sites/{1}/fileUploads".format( Tools.VERSION, site_id) server_response = requests.post(url, headers={'x-tableau-auth': auth_token}) Tools.check_status(server_response, 201) xml_response = ET.fromstring(Tools.encode_for_display( server_response.text)) return xml_response.find('t:fileUpload', namespaces=Tools.XMLNS).get('uploadSessionId')
def swap_site(self, site): url = self.server + "/api/{0}/auth/switchSite".format(Tools.VERSION) if site == "": site_name = "Default Site" else: site_name = site # Builds the request xml_payload = ET.Element('tsRequest') credentials_element = ET.SubElement(xml_payload, 'site', contentUrl=site.replace(" ", "")) xml_payload = ET.tostring(xml_payload) print("\nSwapping site to", site_name, "...") # Make the request to server server_response = self.session.post( url, headers={'x-tableau-auth': self.get_token()}, data=xml_payload) Tools.check_status(server_response, 200) # ASCII encode server response to enable displaying to console server_response = Tools.encode_for_display(server_response.text) # Reads and parses the response parsed_response = ET.fromstring(server_response) # Gets the auth token, site ID and user ID self.set_token( parsed_response.find('t:credentials', namespaces=Tools.XMLNS).get('token')) self.set_site_id( parsed_response.find('.//t:site', namespaces=Tools.XMLNS).get('id')) self.set_user_id( parsed_response.find('.//t:user', namespaces=Tools.XMLNS).get('id')) print("\nNow Signed into", site_name) return self.get_token
def get_details(self, authentication): done = False page_size = 100 page_number = 1 total_returned = 0 while not (done): url = authentication.server + "/api/{0}/sites/{1}/groups".format( Tools.VERSION, authentication.site_id) url += "?pageSize={0}&pageNumber={1}".format( page_size, page_number) server_response = authentication.session.get( url, headers={'x-tableau-auth': authentication.get_token()}) Tools.check_status(server_response, 200) xml_response = ET.fromstring( Tools.encode_for_display(server_response.text)) # Get total number of records from the <pagination> element total_available = xml_response.find('.//t:pagination', namespaces={ 't': "http://tableau.com/api" }).attrib['totalAvailable'] # Note! Need to convert "total_available" to integer total_available = int(total_available) page_number += 1 total_returned += page_size groups = xml_response.findall('.//t:group', namespaces=Tools.XMLNS) for g in groups: if g.get('name') == self.name: self.group_id = g.get('id') if self.domain_name == "": self.domain_name = g.find( './/t:domain', namespaces=Tools.XMLNS).get('name') return self if total_returned >= total_available: done = True error = "Group named '{0}' not found.".format(self.name) raise LookupError(error)
def sign_in_as(self, user_id): """Sign into tableau Server as a user. If user is not unique it will require domain. Creating the Authentication Token""" url = self.server + "/api/{0}/auth/signin".format(Tools.VERSION) # Builds the request xml_payload = ET.Element('tsRequest') credentials_element = ET.SubElement(xml_payload, 'credentials', name=self.username, password=self.password) ET.SubElement(credentials_element, 'site', contentUrl=self.site) ET.SubElement(credentials_element, 'user', id=user_id) xml_payload = ET.tostring(xml_payload) logger.info("\nSigning in as {}, to {} on the {} site...".format( self.username, self.server, self.site)) # Make the request to server server_response = self.session.post(url, data=xml_payload) Tools.check_status(server_response, 200) # ASCII encode server response to enable displaying to console server_response = Tools.encode_for_display(server_response.text) # Reads and parses the response parsed_response = ET.fromstring(server_response) logger.debug("Returned a response of {}".format(parsed_response)) # Gets the auth token, site ID and user ID of the signed in user. self.set_token( parsed_response.find('t:credentials', namespaces=Tools.XMLNS).get('token')) self.set_site_id( parsed_response.find('.//t:site', namespaces=Tools.XMLNS).get('id')) self.set_user_id( parsed_response.find('.//t:user', namespaces=Tools.XMLNS).get('id')) logger.info("\nSigned in as {}, to {} on the {} site...".format( self.username, self.server, self.site)) return self.get_token
def get_users(self, authentication): done = False page_size = 100 page_number = 1 total_returned = 0 users_in_group = [] while not (done): url = authentication.server + "/api/{0}/sites/{1}/groups/{2}/users".format( Tools.VERSION, authentication.site_id, self.group_id) url += "?pageSize={0}&pageNumber={1}".format( page_size, page_number) server_response = authentication.session.get( url, headers={'x-tableau-auth': authentication.get_token()}) Tools.check_status(server_response, 200) xml_response = ET.fromstring( Tools.encode_for_display(server_response.text)) # Get total number of records from the <pagination> element total_available = xml_response.find('.//t:pagination', namespaces={ 't': "http://tableau.com/api" }).attrib['totalAvailable'] # Note! Need to convert "total_available" to integer total_available = int(total_available) page_number += 1 total_returned += page_size users = xml_response.findall('.//t:user', namespaces=Tools.XMLNS) for u in users: user = User(u.get('id'), u.get('name'), u.get('siteRole'), u.get('lastLogin')) users_in_group.append(user) if total_returned >= total_available: done = True return users_in_group
def query_schedule(authentication, name="", frequency="", type=""): """ Gets the schedule info and stores it :param frequency: :param authentication: authentication object that grants user access to API calls and holds any signin info :param name: the name of the schedule :return: """ done = False page_size = 100 page_number = 1 total_returned = 0 while not (done): url = authentication.server + "/api/{0}/schedules".format( Tools.VERSION) url += "?pageSize={0}&pageNumber={1}".format(page_size, page_number) server_response = requests.get( url, headers={'x-tableau-auth': authentication.get_token()}) Tools.check_status(server_response, 200) xml_response = ET.fromstring( Tools.encode_for_display(server_response.text)) # Get total number of records from the <pagination> element total_available = xml_response.find('.//t:pagination', namespaces={ 't': "http://tableau.com/api" }).attrib['totalAvailable'] # Note! Need to convert "total_available" to integer total_available = int(total_available) page_number += 1 total_returned += page_size schedules = xml_response.findall('.//t:schedule', namespaces=Tools.XMLNS) output_schedules = [] for s in schedules: if name != "": if s.get('name') == name: schedule = Schedule(authentication, s.get('name'), s.get('id'), s.get('state'), s.get('priority'), s.get('createdAt'), s.get('updatedAt'), s.get('type'), s.get('frequency'), s.get('nextRunAt')) return schedule if frequency != "": if s.get('frequency') == frequency: if type != "": if s.get('type') == type: schedule = Schedule(authentication, s.get('name'), s.get('id'), s.get('state'), s.get('priority'), s.get('createdAt'), s.get('updatedAt'), s.get('type'), s.get('frequency'), s.get('nextRunAt')) else: schedule = Schedule(authentication, s.get('name'), s.get('id'), s.get('state'), s.get('priority'), s.get('createdAt'), s.get('updatedAt'), s.get('type'), s.get('frequency'), s.get('nextRunAt')) output_schedules.append(schedule) else: if type != "": if s.get('type') == type: schedule = Schedule(authentication, s.get('name'), s.get('id'), s.get('state'), s.get('priority'), s.get('createdAt'), s.get('updatedAt'), s.get('type'), s.get('frequency'), s.get('nextRunAt')) output_schedules.append(schedule) if total_returned >= total_available: done = True if len(output_schedules) > 0: return output_schedules error = "Schedule named '{0}' not found.".format(name) raise LookupError(error)
def update(self, name="", type="", start_time="", frequency="", interval="", end_time="", execution_order="Parallel", priority=""): if name == "": name = self.name if type == "": type = self.type if frequency == "": frequency = self.frequency if start_time == "": # (YYYY-MM-DDTHH:MM:SSZ) needs HH:MM:SS start_time = self.next_run_at # datetime.strptime(self.next_run_at, '%Y-%m-%dT%H:%M:%SZ') if time.localtime().tm_isdst == 1: start_time += timedelta(hours=1) start_time = start_time.strftime('%H:%M:%S') if priority == "": priority = self.priority url = self.authentication.server + "/api/{0}/schedules/{1}".format( Tools.VERSION, self.schedule_id) # Builds the request xml_payload = ET.Element('tsRequest') schedule_element = ET.SubElement(xml_payload, 'schedule', name=name, priority=priority, type=type, frequency=frequency, executionOrder=execution_order) fd = ET.SubElement(schedule_element, 'frequencyDetails', start=start_time, end=end_time) if frequency != "Daily": intervals_element = ET.SubElement(fd, 'intervals') if frequency == "Hourly": ET.SubElement(intervals_element, 'interval', hours=interval, minutes=interval) elif frequency == "Weekly": ET.SubElement(intervals_element, 'interval', weekDay=interval) elif frequency == "Monthly": ET.SubElement(intervals_element, 'interval', monthDay=interval) xml_payload = ET.tostring(xml_payload) # Make the request to server server_response = requests.put( url, headers={'x-tableau-auth': self.authentication.get_token()}, data=xml_payload) Tools.check_status(server_response, 200) # ASCII encode server response to enable displaying to console server_response = Tools.encode_for_display(server_response.text) # Reads and parses the response parsed_response = ET.fromstring(server_response)
def query_tasks(self): done = False page_size = 100 page_number = 1 total_returned = 0 while not (done): url = self.authentication.server + "/api/{0}/sites/{1}/schedules/{2}/extracts".format( Tools.VERSION, self.authentication.site_id, self.schedule_id) url += "?pageSize={0}&pageNumber={1}".format( page_size, page_number) server_response = requests.get( url, headers={'x-tableau-auth': self.authentication.get_token()}) Tools.check_status(server_response, 200) xml_response = ET.fromstring( Tools.encode_for_display(server_response.text)) # Get total number of records from the <pagination> element total_available = xml_response.find('.//t:pagination', namespaces={ 't': "http://tableau.com/api" }).attrib['totalAvailable'] # Note! Need to convert "total_available" to integer total_available = int(total_available) page_number += 1 total_returned += page_size tasks = xml_response.findall('.//t:extract', namespaces=Tools.XMLNS) output_tasks = [] for t in tasks: content_id = "" try: content_id = { "datasource": t.find('.//t:datasource', namespaces=Tools.XMLNS).get('id') } print("Datasource {}".format(content_id)) except AttributeError: content_id = { "workbook": t.find('.//t:workbook', namespaces=Tools.XMLNS).get('id') } print("Workbook {}".format(content_id)) # extract_refresh = t.find('.//t:extractRefresh', namespaces=Tools.XMLNS) extract_id = t.get('id') extract_priority = t.get('priority') # extract_fails = extract_refresh.get('consecutiveFailedCount') extract_type = t.get('type') schedule = self task = Task(self.authentication, extract_id, extract_priority, 0, extract_type, schedule, content_id) output_tasks.append(task) if total_returned >= total_available: done = True if len(output_tasks) > 0: return output_tasks error = "Tasks for the schedule '{0}' not found.".format(self.name) raise LookupError(error)
def query_tasks(authentication, task_id="", schedule_id=""): """ Gets the task info and stores it :param schedule_id: :param authentication: authentication object that grants user access to API calls and holds any signin info :param task_id: task ID for searching for specific task :return: """ if task_id == "": url = authentication.server + "/api/{0}/sites/{1}/tasks/extractRefreshes".format( Tools.VERSION, authentication.site_id) # url += "?pageSize={0}&pageNumber={1}".format(page_size, page_number) server_response = requests.get( url, headers={'x-tableau-auth': authentication.get_token()}) Tools.check_status(server_response, 200) xml_response = ET.fromstring( Tools.encode_for_display(server_response.text)) # Get total number of records from the <pagination> element # total_available = xml_response.find('.//t:pagination', # namespaces={'t': "http://tableau.com/api"}).attrib['totalAvailable'] # Note! Need to convert "total_available" to integer # total_available = int(total_available) # page_number += 1 # total_returned += page_size tasks = xml_response.findall('.//t:tasks', namespaces=Tools.XMLNS) output_tasks = [] if not schedule_id == "": for t in tasks: get_schedule = t.find('.//t:schedule', namespaces=Tools.XMLNS) if schedule_id == get_schedule.get('id'): extract_refresh = t.find('.//t:extractRefresh', namespaces=Tools.XMLNS) extract_id = extract_refresh.get('id') extract_priority = extract_refresh.get('priority') extract_fails = extract_refresh.get( 'consecutiveFailedCount') extract_type = extract_refresh.get('type') try: content_id = { "datasource": t.find('.//t:datasource', namespaces=Tools.XMLNS).get('id') } except AttributeError: content_id = { "workbook": t.find('.//t:workbook', namespaces=Tools.XMLNS).get('id') } schedule = Schedule(authentication, get_schedule.get('name'), get_schedule.get('id'), get_schedule.get('state'), get_schedule.get('priority'), get_schedule.get('createdAt'), get_schedule.get('updatedAt'), get_schedule.get('type'), get_schedule.get('frequency'), get_schedule.get('nextRunAt')) task = Task(authentication, extract_id, extract_priority, extract_fails, extract_type, schedule, content_id) output_tasks.append(task) elif schedule_id == "": for t in tasks: extract_refresh = t.find('.//t:extractRefresh', namespaces=Tools.XMLNS) extract_id = extract_refresh.get('id') extract_priority = extract_refresh.get('priority') extract_fails = extract_refresh.get('consecutiveFailedCount') extract_type = extract_refresh.get('type') get_schedule = t.find('.//t:schedule', namespaces=Tools.XMLNS) schedule = Schedule(authentication, get_schedule.get('name'), get_schedule.get('id'), get_schedule.get('state'), get_schedule.get('priority'), get_schedule.get('createdAt'), get_schedule.get('updatedAt'), get_schedule.get('type'), get_schedule.get('frequency'), get_schedule.get('nextRunAt')) try: content_id = { "datasource": t.find('.//t:datasource', namespaces=Tools.XMLNS).get('id') } except AttributeError: content_id = { "workbook": t.find('.//t:workbook', namespaces=Tools.XMLNS).get('id') } task = Task(authentication, extract_id, extract_priority, extract_fails, extract_type, schedule, content_id) output_tasks.append(task) # if total_returned >= total_available: # done = True else: url = authentication.server + "/api/{0}/sites/{1}/tasks/extractRefreshes".format( Tools.VERSION, authentication.site_id) # url += "?pageSize={0}&pageNumber={1}".format(page_size, page_number) server_response = requests.get( url, headers={'x-tableau-auth': authentication.get_token()}) Tools.check_status(server_response, 200) xml_response = ET.fromstring( Tools.encode_for_display(server_response.text)) # Get total number of records from the <pagination> element # total_available = xml_response.find('.//t:pagination', # namespaces={'t': "http://tableau.com/api"}).attrib['totalAvailable'] # Note! Need to convert "total_available" to integer # total_available = int(total_available) # page_number += 1 # total_returned += page_size tasks = xml_response.findall('.//t:tasks', namespaces=Tools.XMLNS) output_tasks = [] if not schedule_id == "": for t in tasks: get_schedule = t.find('.//t:schedule', namespaces=Tools.XMLNS) if schedule_id == get_schedule.get('id'): extract_refresh = t.find('.//t:extractRefresh', namespaces=Tools.XMLNS) extract_id = extract_refresh.get('id') extract_priority = extract_refresh.get('priority') extract_fails = extract_refresh.get( 'consecutiveFailedCount') extract_type = extract_refresh.get('type') try: content_id = { "datasource": t.find('.//t:datasource', namespaces=Tools.XMLNS).get('id') } except AttributeError: content_id = { "workbook": t.find('.//t:workbook', namespaces=Tools.XMLNS).get('id') } schedule = Schedule(authentication, get_schedule.get('name'), get_schedule.get('id'), get_schedule.get('state'), get_schedule.get('priority'), get_schedule.get('createdAt'), get_schedule.get('updatedAt'), get_schedule.get('type'), get_schedule.get('frequency'), get_schedule.get('nextRunAt')) task = Task(authentication, extract_id, extract_priority, extract_fails, extract_type, schedule, content_id) output_tasks.append(task) elif schedule_id == "": for t in tasks: if task_id == t.find('.//t:extractRefresh', namespaces=Tools.XMLNS).get('id'): extract_refresh = t.find('.//t:extractRefresh', namespaces=Tools.XMLNS) extract_id = extract_refresh.get('id') extract_priority = extract_refresh.get('priority') extract_fails = extract_refresh.get( 'consecutiveFailedCount') extract_type = extract_refresh.get('type') get_schedule = t.find('.//t:schedule', namespaces=Tools.XMLNS) schedule = Schedule(authentication, get_schedule.get('name'), get_schedule.get('id'), get_schedule.get('state'), get_schedule.get('priority'), get_schedule.get('createdAt'), get_schedule.get('updatedAt'), get_schedule.get('type'), get_schedule.get('frequency'), get_schedule.get('nextRunAt')) try: content_id = { "datasource": t.find('.//t:datasource', namespaces=Tools.XMLNS).get('id') } except AttributeError: content_id = { "workbook": t.find('.//t:workbook', namespaces=Tools.XMLNS).get('id') } task = Task(authentication, extract_id, extract_priority, extract_fails, extract_type, schedule, content_id) output_tasks.append(task) if len(output_tasks) > 0: return output_tasks error = "Tasks associated with '{0}{1}' were not found.".format( task_id, schedule_id) raise LookupError(error)
def query(authentication, log, name="", project_id=""): """ Gets the workbook info and stores it :param authentication: authentication object that grants user access to API calls and holds any signin info :param name: the name of the workbook :return: """ done = False page_size = 100 page_number = 1 total_returned = 0 logger = log output_twbs = [] if name == "": logger.debug("No name specified, pulling all workbooks") while not (done): # try: url = authentication.server + "/api/{0}/sites/{1}/workbooks".format( Tools.VERSION, authentication.site_id) url += "?pageSize={0}&pageNumber={1}".format(page_size, page_number) server_response = authentication.session.get( url, headers={'x-tableau-auth': authentication.get_token()}) Tools.check_status(server_response, 200) xml_response = ET.fromstring( Tools.encode_for_display(server_response.text)) # Get total number of records from the <pagination> element total_available = xml_response.find('.//t:pagination', namespaces={ 't': "http://tableau.com/api" }).attrib['totalAvailable'] # Note! Need to convert "total_available" to integer total_available = int(total_available) page_number += 1 total_returned += page_size workbooks = xml_response.findall('.//t:workbook', namespaces=Tools.XMLNS) for w in workbooks: if name == "": if project_id == "": source_project_id = w.find( './/t:project', namespaces=Tools.XMLNS).get('id') workbook = Workbook(w.get('name'), w.get('id'), w.get('contentUrl'), w.get('createdAt'), w.get('updatedAt'), source_project_id) output_twbs.append(workbook) else: if w.find('.//t:project', namespaces=Tools.XMLNS).get('id') == project_id: logger.debug("Match found for given project_id") source_project_id = w.find( './/t:project', namespaces=Tools.XMLNS).get('id') workbook = Workbook(w.get('name'), w.get('id'), w.get('contentUrl'), w.get('createdAt'), w.get('updatedAt'), 'source_project_id)') output_twbs.append(workbook) else: continue elif w.get('name') == name: source_project_id = w.find('.//t:project', namespaces=Tools.XMLNS).get('id') workbook = Workbook(w.get('name'), w.get('id'), w.get('contentUrl'), w.get('createdAt'), w.get('updatedAt'), source_project_id) return workbook if total_returned >= total_available: done = True if name == "": return output_twbs error = "Workbook named '{0}' not found.".format(name) raise LookupError(error)