def get_project_id(project_name, server): """ Get the ID of a project Parameters: project_name -- name of the project the resource is stored in - REQUIRED server -- the server object - REQUIRED Return value(s): project_id -- ID of the resource Exception(s): NameError -- invalid project_name """ # set the filter options options = TSC.RequestOptions() options.filter.add( TSC.Filter(TSC.RequestOptions.Field.Name, TSC.RequestOptions.Operator.Equals, project_name)) # make request filtered_result, _ = server.projects.get(req_options=options) if not filtered_result: raise NameError("Invalid project_name '{}'".format(project_name)) # return the last object in the list (if there are multiple) return (filtered_result.pop().id)
def make_filter(**kwargs): options = TSC.RequestOptions() for item, value in kwargs.items(): name = getattr(TSC.RequestOptions.Field, item) options.filter.add( TSC.Filter(name, TSC.RequestOptions.Operator.Equals, value)) return options
def main(): parser = argparse.ArgumentParser(description="Cancel all of the running background jobs.") # Common options; please keep those in sync across all samples parser.add_argument("--server", "-s", required=True, help="server address") parser.add_argument("--site", "-S", help="site name") parser.add_argument( "--token-name", "-p", required=True, help="name of the personal access token used to sign into the server" ) parser.add_argument( "--token-value", "-v", required=True, help="value of the personal access token used to sign into the server" ) parser.add_argument( "--logging-level", "-l", choices=["debug", "info", "error"], default="error", help="desired logging level (set to error by default)", ) # Options specific to this sample # This sample has no additional options, yet. If you add some, please add them here args = parser.parse_args() # Set logging level based on user input, or error by default logging_level = getattr(logging, args.logging_level.upper()) logging.basicConfig(level=logging_level) tableau_auth = TSC.PersonalAccessTokenAuth(args.token_name, args.token_value, site_id=args.site) server = TSC.Server(args.server, use_server_version=True) with server.auth.sign_in(tableau_auth): req = TSC.RequestOptions() req.filter.add(TSC.Filter("progress", TSC.RequestOptions.Operator.LessThanOrEqual, 0)) for job in TSC.Pager(server.jobs, request_opts=req): print(server.jobs.cancel(job.id), job.id, job.status, job.type)
def generate_report(view_name): # site_id = site to log into, do not specify for default site tableau_auth = TSC.PersonalAccessTokenAuth("Slack API Token", token, site_id="") server = TSC.Server(server_url, use_server_version=True) # The new endpoint was introduced in Version 2.5 server.version = "2.5" with server.auth.sign_in(tableau_auth): # Query for the view that we want an image of req_option = TSC.RequestOptions() req_option.filter.add( TSC.Filter(TSC.RequestOptions.Field.Name, TSC.RequestOptions.Operator.Equals, view_name)) all_views, pagination_item = server.views.get(req_option) if not all_views: raise LookupError("View with the specified name was not found.") view_item = all_views[0] max_age = 1 if not max_age: max_age = 1 image_req_option = TSC.ImageRequestOptions( imageresolution=TSC.ImageRequestOptions.Resolution.High, maxage=max_age) server.views.populate_image(view_item, image_req_option) with open("{0}/view.png".format(view_location), "wb") as image_file: image_file.write(view_item.image)
def download_pdf(self, student_id, grade, name): view_name = "PDF Generator" with self.server.auth.sign_in(self.tableau_auth): req_option = TSC.RequestOptions() req_option.filter.add( TSC.Filter( TSC.RequestOptions.Field.Name, TSC.RequestOptions.Operator.Equals, view_name, )) all_views, pagination_item = self.server.views.get(req_option) if not all_views: raise LookupError( "View with the specified name was not found.") view = all_views[0] pdf_req_option = TSC.PDFRequestOptions( orientation=TSC.PDFRequestOptions.Orientation.Portrait, maxage=1, page_type=TSC.PDFRequestOptions.PageType.Letter, ) pdf_req_option.vf("StudentID", student_id) self.server.views.populate_pdf(view, pdf_req_option) filename = f"output/profile_{grade}_{name}_{student_id}.pdf" with open(filename, "wb") as pdf_file: pdf_file.write(view.pdf)
def test_filter_equals_list(self): with self.assertRaises(ValueError) as cm: TSC.Filter(TSC.RequestOptions.Field.Tags, TSC.RequestOptions.Operator.Equals, ['foo', 'bar']) self.assertEqual( "Filter values can only be a list if the operator is 'in'.", str(cm.exception)),
def _get_request_option(self, name=None, project_name=None, tag=None) -> TSC.RequestOptions: req_option = TSC.RequestOptions() if name: req_option.filter.add( TSC.Filter(TSC.RequestOptions.Field.Name, TSC.RequestOptions.Operator.Equals, name)) if project_name: req_option.filter.add( TSC.Filter(TSC.RequestOptions.Field.ProjectName, TSC.RequestOptions.Operator.Equals, project_name)) if tag: req_option.filter.add( TSC.Filter(TSC.RequestOptions.Field.Tags, TSC.RequestOptions.Operator.Equals, tag)) return req_option
def main(): # Get parsed arguments args = get_args() # Prompt the user to enter the password if args.p is None: password = getpass.getpass("Password: "******"" tableau_auth = TSC.TableauAuth(args.username, password, site_id=site_id) server = TSC.Server(args.server) # The new endpoint was introduced in Version 2.5 server.version = "2.8" # at least 2.5 for exporting a view image, 2.8 for exporting csv file with server.auth.sign_in(tableau_auth): # Step 2: Query for the view that we want an image/csv of req_option = TSC.RequestOptions() req_option.filter.add( TSC.Filter(TSC.RequestOptions.Field.Name, TSC.RequestOptions.Operator.Equals, args.view_name)) all_views, pagination_item = server.views.get(req_option) if not all_views: raise LookupError("View with the specified name was not found.") view_item = all_views[0] (populate_func_name, option_factory_name, member_name, extension) = args.type populate = getattr(server.views, populate_func_name) option_factory = getattr(TSC, option_factory_name) if args.filter: options = option_factory().vf(*args.filter.split(':')) else: options = None if args.file: filename = args.file else: filename = 'out.{}'.format(extension) populate(view_item, options) # Step 3: Export the file to the specified path/filename with open(filename, 'wb') as f: if member_name == 'csv': f.writelines(getattr(view_item, member_name)) else: f.write(getattr(view_item, member_name))
def get_items_by_name(logger, item_endpoint, item_name, container=None): logger.debug(_("export.status").format(item_name)) req_option = TSC.RequestOptions() req_option.filter.add( TSC.Filter(TSC.RequestOptions.Field.Name, TSC.RequestOptions.Operator.Equals, item_name)) if container: logger.debug("Searching in project {}".format(container)) req_option.filter.add( TSC.Filter(TSC.RequestOptions.Field.ParentProjectId, TSC.RequestOptions.Operator.Equals, container)) all_items, pagination_item = item_endpoint.get(req_option) if all_items is None or all_items == []: raise ValueError(_("publish.errors.server_resource_not_found")) if len(all_items) > 1: logger.debug( "{}+ items of this name were found. Returning first page.". format(len(all_items))) return all_items
def get_images(self, seller): with self.server.auth.sign_in(self.tableau_auth): all_views, pagination_item = self.server.views.get( ) # Get all views in Sales site all_project_items, pagination_item = self.server.projects.get( ) #Get all projects in Sales site all_workbooks, pagination_item = self.server.workbooks.get( ) #Get all workbooks in Sales site #Making filters req_option = TSC.RequestOptions() req_option.filter.add( TSC.Filter(TSC.RequestOptions.Field.Name, TSC.RequestOptions.Operator.Equals, 'Seller Detail')) matching_views, pagination_item = self.server.views.get(req_option) #Finding the right view: Seller_Details/MLC Daily View - Seller_Details/MLC Montly View real_matching_views = [] for view in matching_views: workbook = self.server.workbooks.get_by_id(view.workbook_id) #print(view.name + ": " + workbook.name) if workbook.name == "MLC Monthly View" or workbook.name == "MLC Daily View": real_matching_views.append(view) #print(view.name + ": " + workbook.name) Daily_view = real_matching_views[1] Monthly_view = real_matching_views[0] #Adding filter views #Seller filter -> done #Date range filter -> not yet -> not found *solution: create a new view with our date range if "OVIEDO" not in seller: daily_option_factory = getattr(TSC, "ImageRequestOptions") daily_options = daily_option_factory().vf( "SELLER_NAME", seller) montly_option_factory = getattr(TSC, "ImageRequestOptions") montly_options = montly_option_factory().vf( "Seller Name", seller) self.server.views.populate_image(Daily_view, daily_options) self.server.views.populate_image(Monthly_view, montly_options) else: self.server.views.populate_image(Daily_view) self.server.views.populate_image(Monthly_view) with open('monthly_view.png', 'wb') as f: f.write(Monthly_view.image) with open('daily_view.png', 'wb') as f: f.write(Daily_view.image)
def index(): username = False form = UserForm() #instance the form #check if form is calid on submission (also how to read those form fields) if form.validate_on_submit(): username = form.username.data form.username.data = '' #in previous line we have already saved the value of username so lets sut reset it to empty string now form.password.data = '' global tableau_ticket_return #now we are referencing the tableau_ticket_return from the top! tableau_ticket_return = requests.post( "http://localhost/trusted?username="******"\nWorkbook: ", item.name) for view in item.views: print("View:", view.name) return render_template('index-tableau.html', form=form, username=username, tableau_ticket_return=tableau_ticket_return)
def test_multiple_filter_options(self): with open(FILTER_MULTIPLE, 'rb') as f: response_xml = f.read().decode('utf-8') # To ensure that this is deterministic, run this a few times with requests_mock.mock() as m: # Sometimes pep8 requires you to do things you might not otherwise do url = ''.join( (self.baseurl, '/workbooks?pageNumber=1&pageSize=100&', 'filter=name:eq:foo,tags:in:[sample,safari,weather]')) m.get(url, text=response_xml) req_option = TSC.RequestOptions() req_option.filter.add( TSC.Filter(TSC.RequestOptions.Field.Tags, TSC.RequestOptions.Operator.In, ['sample', 'safari', 'weather'])) req_option.filter.add( TSC.Filter(TSC.RequestOptions.Field.Name, TSC.RequestOptions.Operator.Equals, 'foo')) for _ in range(100): matching_workbooks, pagination_item = self.server.workbooks.get( req_option) self.assertEqual(3, pagination_item.total_available)
def login(username=None, password=None, svr=None, email=None, siteurl=None, credential_path='credential.json'): if credential_path is not None: try: # Reading credentials from the json file credentials = open(credential_path).read() credentials = json.loads(credentials) # Setting Up Tableau Server Connection credentials from the credential file username = credentials.get('username') password = credentials.get('password') svr = credentials.get('server') email = credentials.get('email') siteurl = credentials.get('sitename') except Exception as e: return consolelog(f'Credentials could not be read because {e}') exit() else: if username is None or password is None or svr is None or email is None: return consolelog(f'Incomplete credentials provided') exit() try: consolelog('Signing in...') #Signing in to the Server tableau_auth = TSC.TableauAuth(username=username, password=password, site=siteurl) server = TSC.Server(svr) server.use_server_version() # Adding a filter for user related records req_option = TSC.RequestOptions() req_option.filter.add( TSC.Filter(TSC.RequestOptions.Field.OwnerEmail, TSC.RequestOptions.Operator.Equals, email)) # Running the login function to check if the credentials are okay server.auth.sign_in(tableau_auth) consolelog('Signed in!') except Exception as e: consolelog(f'Login failed because {e}') exit() time.sleep(2) return (tableau_auth, server, req_option)
def test_get_with_usage_and_filter(self): with open(GET_XML_USAGE, 'rb') as f: response_xml = f.read().decode('utf-8') with requests_mock.mock() as m: m.get(self.baseurl + "?includeUsageStatistics=true&filter=name:in:[foo,bar]", text=response_xml) options = TSC.RequestOptions() options.filter.add(TSC.Filter(TSC.RequestOptions.Field.Name, TSC.RequestOptions.Operator.In, ["foo", "bar"])) all_views, pagination_item = self.server.views.get(req_options=options, usage=True) self.assertEqual("ENDANGERED SAFARI", all_views[0].name) self.assertEqual(7, all_views[0].total_views) self.assertEqual("Overview", all_views[1].name) self.assertEqual(13, all_views[1].total_views)
def test_filter_equals(self): with requests_mock.mock() as m: m.get(requests_mock.ANY) url = "http://test/api/2.3/sites/dad65087-b08b-4603-af4e-2887b8aafc67/workbooks" opts = TSC.RequestOptions(pagesize=13, pagenumber=13) opts.filter.add( TSC.Filter(TSC.RequestOptions.Field.Name, TSC.RequestOptions.Operator.Equals, "Superstore")) resp = self.server.workbooks.get_request(url, request_object=opts) self.assertTrue(re.search("pagenumber=13", resp.request.query)) self.assertTrue(re.search("pagesize=13", resp.request.query)) self.assertTrue( re.search("filter=name%3aeq%3asuperstore", resp.request.query))
def test_filter_combo(self): with requests_mock.mock() as m: m.get(requests_mock.ANY) url = "http://test/api/2.3/sites/dad65087-b08b-4603-af4e-2887b8aafc67/users" opts = TSC.RequestOptions(pagesize=13, pagenumber=13) opts.filter.add(TSC.Filter(TSC.RequestOptions.Field.LastLogin, TSC.RequestOptions.Operator.GreaterThanOrEqual, '2017-01-15T00:00:00:00Z')) opts.filter.add(TSC.Filter(TSC.RequestOptions.Field.SiteRole, TSC.RequestOptions.Operator.Equals, 'Publisher')) resp = self.server.workbooks._make_request(requests.get, url, content=None, request_object=opts, auth_token='j80k54ll2lfMZ0tv97mlPvvSCRyD0DOM', content_type='text/xml') expected = 'pagenumber=13&pagesize=13&filter=lastlogin:gte:2017-01-15t00:00:00:00z,siterole:eq:publisher' self.assertEqual(resp.request.query, expected)
def test_filter_in(self): with requests_mock.mock() as m: m.get(requests_mock.ANY) url = "http://test/api/2.3/sites/dad65087-b08b-4603-af4e-2887b8aafc67/workbooks" opts = TSC.RequestOptions(pagesize=13, pagenumber=13) opts.filter.add( TSC.Filter(TSC.RequestOptions.Field.Tags, TSC.RequestOptions.Operator.In, ["stocks", "market"])) resp = self.server.workbooks.get_request(url, request_object=opts) self.assertTrue(re.search("pagenumber=13", resp.request.query)) self.assertTrue(re.search("pagesize=13", resp.request.query)) self.assertTrue( re.search("filter=tags%3ain%3a%5bstocks%2cmarket%5d", resp.request.query))
def main(): parser = argparse.ArgumentParser(description='Move one workbook from the default project to another.') parser.add_argument('--server', '-s', required=True, help='server address') parser.add_argument('--username', '-u', required=True, help='username to sign into server') parser.add_argument('--workbook-name', '-w', required=True, help='name of workbook to move') parser.add_argument('--destination-project', '-d', required=True, help='name of project to move workbook into') parser.add_argument('--logging-level', '-l', choices=['debug', 'info', 'error'], default='error', help='desired logging level (set to error by default)') args = parser.parse_args() password = getpass.getpass("Password: "******"Old project: {}".format(all_workbooks[0].project_name)) all_workbooks[0].project_id = dest_project.id target_workbook = server.workbooks.update(all_workbooks[0]) print("New project: {}".format(target_workbook.project_name)) else: error = "No workbook named {} found.".format(args.workbook_name) raise LookupError(error) else: error = "No project named {} found.".format(args.destination_project) raise LookupError(error)
def get_view_by_content_url(logger, server, view_content_url) -> TSC.ViewItem: logger.debug(_("export.status").format(view_content_url)) try: req_option = TSC.RequestOptions() req_option.filter.add( TSC.Filter("contentUrl", TSC.RequestOptions.Operator.Equals, view_content_url)) matching_views, paging = server.views.get(req_option) except TSC.ServerResponseError as e: Errors.exit_with_error( logger, _("publish.errors.unexpected_server_response").format("")) if len(matching_views) < 1: Errors.exit_with_error(logger, message=_("errors.xmlapi.not_found")) return matching_views[0]
def test_filter_in(self): with requests_mock.mock() as m: m.get(requests_mock.ANY) url = "http://test/api/2.3/sites/dad65087-b08b-4603-af4e-2887b8aafc67/workbooks" opts = TSC.RequestOptions(pagesize=13, pagenumber=13) opts.filter.add(TSC.Filter(TSC.RequestOptions.Field.Tags, TSC.RequestOptions.Operator.In, ['stocks', 'market'])) resp = self.server.workbooks._make_request(requests.get, url, content=None, request_object=opts, auth_token='j80k54ll2lfMZ0tv97mlPvvSCRyD0DOM', content_type='text/xml') self.assertEqual(resp.request.query, 'pagenumber=13&pagesize=13&filter=tags:in:[stocks,market]')
def test_filter_equals(self) -> None: with open(FILTER_EQUALS, "rb") as f: response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: m.get(self.baseurl + "/workbooks?filter=name:eq:RESTAPISample", text=response_xml) req_option = TSC.RequestOptions() req_option.filter.add( TSC.Filter(TSC.RequestOptions.Field.Name, TSC.RequestOptions.Operator.Equals, "RESTAPISample")) matching_workbooks, pagination_item = self.server.workbooks.get( req_option) self.assertEqual(2, pagination_item.total_available) self.assertEqual("RESTAPISample", matching_workbooks[0].name) self.assertEqual("RESTAPISample", matching_workbooks[1].name)
def main(): parser = argparse.ArgumentParser( description='Cancel all of the running background jobs') parser.add_argument('--server', '-s', required=True, help='server address') parser.add_argument( '--site', '-S', default=None, help='site to log into, do not specify for default site') parser.add_argument('--username', '-u', required=True, help='username to sign into server') parser.add_argument('--password', '-p', default=None, help='password for the user') parser.add_argument('--logging-level', '-l', choices=['debug', 'info', 'error'], default='error', help='desired logging level (set to error by default)') args = parser.parse_args() if args.password is None: password = getpass.getpass("Password: "******"progress", TSC.RequestOptions.Operator.LessThanOrEqual, 0)) for job in TSC.Pager(server.jobs, request_opts=req): print(server.jobs.cancel(job.id), job.id, job.status, job.type)
def get_wb_by_content_url(logger, server, workbook_content_url) -> TSC.WorkbookItem: logger.debug(_("export.status").format(workbook_content_url)) try: req_option = TSC.RequestOptions() req_option.filter.add( TSC.Filter("contentUrl", TSC.RequestOptions.Operator.Equals, workbook_content_url)) matching_workbooks, paging = server.workbooks.get(req_option) except TSC.ServerResponseError as e: Errors.exit_with_error( logger, _("publish.errors.unexpected_server_response").format("")) if len(matching_workbooks) < 1: Errors.exit_with_error( logger, message=_("dataalerts.failure.error.workbookNotFound")) return matching_workbooks[0]
def get_filtered_resources(server, filter_by, category): # set the filter request options = TSC.RequestOptions() options.filter.add( TSC.Filter(TSC.RequestOptions.Field.Name, TSC.RequestOptions.Operator.Equals, filter_by)) # send the request if category == "project": filtered_result, _ = server.projects.get(req_options=options) elif category == "view": filtered_result, _ = server.views.get(req_options=options) elif category == "workbook": filtered_result, _ = server.workbooks.get(req_options=options) elif category == "datasource": filtered_result, _ = server.datasources.get(req_options=options) # return the last object in the list (if there are multiple) return (filtered_result.pop())
def loginAsUser(): request_options = setPagination() isUserLoggedInToServer = False server, isUserLoggedInToServerAsAdmin = loginToServer() user_id = "" if isUserLoggedInToServerAsAdmin == True: username = session['user'] request_options.filter.add( TSC.Filter(TSC.RequestOptions.Field.Name, TSC.RequestOptions.Operator.Equals, username)) try: all_user_items, pagination_item = server.users.get(request_options) if all_user_items: user_id = all_user_items[0].id server, isUserLoggedInToServer = loginToServer(user_id) except: isUserLoggedInToServer = False return server, isUserLoggedInToServer, user_id
def get_resource_id(resource_type, resource_name, project_name, server): """ Get the ID of a workbook or view Parameters: resource_type -- type of the resource ('workbook'/'view') resource_name -- name of the resource project_name -- name of the project the resource is stored in server -- the server object Return value(s): resource_id -- ID of the resource resource_object -- object Exception(s): NameError -- if resource_type is neither workbook nor view NameError -- invalid project_name or invalid resource_name """ # set the filter request options = TSC.RequestOptions() options.filter.add( TSC.Filter(TSC.RequestOptions.Field.Name, TSC.RequestOptions.Operator.Equals, resource_name)) # how to filter by multiple values? if resource_type == 'workbook': filtered_result, _ = server.workbooks.get(req_options=options) elif resource_type == 'view': filtered_result, _ = server.views.get(req_options=options) elif resource_type == "datasource": filtered_result, _ = server.datasources.get(req_options=options) else: raise NameError("Invalid resource_type") if not filtered_result: raise NameError("No {} with the name '{}' on the server".format( resource_type, resource_name)) if resource_type == "view": result = filtered_result.pop() return (result.id, result) for result in filtered_result: if result.project_name == project_name: return (result.id, result) raise NameError( "No project with the name '{}' on the server".format(project_name))
def test_filter_tags_in(self) -> None: with open(FILTER_TAGS_IN, "rb") as f: response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: m.get(self.baseurl + "/workbooks?filter=tags:in:[sample,safari,weather]", text=response_xml) req_option = TSC.RequestOptions() req_option.filter.add( TSC.Filter(TSC.RequestOptions.Field.Tags, TSC.RequestOptions.Operator.In, ["sample", "safari", "weather"])) matching_workbooks, pagination_item = self.server.workbooks.get( req_option) self.assertEqual(3, pagination_item.total_available) self.assertEqual(set(["weather"]), matching_workbooks[0].tags) self.assertEqual(set(["safari"]), matching_workbooks[1].tags) self.assertEqual(set(["sample"]), matching_workbooks[2].tags)
def test_filter_tags_in(self): with open(FILTER_TAGS_IN, 'rb') as f: response_xml = f.read().decode('utf-8') with requests_mock.mock() as m: m.get(self.baseurl + '/workbooks?filter=tags:in:[sample,safari,weather]', text=response_xml) req_option = TSC.RequestOptions() req_option.filter.add( TSC.Filter(TSC.RequestOptions.Field.Tags, TSC.RequestOptions.Operator.In, ['sample', 'safari', 'weather'])) pagination_item, matching_workbooks = self.server.workbooks.get( req_option) self.assertEqual(3, pagination_item.total_available) self.assertEqual(set(['weather']), matching_workbooks[0].tags) self.assertEqual(set(['safari']), matching_workbooks[1].tags) self.assertEqual(set(['sample']), matching_workbooks[2].tags)
def update_workbooks_by_names(name_list, server, materialized_views_config): workbook_names = sanitize_workbook_list(name_list, "name") for workbook_name in workbook_names: req_option = TSC.RequestOptions() req_option.filter.add( TSC.Filter(TSC.RequestOptions.Field.Name, TSC.RequestOptions.Operator.Equals, workbook_name.rstrip())) workbooks = list(TSC.Pager(server.workbooks, req_option)) if len(workbooks) == 0: print( "Cannot find workbook name: {}, each line should only contain one workbook name" .format(workbook_name)) for workbook in workbooks: workbook.materialized_views_config = materialized_views_config server.workbooks.update(workbook) print( "Updated materialized views settings for workbook: {}".format( workbook.name)) print('\n')
def test_double_query_params(self) -> None: with requests_mock.mock() as m: m.get(requests_mock.ANY) url = self.baseurl + "/views?queryParamExists=true" opts = TSC.RequestOptions() opts.filter.add( TSC.Filter(TSC.RequestOptions.Field.Tags, TSC.RequestOptions.Operator.In, ["stocks", "market"])) opts.sort.add( TSC.Sort(TSC.RequestOptions.Field.Name, TSC.RequestOptions.Direction.Asc)) resp = self.server.workbooks.get_request(url, request_object=opts) self.assertTrue( re.search("queryparamexists=true", resp.request.query)) self.assertTrue( re.search("filter=tags%3ain%3a%5bstocks%2cmarket%5d", resp.request.query)) self.assertTrue(re.search("sort=name%3aasc", resp.request.query))