From 4815b6a1f39d79ea0d13af4e58f09b58d6ba270c Mon Sep 17 00:00:00 2001 From: Jordan Woods Date: Thu, 9 Dec 2021 22:00:10 -0600 Subject: [PATCH 01/13] Add type hints for schedules --- tableauserverclient/models/schedule_item.py | 58 ++++++++++--------- .../server/endpoint/schedules_endpoint.py | 37 +++++++----- tableauserverclient/server/request_factory.py | 9 ++- test/test_schedule.py | 36 ++++++------ 4 files changed, 77 insertions(+), 63 deletions(-) diff --git a/tableauserverclient/models/schedule_item.py b/tableauserverclient/models/schedule_item.py index f8baf0749..2130976a5 100644 --- a/tableauserverclient/models/schedule_item.py +++ b/tableauserverclient/models/schedule_item.py @@ -1,5 +1,6 @@ import xml.etree.ElementTree as ET from datetime import datetime +from typing import Optional, Union from .interval_item import ( IntervalItem, @@ -15,6 +16,7 @@ ) from ..datetime_helpers import parse_datetime +Interval = Union[HourlyInterval, DailyInterval, WeeklyInterval, MonthlyInterval] class ScheduleItem(object): class Type: @@ -31,86 +33,86 @@ class State: Active = "Active" Suspended = "Suspended" - def __init__(self, name, priority, schedule_type, execution_order, interval_item): - self._created_at = None - self._end_schedule_at = None - self._id = None - self._next_run_at = None - self._state = None - self._updated_at = None - self.interval_item = interval_item - self.execution_order = execution_order - self.name = name - self.priority = priority - self.schedule_type = schedule_type + def __init__(self, name: str, priority: int, schedule_type: str, execution_order: str, interval_item: Interval): + self._created_at: Optional[datetime] = None + self._end_schedule_at: Optional[datetime] = None + self._id: Optional[str] = None + self._next_run_at: Optional[datetime] = None + self._state: Optional[str] = None + self._updated_at: Optional[datetime] = None + self.interval_item: Interval = interval_item + self.execution_order: str = execution_order + self.name: str = name + self.priority: int = priority + self.schedule_type: str = schedule_type def __repr__(self): - return ''.format(**self.__dict__) + return ''.format(**vars(self)) @property - def created_at(self): + def created_at(self) -> Optional[datetime]: return self._created_at @property - def end_schedule_at(self): + def end_schedule_at(self) -> Optional[datetime]: return self._end_schedule_at @property - def execution_order(self): + def execution_order(self) -> str: return self._execution_order @execution_order.setter @property_is_enum(ExecutionOrder) - def execution_order(self, value): + def execution_order(self, value: str): self._execution_order = value @property - def id(self): + def id(self) -> Optional[str]: return self._id @property - def name(self): + def name(self) -> str: return self._name @name.setter @property_not_nullable - def name(self, value): + def name(self, value: str): self._name = value @property - def next_run_at(self): + def next_run_at(self) -> Optional[datetime]: return self._next_run_at @property - def priority(self): + def priority(self) -> int: return self._priority @priority.setter @property_is_int(range=(1, 100)) - def priority(self, value): + def priority(self, value: int): self._priority = value @property - def schedule_type(self): + def schedule_type(self) -> str: return self._schedule_type @schedule_type.setter @property_is_enum(Type) @property_not_nullable - def schedule_type(self, value): + def schedule_type(self, value: str): self._schedule_type = value @property - def state(self): + def state(self) -> Optional[str]: return self._state @state.setter @property_is_enum(State) - def state(self, value): + def state(self, value: str): self._state = value @property - def updated_at(self): + def updated_at(self) -> Optional[datetime]: return self._updated_at @property diff --git a/tableauserverclient/server/endpoint/schedules_endpoint.py b/tableauserverclient/server/endpoint/schedules_endpoint.py index d582dca26..28f8d7650 100644 --- a/tableauserverclient/server/endpoint/schedules_endpoint.py +++ b/tableauserverclient/server/endpoint/schedules_endpoint.py @@ -4,24 +4,29 @@ import logging import copy from collections import namedtuple +from typing import TYPE_CHECKING, Callable, List, Optional, Tuple, Union logger = logging.getLogger("tableau.endpoint.schedules") # Oh to have a first class Result concept in Python... AddResponse = namedtuple("AddResponse", ("result", "error", "warnings", "task_created")) OK = AddResponse(result=True, error=None, warnings=None, task_created=None) +if TYPE_CHECKING: + from ..request_options import RequestOptions + from ...models import DatasourceItem, WorkbookItem + class Schedules(Endpoint): @property - def baseurl(self): + def baseurl(self) -> str: return "{0}/schedules".format(self.parent_srv.baseurl) @property - def siteurl(self): + def siteurl(self) -> str: return "{0}/sites/{1}/schedules".format(self.parent_srv.baseurl, self.parent_srv.site_id) @api(version="2.3") - def get(self, req_options=None): + def get(self, req_options: Optional["RequestOptions"] = None) -> Tuple[List[ScheduleItem], PaginationItem]: logger.info("Querying all schedules") url = self.baseurl server_response = self.get_request(url, req_options) @@ -30,7 +35,7 @@ def get(self, req_options=None): return all_schedule_items, pagination_item @api(version="2.3") - def delete(self, schedule_id): + def delete(self, schedule_id: str) -> None: if not schedule_id: error = "Schedule ID undefined" raise ValueError(error) @@ -39,7 +44,7 @@ def delete(self, schedule_id): logger.info("Deleted single schedule (ID: {0})".format(schedule_id)) @api(version="2.3") - def update(self, schedule_item): + def update(self, schedule_item: ScheduleItem) -> ScheduleItem: if not schedule_item.id: error = "Schedule item missing ID." raise MissingRequiredFieldError(error) @@ -52,7 +57,7 @@ def update(self, schedule_item): return updated_schedule._parse_common_tags(server_response.content, self.parent_srv.namespace) @api(version="2.3") - def create(self, schedule_item): + def create(self, schedule_item: ScheduleItem) -> ScheduleItem: if schedule_item.interval_item is None: error = "Interval item must be defined." raise MissingRequiredFieldError(error) @@ -67,15 +72,19 @@ def create(self, schedule_item): @api(version="2.8") def add_to_schedule( self, - schedule_id, - workbook=None, - datasource=None, - task_type=TaskItem.Type.ExtractRefresh, - ): - def add_to(resource, type_, req_factory): + schedule_id: str, + workbook: "WorkbookItem" = None, + datasource: "DatasourceItem" = None, + task_type: str = TaskItem.Type.ExtractRefresh, + ) -> List[AddResponse]: + def add_to( + resource: Union["DatasourceItem", "WorkbookItem"], + type_: str, + req_factory: Callable[[str, str,], bytes] + ) -> AddResponse: id_ = resource.id url = "{0}/{1}/{2}s".format(self.siteurl, schedule_id, type_) - add_req = req_factory(id_, task_type=task_type) + add_req = req_factory(id_, task_type=task_type) # type: ignore[call-arg, arg-type] response = self.put_request(url, add_req) error, warnings, task_created = ScheduleItem.parse_add_to_schedule_response( @@ -99,7 +108,7 @@ def add_to(resource, type_, req_factory): if workbook is not None: items.append((workbook, "workbook", RequestFactory.Schedule.add_workbook_req)) if datasource is not None: - items.append((datasource, "datasource", RequestFactory.Schedule.add_datasource_req)) + items.append((datasource, "datasource", RequestFactory.Schedule.add_datasource_req)) # type:ignore[arg-type] results = (add_to(*x) for x in items) # list() is needed for python 3.x compatibility diff --git a/tableauserverclient/server/request_factory.py b/tableauserverclient/server/request_factory.py index 1e0c357dc..395971ed1 100644 --- a/tableauserverclient/server/request_factory.py +++ b/tableauserverclient/server/request_factory.py @@ -5,6 +5,7 @@ from ..models import TaskItem, UserItem, GroupItem, PermissionsRule, FavoriteItem +from typing import Optional def _add_multipart(parts): mime_multipart_parts = list() @@ -474,7 +475,7 @@ def update_req(self, schedule_item): single_interval_element.attrib[expression] = value return ET.tostring(xml_request) - def _add_to_req(self, id_, target_type, task_type=TaskItem.Type.ExtractRefresh): + def _add_to_req(self, id_: Optional[str], target_type: str, task_type: str = TaskItem.Type.ExtractRefresh) -> bytes: """ @@ -483,6 +484,8 @@ def _add_to_req(self, id_, target_type, task_type=TaskItem.Type.ExtractRefresh): """ + if not isinstance(id_, str): + raise ValueError(f"id_ should be a string, reeceived: {type(id_)}") xml_request = ET.Element("tsRequest") task_element = ET.SubElement(xml_request, "task") task = ET.SubElement(task_element, task_type) @@ -491,10 +494,10 @@ def _add_to_req(self, id_, target_type, task_type=TaskItem.Type.ExtractRefresh): return ET.tostring(xml_request) - def add_workbook_req(self, id_, task_type=TaskItem.Type.ExtractRefresh): + def add_workbook_req(self, id_: Optional[str], task_type: str = TaskItem.Type.ExtractRefresh) -> bytes: return self._add_to_req(id_, "workbook", task_type) - def add_datasource_req(self, id_, task_type=TaskItem.Type.ExtractRefresh): + def add_datasource_req(self, id_: Optional[str], task_type: str = TaskItem.Type.ExtractRefresh) -> bytes: return self._add_to_req(id_, "datasource", task_type) diff --git a/test/test_schedule.py b/test/test_schedule.py index 3a84caeb9..2302f6139 100644 --- a/test/test_schedule.py +++ b/test/test_schedule.py @@ -23,7 +23,7 @@ class ScheduleTests(unittest.TestCase): - def setUp(self): + def setUp(self) -> None: self.server = TSC.Server("http://test") # Fake Signin @@ -32,7 +32,7 @@ def setUp(self): self.baseurl = self.server.schedules.baseurl - def test_get(self): + def test_get(self) -> None: with open(GET_XML, "rb") as f: response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: @@ -71,7 +71,7 @@ def test_get(self): self.assertEqual("Flow", flow.schedule_type) self.assertEqual("2019-03-01T09:00:00Z", format_datetime(flow.next_run_at)) - def test_get_empty(self): + def test_get_empty(self) -> None: with open(GET_EMPTY_XML, "rb") as f: response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: @@ -81,12 +81,12 @@ def test_get_empty(self): self.assertEqual(0, pagination_item.total_available) self.assertEqual([], all_schedules) - def test_delete(self): + def test_delete(self) -> None: with requests_mock.mock() as m: m.delete(self.baseurl + "/c9cff7f9-309c-4361-99ff-d4ba8c9f5467", status_code=204) self.server.schedules.delete("c9cff7f9-309c-4361-99ff-d4ba8c9f5467") - def test_create_hourly(self): + def test_create_hourly(self) -> None: with open(CREATE_HOURLY_XML, "rb") as f: response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: @@ -108,10 +108,10 @@ def test_create_hourly(self): self.assertEqual("2016-09-16T01:30:00Z", format_datetime(new_schedule.next_run_at)) self.assertEqual(TSC.ScheduleItem.ExecutionOrder.Parallel, new_schedule.execution_order) self.assertEqual(time(2, 30), new_schedule.interval_item.start_time) - self.assertEqual(time(23), new_schedule.interval_item.end_time) - self.assertEqual("8", new_schedule.interval_item.interval) + self.assertEqual(time(23), new_schedule.interval_item.end_time) # type: ignore[union-attr] + self.assertEqual("8", new_schedule.interval_item.interval) # type: ignore[union-attr] - def test_create_daily(self): + def test_create_daily(self) -> None: with open(CREATE_DAILY_XML, "rb") as f: response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: @@ -132,7 +132,7 @@ def test_create_daily(self): self.assertEqual(TSC.ScheduleItem.ExecutionOrder.Serial, new_schedule.execution_order) self.assertEqual(time(4, 45), new_schedule.interval_item.start_time) - def test_create_weekly(self): + def test_create_weekly(self) -> None: with open(CREATE_WEEKLY_XML, "rb") as f: response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: @@ -155,12 +155,12 @@ def test_create_weekly(self): self.assertEqual(TSC.ScheduleItem.ExecutionOrder.Parallel, new_schedule.execution_order) self.assertEqual(time(9, 15), new_schedule.interval_item.start_time) self.assertEqual(("Monday", "Wednesday", "Friday"), - new_schedule.interval_item.interval) + new_schedule.interval_item.interval) # type: ignore[union-attr] self.assertEqual(2, len(new_schedule.warnings)) self.assertEqual("warning 1", new_schedule.warnings[0]) self.assertEqual("warning 2", new_schedule.warnings[1]) - def test_create_monthly(self): + def test_create_monthly(self) -> None: with open(CREATE_MONTHLY_XML, "rb") as f: response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: @@ -180,9 +180,9 @@ def test_create_monthly(self): self.assertEqual("2016-10-12T14:00:00Z", format_datetime(new_schedule.next_run_at)) self.assertEqual(TSC.ScheduleItem.ExecutionOrder.Serial, new_schedule.execution_order) self.assertEqual(time(7), new_schedule.interval_item.start_time) - self.assertEqual("12", new_schedule.interval_item.interval) + self.assertEqual("12", new_schedule.interval_item.interval) # type: ignore[union-attr] - def test_update(self): + def test_update(self) -> None: with open(UPDATE_XML, "rb") as f: response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: @@ -204,11 +204,11 @@ def test_update(self): self.assertEqual(TSC.ScheduleItem.ExecutionOrder.Parallel, single_schedule.execution_order) self.assertEqual(time(7), single_schedule.interval_item.start_time) self.assertEqual(("Monday", "Friday"), - single_schedule.interval_item.interval) + single_schedule.interval_item.interval) # type: ignore[union-attr] self.assertEqual(TSC.ScheduleItem.State.Suspended, single_schedule.state) # Tests calling update with a schedule item returned from the server - def test_update_after_get(self): + def test_update_after_get(self) -> None: with open(GET_XML, "rb") as f: get_response_xml = f.read().decode("utf-8") with open(UPDATE_XML, "rb") as f: @@ -232,7 +232,7 @@ def test_update_after_get(self): self.assertEqual(TSC.ScheduleItem.State.Suspended, schedule_item.state) self.assertEqual('weekly-schedule-1', schedule_item.name) - def test_add_workbook(self): + def test_add_workbook(self) -> None: self.server.version = "2.8" baseurl = "{}/sites/{}/schedules".format(self.server.baseurl, self.server.site_id) @@ -247,7 +247,7 @@ def test_add_workbook(self): result = self.server.schedules.add_to_schedule('foo', workbook=workbook) self.assertEqual(0, len(result), "Added properly") - def test_add_workbook_with_warnings(self): + def test_add_workbook_with_warnings(self) -> None: self.server.version = "2.8" baseurl = "{}/sites/{}/schedules".format(self.server.baseurl, self.server.site_id) @@ -263,7 +263,7 @@ def test_add_workbook_with_warnings(self): self.assertEqual(1, len(result), "Not added properly") self.assertEqual(2, len(result[0].warnings)) - def test_add_datasource(self): + def test_add_datasource(self) -> None: self.server.version = "2.8" baseurl = "{}/sites/{}/schedules".format(self.server.baseurl, self.server.site_id) From 83cfbe7cbd54abd64a0d78b19414015ef05b5fe8 Mon Sep 17 00:00:00 2001 From: Jordan Woods Date: Thu, 27 Jan 2022 21:58:11 -0600 Subject: [PATCH 02/13] Squashed commit of the following: commit b836f331f6fa46141526050f60b8d62e591f5f91 Author: Brian Cantoni Date: Thu Jan 27 19:29:50 2022 -0800 WIP: Enable Black for CI and add as dependency (#935) * Enable Black for CI and add as dependency * Bulk reformat with Black, line length 120 Co-authored-by: Jac Fitzgerald --- .github/workflows/run-tests.yml | 4 + samples/add_default_permission.py | 32 +- samples/create_group.py | 29 +- samples/create_project.py | 37 +- samples/create_schedules.py | 79 +- samples/download_view_image.py | 44 +- samples/explore_datasource.py | 44 +- samples/explore_webhooks.py | 35 +- samples/explore_workbook.py | 50 +- samples/export.py | 60 +- samples/export_wb.py | 41 +- samples/filter_sort_groups.py | 60 +- samples/filter_sort_projects.py | 73 +- samples/initialize_server.py | 43 +- samples/kill_all_jobs.py | 27 +- samples/list.py | 41 +- samples/login.py | 33 +- samples/metadata_query.py | 44 +- samples/move_workbook_projects.py | 36 +- samples/move_workbook_sites.py | 55 +- samples/pagination_sample.py | 27 +- samples/publish_datasource.py | 62 +- samples/publish_workbook.py | 56 +- samples/query_permissions.py | 46 +- samples/refresh.py | 33 +- samples/refresh_tasks.py | 37 +- samples/set_http_options.py | 33 +- samples/set_refresh_schedule.py | 32 +- samples/update_connection.py | 44 +- samples/update_datasource_data.py | 33 +- setup.cfg | 4 - setup.py | 2 +- tableauserverclient/__init__.py | 2 +- tableauserverclient/_version.py | 8 +- tableauserverclient/models/flow_run_item.py | 40 +- tableauserverclient/models/job_item.py | 2 +- tableauserverclient/models/revision_item.py | 10 +- tableauserverclient/server/__init__.py | 2 +- .../server/endpoint/datasources_endpoint.py | 29 +- .../server/endpoint/endpoint.py | 1 + .../server/endpoint/exceptions.py | 4 +- .../server/endpoint/flow_runs_endpoint.py | 6 +- .../server/endpoint/jobs_endpoint.py | 3 +- .../server/endpoint/projects_endpoint.py | 4 +- .../server/endpoint/workbooks_endpoint.py | 24 +- tableauserverclient/server/request_factory.py | 2 +- tableauserverclient/server/server.py | 2 +- test/_utils.py | 8 +- test/test_auth.py | 126 +-- test/test_data_acceleration_report.py | 8 +- test/test_dataalert.py | 106 +-- test/test_database.py | 98 +- test/test_datasource.py | 624 ++++++------ test/test_exponential_backoff.py | 5 +- test/test_favorites.py | 117 ++- test/test_filesys_helpers.py | 48 +- test/test_fileuploads.py | 46 +- test/test_flow.py | 152 +-- test/test_flowruns.py | 77 +- test/test_group.py | 255 ++--- test/test_job.py | 60 +- test/test_metadata.py | 85 +- test/test_pager.py | 56 +- test/test_project.py | 330 +++---- test/test_regression_tests.py | 39 +- test/test_request_option.py | 185 ++-- test/test_requests.py | 30 +- test/test_schedule.py | 90 +- test/test_server_info.py | 50 +- test/test_site.py | 194 ++-- test/test_sort.py | 78 +- test/test_subscription.py | 63 +- test/test_table.py | 38 +- test/test_tableauauth_model.py | 9 +- test/test_task.py | 71 +- test/test_user.py | 228 +++-- test/test_view.py | 248 ++--- test/test_webhook.py | 43 +- test/test_workbook.py | 890 +++++++++--------- 79 files changed, 3106 insertions(+), 2766 deletions(-) diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 6485e9022..06783f0ac 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -25,6 +25,10 @@ jobs: python -m pip install --upgrade pip pip install -e .[test] + - name: Format with black + run: | + black --check --line-length 120 tableauserverclient samples test + - name: Test with pytest run: | pytest test diff --git a/samples/add_default_permission.py b/samples/add_default_permission.py index 8018c7b30..56d3afdf1 100644 --- a/samples/add_default_permission.py +++ b/samples/add_default_permission.py @@ -16,16 +16,23 @@ def main(): - parser = argparse.ArgumentParser(description='Add workbook default permissions for a given project.') + parser = argparse.ArgumentParser(description="Add workbook default permissions for a given project.") # 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)') + 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 @@ -53,10 +60,7 @@ def main(): new_capabilities = {TSC.Permission.Capability.ExportXml: TSC.Permission.Mode.Allow} # Each PermissionRule in the list contains a grantee and a dict of capabilities - new_rules = [TSC.PermissionsRule( - grantee=default_permissions.grantee, - capabilities=new_capabilities - )] + new_rules = [TSC.PermissionsRule(grantee=default_permissions.grantee, capabilities=new_capabilities)] new_default_permissions = server.projects.update_workbook_default_permissions(project, new_rules) @@ -78,5 +82,5 @@ def main(): # server.projects.delete(project.id) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/samples/create_group.py b/samples/create_group.py index ad0e6cc4f..16016398d 100644 --- a/samples/create_group.py +++ b/samples/create_group.py @@ -16,16 +16,23 @@ def main(): - parser = argparse.ArgumentParser(description='Creates a sample user group.') + parser = argparse.ArgumentParser(description="Creates a sample user group.") # 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)') + 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 @@ -38,10 +45,10 @@ def main(): 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): - group = TSC.GroupItem('test') + group = TSC.GroupItem("test") group = server.groups.create(group) print(group) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/samples/create_project.py b/samples/create_project.py index 6ed659ee9..6271f3d93 100644 --- a/samples/create_project.py +++ b/samples/create_project.py @@ -17,24 +17,31 @@ def create_project(server, project_item, samples=False): try: project_item = server.projects.create(project_item, samples) - print('Created a new project called: %s' % project_item.name) + print("Created a new project called: %s" % project_item.name) return project_item except TSC.ServerResponseError: - print('We have already created this project: %s' % project_item.name) + print("We have already created this project: %s" % project_item.name) sys.exit(1) def main(): - parser = argparse.ArgumentParser(description='Create new projects.') + parser = argparse.ArgumentParser(description="Create new projects.") # 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)') + 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 @@ -52,20 +59,20 @@ def main(): server.use_server_version() # Without parent_id specified, projects are created at the top level. - top_level_project = TSC.ProjectItem(name='Top Level Project') + top_level_project = TSC.ProjectItem(name="Top Level Project") top_level_project = create_project(server, top_level_project) # Specifying parent_id creates a nested projects. - child_project = TSC.ProjectItem(name='Child Project', parent_id=top_level_project.id) + child_project = TSC.ProjectItem(name="Child Project", parent_id=top_level_project.id) child_project = create_project(server, child_project, samples=True) # Projects can be nested at any level. - grand_child_project = TSC.ProjectItem(name='Grand Child Project', parent_id=child_project.id) + grand_child_project = TSC.ProjectItem(name="Grand Child Project", parent_id=child_project.id) grand_child_project = create_project(server, grand_child_project) # Projects can be updated changed_project = server.projects.update(grand_child_project, samples=True) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/samples/create_schedules.py b/samples/create_schedules.py index 39332713b..420bb59b1 100644 --- a/samples/create_schedules.py +++ b/samples/create_schedules.py @@ -16,16 +16,23 @@ def main(): - parser = argparse.ArgumentParser(description='Creates sample schedules for each type of frequency.') + parser = argparse.ArgumentParser(description="Creates sample schedules for each type of frequency.") # 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)') + 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 @@ -40,43 +47,59 @@ def main(): with server.auth.sign_in(tableau_auth): # Hourly Schedule # This schedule will run every 2 hours between 2:30AM and 11:00PM - hourly_interval = TSC.HourlyInterval(start_time=time(2, 30), - end_time=time(23, 0), - interval_value=2) - - hourly_schedule = TSC.ScheduleItem("Hourly-Schedule", 50, TSC.ScheduleItem.Type.Extract, - TSC.ScheduleItem.ExecutionOrder.Parallel, hourly_interval) + hourly_interval = TSC.HourlyInterval(start_time=time(2, 30), end_time=time(23, 0), interval_value=2) + + hourly_schedule = TSC.ScheduleItem( + "Hourly-Schedule", + 50, + TSC.ScheduleItem.Type.Extract, + TSC.ScheduleItem.ExecutionOrder.Parallel, + hourly_interval, + ) hourly_schedule = server.schedules.create(hourly_schedule) print("Hourly schedule created (ID: {}).".format(hourly_schedule.id)) # Daily Schedule # This schedule will run every day at 5AM daily_interval = TSC.DailyInterval(start_time=time(5)) - daily_schedule = TSC.ScheduleItem("Daily-Schedule", 60, TSC.ScheduleItem.Type.Subscription, - TSC.ScheduleItem.ExecutionOrder.Serial, daily_interval) + daily_schedule = TSC.ScheduleItem( + "Daily-Schedule", + 60, + TSC.ScheduleItem.Type.Subscription, + TSC.ScheduleItem.ExecutionOrder.Serial, + daily_interval, + ) daily_schedule = server.schedules.create(daily_schedule) print("Daily schedule created (ID: {}).".format(daily_schedule.id)) # Weekly Schedule # This schedule will wun every Monday, Wednesday, and Friday at 7:15PM - weekly_interval = TSC.WeeklyInterval(time(19, 15), - TSC.IntervalItem.Day.Monday, - TSC.IntervalItem.Day.Wednesday, - TSC.IntervalItem.Day.Friday) - weekly_schedule = TSC.ScheduleItem("Weekly-Schedule", 70, TSC.ScheduleItem.Type.Extract, - TSC.ScheduleItem.ExecutionOrder.Serial, weekly_interval) + weekly_interval = TSC.WeeklyInterval( + time(19, 15), TSC.IntervalItem.Day.Monday, TSC.IntervalItem.Day.Wednesday, TSC.IntervalItem.Day.Friday + ) + weekly_schedule = TSC.ScheduleItem( + "Weekly-Schedule", + 70, + TSC.ScheduleItem.Type.Extract, + TSC.ScheduleItem.ExecutionOrder.Serial, + weekly_interval, + ) weekly_schedule = server.schedules.create(weekly_schedule) print("Weekly schedule created (ID: {}).".format(weekly_schedule.id)) # Monthly Schedule # This schedule will run on the 15th of every month at 11:30PM - monthly_interval = TSC.MonthlyInterval(start_time=time(23, 30), - interval_value=15) - monthly_schedule = TSC.ScheduleItem("Monthly-Schedule", 80, TSC.ScheduleItem.Type.Subscription, - TSC.ScheduleItem.ExecutionOrder.Parallel, monthly_interval) + monthly_interval = TSC.MonthlyInterval(start_time=time(23, 30), interval_value=15) + monthly_schedule = TSC.ScheduleItem( + "Monthly-Schedule", + 80, + TSC.ScheduleItem.Type.Subscription, + TSC.ScheduleItem.ExecutionOrder.Parallel, + monthly_interval, + ) monthly_schedule = server.schedules.create(monthly_schedule) print("Monthly schedule created (ID: {}).".format(monthly_schedule.id)) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/samples/download_view_image.py b/samples/download_view_image.py index 3ac2ed4d5..3b2fbac1c 100644 --- a/samples/download_view_image.py +++ b/samples/download_view_image.py @@ -16,21 +16,27 @@ def main(): - parser = argparse.ArgumentParser(description='Download image of a specified view.') + parser = argparse.ArgumentParser(description="Download image of a specified view.") # 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)') + 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 - parser.add_argument('--view-name', '-vn', required=True, - help='name of view to download an image of') - parser.add_argument('--filepath', '-f', required=True, help='filepath to save the image returned') - parser.add_argument('--maxage', '-m', required=False, help='max age of the image in the cache in minutes.') + parser.add_argument("--view-name", "-vn", required=True, help="name of view to download an image of") + parser.add_argument("--filepath", "-f", required=True, help="filepath to save the image returned") + parser.add_argument("--maxage", "-m", required=False, help="max age of the image in the cache in minutes.") args = parser.parse_args() @@ -44,8 +50,9 @@ def main(): with server.auth.sign_in(tableau_auth): # Step 2: 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, args.view_name)) + 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.") @@ -55,8 +62,9 @@ def main(): if not max_age: max_age = 1 - image_req_option = TSC.ImageRequestOptions(imageresolution=TSC.ImageRequestOptions.Resolution.High, - maxage=max_age) + image_req_option = TSC.ImageRequestOptions( + imageresolution=TSC.ImageRequestOptions.Resolution.High, maxage=max_age + ) server.views.populate_image(view_item, image_req_option) with open(args.filepath, "wb") as image_file: @@ -65,5 +73,5 @@ def main(): print("View image saved to {0}".format(args.filepath)) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/samples/explore_datasource.py b/samples/explore_datasource.py index a78345122..014a274ef 100644 --- a/samples/explore_datasource.py +++ b/samples/explore_datasource.py @@ -17,19 +17,26 @@ def main(): - parser = argparse.ArgumentParser(description='Explore datasource functions supported by the Server API.') + parser = argparse.ArgumentParser(description="Explore datasource functions supported by the Server API.") # 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)') + 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 - parser.add_argument('--publish', metavar='FILEPATH', help='path to datasource to publish') - parser.add_argument('--download', metavar='FILEPATH', help='path to save downloaded datasource') + parser.add_argument("--publish", metavar="FILEPATH", help="path to datasource to publish") + parser.add_argument("--download", metavar="FILEPATH", help="path to save downloaded datasource") args = parser.parse_args() @@ -50,7 +57,8 @@ def main(): if default_project is not None: new_datasource = TSC.DatasourceItem(default_project.id) new_datasource = server.datasources.publish( - new_datasource, args.publish, TSC.Server.PublishMode.Overwrite) + new_datasource, args.publish, TSC.Server.PublishMode.Overwrite + ) print("Datasource published. ID: {}".format(new_datasource.id)) else: print("Publish failed. Could not find the default project.") @@ -67,12 +75,16 @@ def main(): # Populate connections server.datasources.populate_connections(sample_datasource) print("\nConnections for {}: ".format(sample_datasource.name)) - print(["{0}({1})".format(connection.id, connection.datasource_name) - for connection in sample_datasource.connections]) + print( + [ + "{0}({1})".format(connection.id, connection.datasource_name) + for connection in sample_datasource.connections + ] + ) # Add some tags to the datasource original_tag_set = set(sample_datasource.tags) - sample_datasource.tags.update('a', 'b', 'c', 'd') + sample_datasource.tags.update("a", "b", "c", "d") server.datasources.update(sample_datasource) print("\nOld tag set: {}".format(original_tag_set)) print("New tag set: {}".format(sample_datasource.tags)) @@ -82,5 +94,5 @@ def main(): server.datasources.update(sample_datasource) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/samples/explore_webhooks.py b/samples/explore_webhooks.py index 50c677cba..764fb0904 100644 --- a/samples/explore_webhooks.py +++ b/samples/explore_webhooks.py @@ -18,19 +18,26 @@ def main(): - parser = argparse.ArgumentParser(description='Explore webhook functions supported by the Server API.') + parser = argparse.ArgumentParser(description="Explore webhook functions supported by the Server API.") # 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)') + 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 - parser.add_argument('--create', help='create a webhook') - parser.add_argument('--delete', help='delete a webhook', action='store_true') + parser.add_argument("--create", help="create a webhook") + parser.add_argument("--delete", help="delete a webhook", action="store_true") args = parser.parse_args() @@ -63,12 +70,12 @@ def main(): # Pick one webhook from the list and delete it sample_webhook = all_webhooks[0] # sample_webhook.delete() - print("+++"+sample_webhook.name) + print("+++" + sample_webhook.name) - if (args.delete): + if args.delete: print("Deleting webhook " + sample_webhook.name) server.webhooks.delete(sample_webhook.id) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/samples/explore_workbook.py b/samples/explore_workbook.py index 8746db80e..a5a337653 100644 --- a/samples/explore_workbook.py +++ b/samples/explore_workbook.py @@ -18,21 +18,29 @@ def main(): - parser = argparse.ArgumentParser(description='Explore workbook functions supported by the Server API.') + parser = argparse.ArgumentParser(description="Explore workbook functions supported by the Server API.") # 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)') + 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 - parser.add_argument('--publish', metavar='FILEPATH', help='path to workbook to publish') - parser.add_argument('--download', metavar='FILEPATH', help='path to save downloaded workbook') - parser.add_argument('--preview-image', '-i', metavar='FILENAME', - help='filename (a .png file) to save the preview image') + parser.add_argument("--publish", metavar="FILEPATH", help="path to workbook to publish") + parser.add_argument("--download", metavar="FILEPATH", help="path to save downloaded workbook") + parser.add_argument( + "--preview-image", "-i", metavar="FILENAME", help="filename (a .png file) to save the preview image" + ) args = parser.parse_args() @@ -56,7 +64,7 @@ def main(): new_workbook = server.workbooks.publish(new_workbook, args.publish, overwrite_true) print("Workbook published. ID: {}".format(new_workbook.id)) else: - print('Publish failed. Could not find the default project.') + print("Publish failed. Could not find the default project.") # Gets all workbook items all_workbooks, pagination_item = server.workbooks.get() @@ -75,12 +83,16 @@ def main(): # Populate connections server.workbooks.populate_connections(sample_workbook) print("\nConnections for {}: ".format(sample_workbook.name)) - print(["{0}({1})".format(connection.id, connection.datasource_name) - for connection in sample_workbook.connections]) + print( + [ + "{0}({1})".format(connection.id, connection.datasource_name) + for connection in sample_workbook.connections + ] + ) # Update tags and show_tabs flag original_tag_set = set(sample_workbook.tags) - sample_workbook.tags.update('a', 'b', 'c', 'd') + sample_workbook.tags.update("a", "b", "c", "d") sample_workbook.show_tabs = True server.workbooks.update(sample_workbook) print("\nWorkbook's old tag set: {}".format(original_tag_set)) @@ -111,10 +123,10 @@ def main(): if args.preview_image: # Populate workbook preview image server.workbooks.populate_preview_image(sample_workbook) - with open(args.preview_image, 'wb') as f: + with open(args.preview_image, "wb") as f: f.write(sample_workbook.preview_image) print("\nDownloaded preview image of workbook to {}".format(os.path.abspath(args.preview_image))) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/samples/export.py b/samples/export.py index 6317ec53b..b5f2eec43 100644 --- a/samples/export.py +++ b/samples/export.py @@ -12,29 +12,38 @@ def main(): - parser = argparse.ArgumentParser(description='Export a view as an image, PDF, or CSV') + parser = argparse.ArgumentParser(description="Export a view as an image, PDF, or CSV") # 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)') + 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 group = parser.add_mutually_exclusive_group(required=True) - group.add_argument('--pdf', dest='type', action='store_const', const=('populate_pdf', 'PDFRequestOptions', 'pdf', - 'pdf')) - group.add_argument('--png', dest='type', action='store_const', const=('populate_image', 'ImageRequestOptions', - 'image', 'png')) - group.add_argument('--csv', dest='type', action='store_const', const=('populate_csv', 'CSVRequestOptions', 'csv', - 'csv')) + group.add_argument( + "--pdf", dest="type", action="store_const", const=("populate_pdf", "PDFRequestOptions", "pdf", "pdf") + ) + group.add_argument( + "--png", dest="type", action="store_const", const=("populate_image", "ImageRequestOptions", "image", "png") + ) + group.add_argument( + "--csv", dest="type", action="store_const", const=("populate_csv", "CSVRequestOptions", "csv", "csv") + ) - parser.add_argument('--file', '-f', help='filename to store the exported data') - parser.add_argument('--filter', '-vf', metavar='COLUMN:VALUE', - help='View filter to apply to the view') - parser.add_argument('resource_id', help='LUID for the view') + parser.add_argument("--file", "-f", help="filename to store the exported data") + parser.add_argument("--filter", "-vf", metavar="COLUMN:VALUE", help="View filter to apply to the view") + parser.add_argument("resource_id", help="LUID for the view") args = parser.parse_args() @@ -45,8 +54,7 @@ def main(): 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): - views = filter(lambda x: x.id == args.resource_id, - TSC.Pager(server.views.get)) + views = filter(lambda x: x.id == args.resource_id, TSC.Pager(server.views.get)) view = views.pop() # We have a number of different types and functions for each different export type. @@ -58,21 +66,21 @@ def main(): option_factory = getattr(TSC, option_factory_name) if args.filter: - options = option_factory().vf(*args.filter.split(':')) + options = option_factory().vf(*args.filter.split(":")) else: options = None if args.file: filename = args.file else: - filename = 'out.{}'.format(extension) + filename = "out.{}".format(extension) populate(view, options) - with file(filename, 'wb') as f: - if member_name == 'csv': + with file(filename, "wb") as f: + if member_name == "csv": f.writelines(getattr(view, member_name)) else: f.write(getattr(view, member_name)) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/samples/export_wb.py b/samples/export_wb.py index 2be476130..2376ee62b 100644 --- a/samples/export_wb.py +++ b/samples/export_wb.py @@ -16,11 +16,13 @@ import os.path import tableauserverclient as TSC + try: import PyPDF2 except ImportError: - print('Please `pip install PyPDF2` to use this sample') + print("Please `pip install PyPDF2` to use this sample") import sys + sys.exit(1) @@ -34,7 +36,7 @@ def download_pdf(server, tempdir, view): # -> Filename to downloaded pdf logging.info("Exporting {}".format(view.id)) destination_filename = os.path.join(tempdir, view.id) server.views.populate_pdf(view) - with file(destination_filename, 'wb') as f: + with file(destination_filename, "wb") as f: f.write(view.pdf) return destination_filename @@ -50,19 +52,26 @@ def cleanup(tempdir): def main(): - parser = argparse.ArgumentParser(description='Export to PDF all of the views in a workbook.') + parser = argparse.ArgumentParser(description="Export to PDF all of the views in a workbook.") # 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)') + 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 - parser.add_argument('--file', '-f', default='out.pdf', help='filename to store the exported data') - parser.add_argument('resource_id', help='LUID for the workbook') + parser.add_argument("--file", "-f", default="out.pdf", help="filename to store the exported data") + parser.add_argument("resource_id", help="LUID for the workbook") args = parser.parse_args() @@ -70,7 +79,7 @@ def main(): logging_level = getattr(logging, args.logging_level.upper()) logging.basicConfig(level=logging_level) - tempdir = tempfile.mkdtemp('tsc') + tempdir = tempfile.mkdtemp("tsc") logging.debug("Saving to tempdir: %s", tempdir) try: @@ -82,11 +91,11 @@ def main(): downloaded = (download(x) for x in get_list(args.resource_id)) output = reduce(combine_into, downloaded, PyPDF2.PdfFileMerger()) - with file(args.file, 'wb') as f: + with file(args.file, "wb") as f: output.write(f) finally: cleanup(tempdir) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/samples/filter_sort_groups.py b/samples/filter_sort_groups.py index 24dee791d..f883a5a08 100644 --- a/samples/filter_sort_groups.py +++ b/samples/filter_sort_groups.py @@ -12,27 +12,34 @@ import tableauserverclient as TSC -def create_example_group(group_name='Example Group', server=None): +def create_example_group(group_name="Example Group", server=None): new_group = TSC.GroupItem(group_name) try: new_group = server.groups.create(new_group) - print('Created a new project called: \'%s\'' % group_name) + print("Created a new project called: '%s'" % group_name) print(new_group) except TSC.ServerResponseError: - print('Group \'%s\' already existed' % group_name) + print("Group '%s' already existed" % group_name) def main(): - parser = argparse.ArgumentParser(description='Filter and sort groups.') + parser = argparse.ArgumentParser(description="Filter and sort groups.") # 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)') + 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 @@ -46,21 +53,21 @@ def main(): server = TSC.Server(args.server, use_server_version=True) with server.auth.sign_in(tableau_auth): - group_name = 'SALES NORTHWEST' + group_name = "SALES NORTHWEST" # Try to create a group named "SALES NORTHWEST" create_example_group(group_name, server) - group_name = 'SALES ROMANIA' + group_name = "SALES ROMANIA" # Try to create a group named "SALES ROMANIA" create_example_group(group_name, server) # URL Encode the name of the group that we want to filter on # i.e. turn spaces into plus signs - filter_group_name = 'SALES+ROMANIA' + filter_group_name = "SALES+ROMANIA" options = TSC.RequestOptions() - options.filter.add(TSC.Filter(TSC.RequestOptions.Field.Name, - TSC.RequestOptions.Operator.Equals, - filter_group_name)) + options.filter.add( + TSC.Filter(TSC.RequestOptions.Field.Name, TSC.RequestOptions.Operator.Equals, filter_group_name) + ) filtered_groups, _ = server.groups.get(req_options=options) # Result can either be a matching group or an empty list @@ -72,18 +79,21 @@ def main(): print(error) options = TSC.RequestOptions() - options.filter.add(TSC.Filter(TSC.RequestOptions.Field.Name, - TSC.RequestOptions.Operator.In, - ['SALES+NORTHWEST', 'SALES+ROMANIA', 'this_group'])) + options.filter.add( + TSC.Filter( + TSC.RequestOptions.Field.Name, + TSC.RequestOptions.Operator.In, + ["SALES+NORTHWEST", "SALES+ROMANIA", "this_group"], + ) + ) - options.sort.add(TSC.Sort(TSC.RequestOptions.Field.Name, - TSC.RequestOptions.Direction.Desc)) + options.sort.add(TSC.Sort(TSC.RequestOptions.Field.Name, TSC.RequestOptions.Direction.Desc)) matching_groups, pagination_item = server.groups.get(req_options=options) - print('Filtered groups are:') + print("Filtered groups are:") for group in matching_groups: print(group.name) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/samples/filter_sort_projects.py b/samples/filter_sort_projects.py index 23b350fa6..75b13f848 100644 --- a/samples/filter_sort_projects.py +++ b/samples/filter_sort_projects.py @@ -11,29 +11,39 @@ import tableauserverclient as TSC -def create_example_project(name='Example Project', content_permissions='LockedToProject', - description='Project created for testing', server=None): - - new_project = TSC.ProjectItem(name=name, content_permissions=content_permissions, - description=description) +def create_example_project( + name="Example Project", + content_permissions="LockedToProject", + description="Project created for testing", + server=None, +): + + new_project = TSC.ProjectItem(name=name, content_permissions=content_permissions, description=description) try: server.projects.create(new_project) - print('Created a new project called: %s' % name) + print("Created a new project called: %s" % name) except TSC.ServerResponseError: - print('We have already created this resource: %s' % name) + print("We have already created this resource: %s" % name) def main(): - parser = argparse.ArgumentParser(description='Filter and sort projects.') + parser = argparse.ArgumentParser(description="Filter and sort projects.") # 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)') + 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 @@ -49,12 +59,12 @@ def main(): # Use highest Server REST API version available server.use_server_version() - filter_project_name = 'default' + filter_project_name = "default" options = TSC.RequestOptions() - options.filter.add(TSC.Filter(TSC.RequestOptions.Field.Name, - TSC.RequestOptions.Operator.Equals, - filter_project_name)) + options.filter.add( + TSC.Filter(TSC.RequestOptions.Field.Name, TSC.RequestOptions.Operator.Equals, filter_project_name) + ) filtered_projects, _ = server.projects.get(req_options=options) # Result can either be a matching project or an empty list @@ -65,26 +75,27 @@ def main(): error = "No project named '{}' found".format(filter_project_name) print(error) - create_example_project(name='Example 1', server=server) - create_example_project(name='Example 2', server=server) - create_example_project(name='Example 3', server=server) - create_example_project(name='Proiect ca Exemplu', server=server) + create_example_project(name="Example 1", server=server) + create_example_project(name="Example 2", server=server) + create_example_project(name="Example 3", server=server) + create_example_project(name="Proiect ca Exemplu", server=server) options = TSC.RequestOptions() # don't forget to URL encode the query names - options.filter.add(TSC.Filter(TSC.RequestOptions.Field.Name, - TSC.RequestOptions.Operator.In, - ['Example+1', 'Example+2', 'Example+3'])) + options.filter.add( + TSC.Filter( + TSC.RequestOptions.Field.Name, TSC.RequestOptions.Operator.In, ["Example+1", "Example+2", "Example+3"] + ) + ) - options.sort.add(TSC.Sort(TSC.RequestOptions.Field.Name, - TSC.RequestOptions.Direction.Desc)) + options.sort.add(TSC.Sort(TSC.RequestOptions.Field.Name, TSC.RequestOptions.Direction.Desc)) matching_projects, pagination_item = server.projects.get(req_options=options) - print('Filtered projects are:') + print("Filtered projects are:") for project in matching_projects: print(project.name, project.id) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/samples/initialize_server.py b/samples/initialize_server.py index a7dd552e1..586011120 100644 --- a/samples/initialize_server.py +++ b/samples/initialize_server.py @@ -11,20 +11,27 @@ def main(): - parser = argparse.ArgumentParser(description='Initialize a server with content.') + parser = argparse.ArgumentParser(description="Initialize a server with content.") # 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)') + 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 - parser.add_argument('--datasources-folder', '-df', required=True, help='folder containing datasources') - parser.add_argument('--workbooks-folder', '-wf', required=True, help='folder containing workbooks') - parser.add_argument('--project', required=False, default='Default', help='project to use') + parser.add_argument("--datasources-folder", "-df", required=True, help="folder containing datasources") + parser.add_argument("--workbooks-folder", "-wf", required=True, help="folder containing workbooks") + parser.add_argument("--project", required=False, default="Default", help="project to use") args = parser.parse_args() @@ -50,8 +57,11 @@ def main(): # Create the site if it doesn't exist if existing_site is None: print("Site not found: {0} Creating it...").format(args.site_id) - new_site = TSC.SiteItem(name=args.site_id, content_url=args.site_id.replace(" ", ""), - admin_mode=TSC.SiteItem.AdminMode.ContentAndUsers) + new_site = TSC.SiteItem( + name=args.site_id, + content_url=args.site_id.replace(" ", ""), + admin_mode=TSC.SiteItem.AdminMode.ContentAndUsers, + ) server.sites.create(new_site) else: print("Site {0} exists. Moving on...").format(args.site_id) @@ -70,6 +80,7 @@ def main(): # Step 4: Create the project we need only if it doesn't exist ################################################################################ import time + time.sleep(2) # sad panda...something about eventually consistent model all_projects = TSC.Pager(server_upload.projects) project = next((p for p in all_projects if p.name.lower() == args.project.lower()), None) @@ -90,7 +101,7 @@ def main(): def publish_datasources_to_site(server_object, project, folder): - path = folder + '/*.tds*' + path = folder + "/*.tds*" for fname in glob.glob(path): new_ds = TSC.DatasourceItem(project.id) @@ -99,7 +110,7 @@ def publish_datasources_to_site(server_object, project, folder): def publish_workbooks_to_site(server_object, project, folder): - path = folder + '/*.twb*' + path = folder + "/*.twb*" for fname in glob.glob(path): new_workbook = TSC.WorkbookItem(project.id) diff --git a/samples/kill_all_jobs.py b/samples/kill_all_jobs.py index 196da4b01..02f19d976 100644 --- a/samples/kill_all_jobs.py +++ b/samples/kill_all_jobs.py @@ -11,16 +11,23 @@ def main(): - parser = argparse.ArgumentParser(description='Cancel all of the running background jobs.') + 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)') + 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 @@ -40,5 +47,5 @@ def main(): print(server.jobs.cancel(job.id), job.id, job.status, job.type) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/samples/list.py b/samples/list.py index 867757668..7053118a7 100644 --- a/samples/list.py +++ b/samples/list.py @@ -13,18 +13,25 @@ def main(): - parser = argparse.ArgumentParser(description='List out the names and LUIDs for different resource types.') + parser = argparse.ArgumentParser(description="List out the names and LUIDs for different resource types.") # 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', '-n', 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)') + parser.add_argument("--server", "-s", required=True, help="server address") + parser.add_argument("--site", "-S", help="site name") + parser.add_argument( + "--token-name", "-n", 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 - parser.add_argument('resource_type', choices=['workbook', 'datasource', 'project', 'view', 'job', 'webhooks']) + parser.add_argument("resource_type", choices=["workbook", "datasource", "project", "view", "job", "webhooks"]) args = parser.parse_args() @@ -37,17 +44,17 @@ def main(): server = TSC.Server(args.server, use_server_version=True) with server.auth.sign_in(tableau_auth): endpoint = { - 'workbook': server.workbooks, - 'datasource': server.datasources, - 'view': server.views, - 'job': server.jobs, - 'project': server.projects, - 'webhooks': server.webhooks, + "workbook": server.workbooks, + "datasource": server.datasources, + "view": server.views, + "job": server.jobs, + "project": server.projects, + "webhooks": server.webhooks, }.get(args.resource_type) for resource in TSC.Pager(endpoint.get): print(resource.id, resource.name) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/samples/login.py b/samples/login.py index c8af97505..3fa2ab1ae 100644 --- a/samples/login.py +++ b/samples/login.py @@ -12,18 +12,23 @@ def main(): - parser = argparse.ArgumentParser(description='Logs in to the server.') + parser = argparse.ArgumentParser(description="Logs in to the server.") # This command is special, as it doesn't take `token-value` and it offer both token-based and password based authentication. # Please still try to keep common options like `server` and `site` consistent across samples # Common options: - parser.add_argument('--server', '-s', required=True, help='server address') - parser.add_argument('--site', '-S', help='site name') - parser.add_argument('--logging-level', '-l', choices=['debug', 'info', 'error'], default='error', - help='desired logging level (set to error by default)') + parser.add_argument("--server", "-s", required=True, help="server address") + parser.add_argument("--site", "-S", help="site name") + 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 group = parser.add_mutually_exclusive_group(required=True) - group.add_argument('--username', '-u', help='username to sign into the server') - group.add_argument('--token-name', '-n', help='name of the personal access token used to sign into the server') + group.add_argument("--username", "-u", help="username to sign into the server") + group.add_argument("--token-name", "-n", help="name of the personal access token used to sign into the server") args = parser.parse_args() @@ -41,19 +46,19 @@ def main(): print("\nSigning in...\nServer: {}\nSite: {}\nUsername: {}".format(args.server, args.site, args.username)) tableau_auth = TSC.TableauAuth(args.username, password, site_id=args.site) with server.auth.sign_in(tableau_auth): - print('Logged in successfully') + print("Logged in successfully") else: # Trying to authenticate using personal access tokens. personal_access_token = getpass.getpass("Personal Access Token: ") - print("\nSigning in...\nServer: {}\nSite: {}\nToken name: {}" - .format(args.server, args.site, args.token_name)) - tableau_auth = TSC.PersonalAccessTokenAuth(token_name=args.token_name, - personal_access_token=personal_access_token, site_id=args.site) + print("\nSigning in...\nServer: {}\nSite: {}\nToken name: {}".format(args.server, args.site, args.token_name)) + tableau_auth = TSC.PersonalAccessTokenAuth( + token_name=args.token_name, personal_access_token=personal_access_token, site_id=args.site + ) with server.auth.sign_in_with_personal_access_token(tableau_auth): - print('Logged in successfully') + print("Logged in successfully") -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/samples/metadata_query.py b/samples/metadata_query.py index c9cf7394c..65df9ddb0 100644 --- a/samples/metadata_query.py +++ b/samples/metadata_query.py @@ -12,19 +12,29 @@ def main(): - parser = argparse.ArgumentParser(description='Use the metadata API to get information on a published data source.') + parser = argparse.ArgumentParser(description="Use the metadata API to get information on a published data source.") # 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', '-n', 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)') + parser.add_argument("--server", "-s", required=True, help="server address") + parser.add_argument("--site", "-S", help="site name") + parser.add_argument( + "--token-name", "-n", 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 - parser.add_argument('datasource_name', nargs='?', help="The name of the published datasource. If not present, we query all data sources.") - + parser.add_argument( + "datasource_name", + nargs="?", + help="The name of the published datasource. If not present, we query all data sources.", + ) args = parser.parse_args() @@ -37,7 +47,8 @@ def main(): server = TSC.Server(args.server, use_server_version=True) with server.auth.sign_in(tableau_auth): # Execute the query - result = server.metadata.query(""" + result = server.metadata.query( + """ query useMetadataApiToQueryOrdersDatabases($name: String){ publishedDatasources (filter: {name: $name}) { luid @@ -48,17 +59,20 @@ def main(): name } } - }""", {"name": args.datasource_name}) + }""", + {"name": args.datasource_name}, + ) # Display warnings/errors (if any) if result.get("errors"): print("### Errors/Warnings:") pprint(result["errors"]) - + # Print the results if result.get("data"): print("### Results:") pprint(result["data"]["publishedDatasources"]) -if __name__ == '__main__': + +if __name__ == "__main__": main() diff --git a/samples/move_workbook_projects.py b/samples/move_workbook_projects.py index c8227aeda..172112b20 100644 --- a/samples/move_workbook_projects.py +++ b/samples/move_workbook_projects.py @@ -15,19 +15,26 @@ def main(): - parser = argparse.ArgumentParser(description='Move one workbook from the default project to another.') + parser = argparse.ArgumentParser(description="Move one workbook from the default project to another.") # 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)') + 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 - 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("--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") args = parser.parse_args() @@ -41,8 +48,9 @@ def main(): with server.auth.sign_in(tableau_auth): # Step 2: Query workbook to move req_option = TSC.RequestOptions() - req_option.filter.add(TSC.Filter(TSC.RequestOptions.Field.Name, - TSC.RequestOptions.Operator.Equals, args.workbook_name)) + req_option.filter.add( + TSC.Filter(TSC.RequestOptions.Field.Name, TSC.RequestOptions.Operator.Equals, args.workbook_name) + ) all_workbooks, pagination_item = server.workbooks.get(req_option) # Step 3: Find destination project @@ -64,5 +72,5 @@ def main(): raise LookupError(error) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/samples/move_workbook_sites.py b/samples/move_workbook_sites.py index e0475ac06..c473712e4 100644 --- a/samples/move_workbook_sites.py +++ b/samples/move_workbook_sites.py @@ -17,22 +17,30 @@ def main(): - parser = argparse.ArgumentParser(description="Move one workbook from the" - "default project of the default site to" - "the default project of another site.") + parser = argparse.ArgumentParser( + description="Move one workbook from the" + "default project of the default site to" + "the default project of another site." + ) # 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)') + 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 - parser.add_argument('--workbook-name', '-w', required=True, help='name of workbook to move') - parser.add_argument('--destination-site', '-d', required=True, help='name of site to move workbook into') - + parser.add_argument("--workbook-name", "-w", required=True, help="name of workbook to move") + parser.add_argument("--destination-site", "-d", required=True, help="name of site to move workbook into") args = parser.parse_args() @@ -49,13 +57,14 @@ def main(): with source_server.auth.sign_in(tableau_auth): # Step 2: Query workbook to move req_option = TSC.RequestOptions() - req_option.filter.add(TSC.Filter(TSC.RequestOptions.Field.Name, - TSC.RequestOptions.Operator.Equals, args.workbook_name)) + req_option.filter.add( + TSC.Filter(TSC.RequestOptions.Field.Name, TSC.RequestOptions.Operator.Equals, args.workbook_name) + ) all_workbooks, pagination_item = source_server.workbooks.get(req_option) # Step 3: Download workbook to a temp directory if len(all_workbooks) == 0: - print('No workbook named {} found.'.format(args.workbook_name)) + print("No workbook named {} found.".format(args.workbook_name)) else: tmpdir = tempfile.mkdtemp() try: @@ -63,8 +72,9 @@ def main(): # Step 4: Check if destination site exists, then sign in to the site all_sites, pagination_info = source_server.sites.get() - found_destination_site = any((True for site in all_sites if - args.destination_site.lower() == site.content_url.lower())) + found_destination_site = any( + (True for site in all_sites if args.destination_site.lower() == site.content_url.lower()) + ) if not found_destination_site: error = "No site named {} found.".format(args.destination_site) raise LookupError(error) @@ -78,8 +88,9 @@ def main(): # Step 5: Create a new workbook item and publish workbook. Note that # an empty project_id will publish to the 'Default' project. new_workbook = TSC.WorkbookItem(name=args.workbook_name, project_id="") - new_workbook = dest_server.workbooks.publish(new_workbook, workbook_path, - mode=TSC.Server.PublishMode.Overwrite) + new_workbook = dest_server.workbooks.publish( + new_workbook, workbook_path, mode=TSC.Server.PublishMode.Overwrite + ) print("Successfully moved {0} ({1})".format(new_workbook.name, new_workbook.id)) # Step 6: Delete workbook from source site and delete temp directory @@ -89,5 +100,5 @@ def main(): shutil.rmtree(tmpdir) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/samples/pagination_sample.py b/samples/pagination_sample.py index 2ebd011dc..5c1a78fd5 100644 --- a/samples/pagination_sample.py +++ b/samples/pagination_sample.py @@ -18,16 +18,23 @@ def main(): - parser = argparse.ArgumentParser(description='Demonstrate pagination on the list of workbooks on the server.') + parser = argparse.ArgumentParser(description="Demonstrate pagination on the list of workbooks on the server.") # 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', '-n', 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)') + parser.add_argument("--server", "-s", required=True, help="server address") + parser.add_argument("--site", "-S", help="site name") + parser.add_argument( + "--token-name", "-n", 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 @@ -68,5 +75,5 @@ def main(): # >>> all_workbooks = list(TSC.Pager(server.workbooks, request_options)) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/samples/publish_datasource.py b/samples/publish_datasource.py index 8ae744185..ad929fd99 100644 --- a/samples/publish_datasource.py +++ b/samples/publish_datasource.py @@ -25,24 +25,31 @@ def main(): - parser = argparse.ArgumentParser(description='Publish a datasource to server.') + parser = argparse.ArgumentParser(description="Publish a datasource to server.") # 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)') + 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 - parser.add_argument('--file', '-f', required=True, help='filepath to the datasource to publish') - parser.add_argument('--project', help='Project within which to publish the datasource') - parser.add_argument('--async', '-a', help='Publishing asynchronously', dest='async_', action='store_true') - parser.add_argument('--conn-username', help='connection username') - parser.add_argument('--conn-password', help='connection password') - parser.add_argument('--conn-embed', help='embed connection password to datasource', action='store_true') - parser.add_argument('--conn-oauth', help='connection is configured to use oAuth', action='store_true') + parser.add_argument("--file", "-f", required=True, help="filepath to the datasource to publish") + parser.add_argument("--project", help="Project within which to publish the datasource") + parser.add_argument("--async", "-a", help="Publishing asynchronously", dest="async_", action="store_true") + parser.add_argument("--conn-username", help="connection username") + parser.add_argument("--conn-password", help="connection password") + parser.add_argument("--conn-embed", help="embed connection password to datasource", action="store_true") + parser.add_argument("--conn-oauth", help="connection is configured to use oAuth", action="store_true") args = parser.parse_args() @@ -64,9 +71,9 @@ def main(): # Retrieve the project id, if a project name was passed if args.project is not None: req_options = TSC.RequestOptions() - req_options.filter.add(TSC.Filter(TSC.RequestOptions.Field.Name, - TSC.RequestOptions.Operator.Equals, - args.project)) + req_options.filter.add( + TSC.Filter(TSC.RequestOptions.Field.Name, TSC.RequestOptions.Operator.Equals, args.project) + ) projects = list(TSC.Pager(server.projects, req_options)) if len(projects) > 1: raise ValueError("The project name is not unique") @@ -78,8 +85,9 @@ def main(): # Create a connection_credentials item if connection details are provided new_conn_creds = None if args.conn_username: - new_conn_creds = TSC.ConnectionCredentials(args.conn_username, args.conn_password, - embed=args.conn_embed, oauth=args.conn_oauth) + new_conn_creds = TSC.ConnectionCredentials( + args.conn_username, args.conn_password, embed=args.conn_embed, oauth=args.conn_oauth + ) # Define publish mode - Overwrite, Append, or CreateNew publish_mode = TSC.Server.PublishMode.Overwrite @@ -87,15 +95,17 @@ def main(): # Publish datasource if args.async_: # Async publishing, returns a job_item - new_job = server.datasources.publish(new_datasource, args.filepath, publish_mode, - connection_credentials=new_conn_creds, as_job=True) + new_job = server.datasources.publish( + new_datasource, args.filepath, publish_mode, connection_credentials=new_conn_creds, as_job=True + ) print("Datasource published asynchronously. Job ID: {0}".format(new_job.id)) else: # Normal publishing, returns a datasource_item - new_datasource = server.datasources.publish(new_datasource, args.filepath, publish_mode, - connection_credentials=new_conn_creds) + new_datasource = server.datasources.publish( + new_datasource, args.filepath, publish_mode, connection_credentials=new_conn_creds + ) print("Datasource published. Datasource ID: {0}".format(new_datasource.id)) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/samples/publish_workbook.py b/samples/publish_workbook.py index fcfcddc15..c553eda0b 100644 --- a/samples/publish_workbook.py +++ b/samples/publish_workbook.py @@ -23,21 +23,27 @@ def main(): - parser = argparse.ArgumentParser(description='Publish a workbook to server.') + parser = argparse.ArgumentParser(description="Publish a workbook to server.") # 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)') + 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 - parser.add_argument('--file', '-f', required=True, help='local filepath of the workbook to publish') - parser.add_argument('--as-job', '-a', help='Publishing asynchronously', action='store_true') - parser.add_argument('--skip-connection-check', '-c', help='Skip live connection check', action='store_true') - + parser.add_argument("--file", "-f", required=True, help="local filepath of the workbook to publish") + parser.add_argument("--as-job", "-a", help="Publishing asynchronously", action="store_true") + parser.add_argument("--skip-connection-check", "-c", help="Skip live connection check", action="store_true") args = parser.parse_args() @@ -72,19 +78,29 @@ def main(): if default_project is not None: new_workbook = TSC.WorkbookItem(default_project.id) if args.as_job: - new_job = server.workbooks.publish(new_workbook, args.filepath, overwrite_true, - connections=all_connections, as_job=args.as_job, - skip_connection_check=args.skip_connection_check) + new_job = server.workbooks.publish( + new_workbook, + args.filepath, + overwrite_true, + connections=all_connections, + as_job=args.as_job, + skip_connection_check=args.skip_connection_check, + ) print("Workbook published. JOB ID: {0}".format(new_job.id)) else: - new_workbook = server.workbooks.publish(new_workbook, args.filepath, overwrite_true, - connections=all_connections, as_job=args.as_job, - skip_connection_check=args.skip_connection_check) + new_workbook = server.workbooks.publish( + new_workbook, + args.filepath, + overwrite_true, + connections=all_connections, + as_job=args.as_job, + skip_connection_check=args.skip_connection_check, + ) print("Workbook published. ID: {0}".format(new_workbook.id)) else: error = "The default project could not be found." raise LookupError(error) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/samples/query_permissions.py b/samples/query_permissions.py index 0909f915d..c0d1c3afa 100644 --- a/samples/query_permissions.py +++ b/samples/query_permissions.py @@ -13,19 +13,26 @@ def main(): - parser = argparse.ArgumentParser(description='Query permissions of a given resource.') + parser = argparse.ArgumentParser(description="Query permissions of a given resource.") # 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)') + 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 - parser.add_argument('resource_type', choices=['workbook', 'datasource', 'flow', 'table', 'database']) - parser.add_argument('resource_id') + parser.add_argument("resource_type", choices=["workbook", "datasource", "flow", "table", "database"]) + parser.add_argument("resource_id") args = parser.parse_args() @@ -40,11 +47,11 @@ def main(): # Mapping to grab the handler for the user-inputted resource type endpoint = { - 'workbook': server.workbooks, - 'datasource': server.datasources, - 'flow': server.flows, - 'table': server.tables, - 'database': server.databases + "workbook": server.workbooks, + "datasource": server.datasources, + "flow": server.flows, + "table": server.tables, + "database": server.databases, }.get(args.resource_type) # Get the resource by its ID @@ -55,8 +62,9 @@ def main(): permissions = resource.permissions # Print result - print("\n{0} permission rule(s) found for {1} {2}." - .format(len(permissions), args.resource_type, args.resource_id)) + print( + "\n{0} permission rule(s) found for {1} {2}.".format(len(permissions), args.resource_type, args.resource_id) + ) for permission in permissions: grantee = permission.grantee @@ -67,5 +75,5 @@ def main(): print("\t{0} - {1}".format(capability, capabilities[capability])) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/samples/refresh.py b/samples/refresh.py index 3eed5b4be..18a7f36e2 100644 --- a/samples/refresh.py +++ b/samples/refresh.py @@ -11,19 +11,26 @@ def main(): - parser = argparse.ArgumentParser(description='Trigger a refresh task on a workbook or datasource.') + parser = argparse.ArgumentParser(description="Trigger a refresh task on a workbook or datasource.") # 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)') + 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 - parser.add_argument('resource_type', choices=['workbook', 'datasource']) - parser.add_argument('resource_id') + parser.add_argument("resource_type", choices=["workbook", "datasource"]) + parser.add_argument("resource_id") args = parser.parse_args() @@ -46,7 +53,7 @@ def main(): # trigger the refresh, you'll get a job id back which can be used to poll for when the refresh is done job = server.datasources.refresh(resource) - + print(f"Update job posted (ID: {job.id})") print("Waiting for job...") # `wait_for_job` will throw if the job isn't executed successfully @@ -54,5 +61,5 @@ def main(): print("Job finished succesfully") -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/samples/refresh_tasks.py b/samples/refresh_tasks.py index bf69d064a..6ef781544 100644 --- a/samples/refresh_tasks.py +++ b/samples/refresh_tasks.py @@ -28,28 +28,35 @@ def handle_info(server, args): def main(): - parser = argparse.ArgumentParser(description='Get all of the refresh tasks available on a server') + parser = argparse.ArgumentParser(description="Get all of the refresh tasks available on a server") # 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)') + 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 subcommands = parser.add_subparsers() - list_arguments = subcommands.add_parser('list') + list_arguments = subcommands.add_parser("list") list_arguments.set_defaults(func=handle_list) - run_arguments = subcommands.add_parser('run') - run_arguments.add_argument('id', default=None) + run_arguments = subcommands.add_parser("run") + run_arguments.add_argument("id", default=None) run_arguments.set_defaults(func=handle_run) - info_arguments = subcommands.add_parser('info') - info_arguments.add_argument('id', default=None) + info_arguments = subcommands.add_parser("info") + info_arguments.add_argument("id", default=None) info_arguments.set_defaults(func=handle_info) args = parser.parse_args() @@ -65,5 +72,5 @@ def main(): args.func(server, args) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/samples/set_http_options.py b/samples/set_http_options.py index 40ed9167e..238da1d7c 100644 --- a/samples/set_http_options.py +++ b/samples/set_http_options.py @@ -13,16 +13,23 @@ def main(): - parser = argparse.ArgumentParser(description='List workbooks on site, with option set to ignore SSL verification.') + parser = argparse.ArgumentParser(description="List workbooks on site, with option set to ignore SSL verification.") # 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)') + 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 @@ -37,16 +44,16 @@ def main(): server = TSC.Server(args.server) # Step 2: Set http options to disable verifying SSL - server.add_http_options({'verify': False}) + server.add_http_options({"verify": False}) with server.auth.sign_in(tableau_auth): # Step 3: Query all workbooks and list them all_workbooks, pagination_item = server.workbooks.get() - print('{0} workbooks found. Showing {1}:'.format(pagination_item.total_available, pagination_item.page_size)) + print("{0} workbooks found. Showing {1}:".format(pagination_item.total_available, pagination_item.page_size)) for workbook in all_workbooks: - print('\t{0} (ID: {1})'.format(workbook.name, workbook.id)) + print("\t{0} (ID: {1})".format(workbook.name, workbook.id)) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/samples/set_refresh_schedule.py b/samples/set_refresh_schedule.py index 862ea2372..50fccaf2b 100644 --- a/samples/set_refresh_schedule.py +++ b/samples/set_refresh_schedule.py @@ -13,21 +13,28 @@ def usage(args): - parser = argparse.ArgumentParser(description='Set refresh schedule for a workbook or datasource.') + parser = argparse.ArgumentParser(description="Set refresh schedule for a workbook or datasource.") # 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)') + 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 group = parser.add_mutually_exclusive_group(required=True) - group.add_argument('--workbook', '-w') - group.add_argument('--datasource', '-d') - parser.add_argument('schedule') + group.add_argument("--workbook", "-w") + group.add_argument("--datasource", "-d") + parser.add_argument("schedule") return parser.parse_args(args) @@ -84,6 +91,7 @@ def run(args): def main(): import sys + args = usage(sys.argv[1:]) run(args) diff --git a/samples/update_connection.py b/samples/update_connection.py index 0e87217e8..44f8ec6c0 100644 --- a/samples/update_connection.py +++ b/samples/update_connection.py @@ -11,22 +11,29 @@ def main(): - parser = argparse.ArgumentParser(description='Update a connection on a datasource or workbook to embed credentials') + parser = argparse.ArgumentParser(description="Update a connection on a datasource or workbook to embed credentials") # 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)') + 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 - parser.add_argument('resource_type', choices=['workbook', 'datasource']) - parser.add_argument('resource_id') - parser.add_argument('connection_id') - parser.add_argument('datasource_username') - parser.add_argument('datasource_password') + parser.add_argument("resource_type", choices=["workbook", "datasource"]) + parser.add_argument("resource_id") + parser.add_argument("connection_id") + parser.add_argument("datasource_username") + parser.add_argument("datasource_password") args = parser.parse_args() @@ -37,16 +44,13 @@ def main(): 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): - endpoint = { - 'workbook': server.workbooks, - 'datasource': server.datasources - }.get(args.resource_type) + endpoint = {"workbook": server.workbooks, "datasource": server.datasources}.get(args.resource_type) update_function = endpoint.update_connection resource = endpoint.get_by_id(args.resource_id) endpoint.populate_connections(resource) connections = list(filter(lambda x: x.id == args.connection_id, resource.connections)) - assert(len(connections) == 1) + assert len(connections) == 1 connection = connections[0] connection.username = args.datasource_username connection.password = args.datasource_password @@ -54,5 +58,5 @@ def main(): print(update_function(resource, connection).__dict__) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/samples/update_datasource_data.py b/samples/update_datasource_data.py index 74c8ea6fb..41f42ee74 100644 --- a/samples/update_datasource_data.py +++ b/samples/update_datasource_data.py @@ -21,18 +21,27 @@ def main(): - parser = argparse.ArgumentParser(description='Delete the `Europe` region from a published `World Indicators` datasource.') + parser = argparse.ArgumentParser( + description="Delete the `Europe` region from a published `World Indicators` datasource." + ) # 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)') + 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 - parser.add_argument('datasource_id', help="The LUID of the `World Indicators` datasource") + parser.add_argument("datasource_id", help="The LUID of the `World Indicators` datasource") args = parser.parse_args() @@ -61,7 +70,7 @@ def main(): "action": "delete", "target-table": "Extract", "target-schema": "Extract", - "condition": {"op": "eq", "target-col": "Region", "const": {"type": "string", "v": "Europe"}} + "condition": {"op": "eq", "target-col": "Region", "const": {"type": "string", "v": "Europe"}}, } ] @@ -74,5 +83,5 @@ def main(): print("Job finished succesfully") -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/setup.cfg b/setup.cfg index 1debabe18..e40e4a8c3 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,10 +1,6 @@ [wheel] universal = 1 -[pycodestyle] -select = -max_line_length = 120 - [pep8] max_line_length = 120 diff --git a/setup.py b/setup.py index 429e7c09d..fc4d4dcd7 100644 --- a/setup.py +++ b/setup.py @@ -15,7 +15,7 @@ # This makes work easier for offline installs or low bandwidth machines needs_pytest = {'pytest', 'test', 'ptr'}.intersection(sys.argv) pytest_runner = ['pytest-runner'] if needs_pytest else [] -test_requirements = ['mock', 'pycodestyle', 'pytest', 'requests-mock>=1.0,<2.0', 'mypy==0.910'] +test_requirements = ['black', 'mock', 'pytest', 'requests-mock>=1.0,<2.0', 'mypy==0.910'] setup( name='tableauserverclient', diff --git a/tableauserverclient/__init__.py b/tableauserverclient/__init__.py index cacb96a0d..a098afad4 100644 --- a/tableauserverclient/__init__.py +++ b/tableauserverclient/__init__.py @@ -35,7 +35,7 @@ WebhookItem, PersonalAccessTokenAuth, FlowRunItem, - RevisionItem + RevisionItem, ) from .server import ( RequestOptions, diff --git a/tableauserverclient/_version.py b/tableauserverclient/_version.py index 62c3ce236..d47374097 100644 --- a/tableauserverclient/_version.py +++ b/tableauserverclient/_version.py @@ -120,7 +120,7 @@ def versions_from_parentdir(parentdir_prefix, root, verbose): dirname = os.path.basename(root) if dirname.startswith(parentdir_prefix): return { - "version": dirname[len(parentdir_prefix):], + "version": dirname[len(parentdir_prefix) :], "full-revisionid": None, "dirty": False, "error": None, @@ -187,7 +187,7 @@ def git_versions_from_keywords(keywords, tag_prefix, verbose): # starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of # just "foo-1.0". If we see a "tag: " prefix, prefer those. TAG = "tag: " - tags = set([r[len(TAG):] for r in refs if r.startswith(TAG)]) + tags = set([r[len(TAG) :] for r in refs if r.startswith(TAG)]) if not tags: # Either we're using git < 1.8.3, or there really are no tags. We use # a heuristic: assume all version tags have a digit. The old git %d @@ -204,7 +204,7 @@ def git_versions_from_keywords(keywords, tag_prefix, verbose): for ref in sorted(tags): # sorting will prefer e.g. "2.0" over "2.0rc1" if ref.startswith(tag_prefix): - r = ref[len(tag_prefix):] + r = ref[len(tag_prefix) :] if verbose: print("picking %s" % r) return { @@ -304,7 +304,7 @@ def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command): tag_prefix, ) return pieces - pieces["closest-tag"] = full_tag[len(tag_prefix):] + pieces["closest-tag"] = full_tag[len(tag_prefix) :] # distance: number of commits since tag pieces["distance"] = int(mo.group(2)) diff --git a/tableauserverclient/models/flow_run_item.py b/tableauserverclient/models/flow_run_item.py index 251c667b1..a0cbd55ab 100644 --- a/tableauserverclient/models/flow_run_item.py +++ b/tableauserverclient/models/flow_run_item.py @@ -5,50 +5,42 @@ class FlowRunItem(object): def __init__(self) -> None: - self._id=None - self._flow_id=None - self._status=None - self._started_at=None - self._completed_at=None - self._progress=None - self._background_job_id=None + self._id = None + self._flow_id = None + self._status = None + self._started_at = None + self._completed_at = None + self._progress = None + self._background_job_id = None - @property def id(self): return self._id - @property def flow_id(self): return self._flow_id - @property def status(self): return self._status - @property def started_at(self): return self._started_at - @property def completed_at(self): return self._completed_at - @property def progress(self): return self._progress - @property def background_job_id(self): return self._background_job_id - def _set_values( self, id, @@ -74,14 +66,13 @@ def _set_values( if background_job_id is not None: self._background_job_id = background_job_id - @classmethod def from_response(cls, resp, ns): all_flowrun_items = list() parsed_response = ET.fromstring(resp) all_flowrun_xml = itertools.chain( parsed_response.findall(".//t:flowRun[@id]", namespaces=ns), - parsed_response.findall(".//t:flowRuns[@id]", namespaces=ns) + parsed_response.findall(".//t:flowRuns[@id]", namespaces=ns), ) for flowrun_xml in all_flowrun_xml: @@ -91,16 +82,15 @@ def from_response(cls, resp, ns): all_flowrun_items.append(flowrun_item) return all_flowrun_items - @staticmethod def _parse_element(flowrun_xml, ns): result = {} - result['id'] = flowrun_xml.get("id", None) - result['flow_id'] = flowrun_xml.get("flowId", None) - result['status'] = flowrun_xml.get("status", None) - result['started_at'] = parse_datetime(flowrun_xml.get("startedAt", None)) - result['completed_at'] = parse_datetime(flowrun_xml.get("completedAt", None)) - result['progress'] = flowrun_xml.get("progress", None) - result['background_job_id'] = flowrun_xml.get("backgroundJobId", None) + result["id"] = flowrun_xml.get("id", None) + result["flow_id"] = flowrun_xml.get("flowId", None) + result["status"] = flowrun_xml.get("status", None) + result["started_at"] = parse_datetime(flowrun_xml.get("startedAt", None)) + result["completed_at"] = parse_datetime(flowrun_xml.get("completedAt", None)) + result["progress"] = flowrun_xml.get("progress", None) + result["background_job_id"] = flowrun_xml.get("backgroundJobId", None) return result diff --git a/tableauserverclient/models/job_item.py b/tableauserverclient/models/job_item.py index 8c5fc52a6..6d9cc5ec0 100644 --- a/tableauserverclient/models/job_item.py +++ b/tableauserverclient/models/job_item.py @@ -31,7 +31,7 @@ def __init__( finish_code: int = 0, notes: Optional[List[str]] = None, mode: Optional[str] = None, - flow_run: Optional[FlowRunItem] = None + flow_run: Optional[FlowRunItem] = None, ): self._id = id_ self._type = job_type diff --git a/tableauserverclient/models/revision_item.py b/tableauserverclient/models/revision_item.py index 6fac9d7d3..1c4510269 100644 --- a/tableauserverclient/models/revision_item.py +++ b/tableauserverclient/models/revision_item.py @@ -5,6 +5,7 @@ if TYPE_CHECKING: from datetime import datetime + class RevisionItem(object): def __init__(self): self._resource_id: Optional[str] = None @@ -55,12 +56,7 @@ def __repr__(self): ) @classmethod - def from_response( - cls, - resp: bytes, - ns, - resource_item - ) -> List["RevisionItem"]: + def from_response(cls, resp: bytes, ns, resource_item) -> List["RevisionItem"]: all_revision_items = list() parsed_response = ET.fromstring(resp) all_revision_xml = parsed_response.findall(".//t:revision", namespaces=ns) @@ -72,7 +68,7 @@ def from_response( revision_item._current = string_to_bool(revision_xml.get("isCurrent", "")) revision_item._deleted = string_to_bool(revision_xml.get("isDeleted", "")) revision_item._created_at = parse_datetime(revision_xml.get("createdAt", None)) - for user in revision_xml.findall('.//t:user', namespaces=ns): + for user in revision_xml.findall(".//t:user", namespaces=ns): revision_item._user_id = user.get("id", None) revision_item._user_name = user.get("name", None) diff --git a/tableauserverclient/server/__init__.py b/tableauserverclient/server/__init__.py index 5d6516cc0..242766ae0 100644 --- a/tableauserverclient/server/__init__.py +++ b/tableauserverclient/server/__init__.py @@ -33,7 +33,7 @@ FlowItem, WebhookItem, FlowRunItem, - RevisionItem + RevisionItem, ) from .endpoint import ( Auth, diff --git a/tableauserverclient/server/endpoint/datasources_endpoint.py b/tableauserverclient/server/endpoint/datasources_endpoint.py index 6b5825126..d29e52bea 100644 --- a/tableauserverclient/server/endpoint/datasources_endpoint.py +++ b/tableauserverclient/server/endpoint/datasources_endpoint.py @@ -403,20 +403,14 @@ def revisions_fetcher(): return self._get_datasource_revisions(datasource_item) datasource_item._set_revisions(revisions_fetcher) - logger.info( - "Populated revisions for datasource (ID: {0})".format(datasource_item.id) - ) + logger.info("Populated revisions for datasource (ID: {0})".format(datasource_item.id)) def _get_datasource_revisions( - self, - datasource_item: DatasourceItem, - req_options: Optional["RequestOptions"] = None + self, datasource_item: DatasourceItem, req_options: Optional["RequestOptions"] = None ) -> List[RevisionItem]: url = "{0}/{1}/revisions".format(self.baseurl, datasource_item.id) server_response = self.get_request(url, req_options) - revisions = RevisionItem.from_response( - server_response.content, self.parent_srv.namespace, datasource_item - ) + revisions = RevisionItem.from_response(server_response.content, self.parent_srv.namespace, datasource_item) return revisions # Download 1 datasource revision by revision number @@ -432,9 +426,7 @@ def download_revision( if not datasource_id: error = "Datasource ID undefined." raise ValueError(error) - url = "{0}/{1}/revisions/{2}/content".format( - self.baseurl, datasource_id, revision_number - ) + url = "{0}/{1}/revisions/{2}/content".format(self.baseurl, datasource_id, revision_number) if no_extract is False or no_extract is True: import warnings @@ -447,9 +439,7 @@ def download_revision( if not include_extract: url += "?includeExtract=False" - with closing( - self.get_request(url, parameters={"stream": True}) - ) as server_response: + with closing(self.get_request(url, parameters={"stream": True})) as server_response: _, params = cgi.parse_header(server_response.headers["Content-Disposition"]) filename = to_filename(os.path.basename(params["filename"])) @@ -460,9 +450,7 @@ def download_revision( f.write(chunk) logger.info( - "Downloaded datasource revision {0} to {1} (ID: {2})".format( - revision_number, download_path, datasource_id - ) + "Downloaded datasource revision {0} to {1} (ID: {2})".format(revision_number, download_path, datasource_id) ) return os.path.abspath(download_path) @@ -473,5 +461,6 @@ def delete_revision(self, datasource_id: str, revision_number: str) -> None: url = "/".join([self.baseurl, datasource_id, "revisions", revision_number]) self.delete_request(url) - logger.info("Deleted single datasource revsision (ID: {0}) (Revision: {1})".format(datasource_id, revision_number)) - + logger.info( + "Deleted single datasource revsision (ID: {0}) (Revision: {1})".format(datasource_id, revision_number) + ) diff --git a/tableauserverclient/server/endpoint/endpoint.py b/tableauserverclient/server/endpoint/endpoint.py index 5c8a56791..73e25cf4d 100644 --- a/tableauserverclient/server/endpoint/endpoint.py +++ b/tableauserverclient/server/endpoint/endpoint.py @@ -18,6 +18,7 @@ XML_CONTENT_TYPE = "text/xml" JSON_CONTENT_TYPE = "application/json" + class Endpoint(object): def __init__(self, parent_srv): self.parent_srv = parent_srv diff --git a/tableauserverclient/server/endpoint/exceptions.py b/tableauserverclient/server/endpoint/exceptions.py index e4185c1cb..26de0c3e3 100644 --- a/tableauserverclient/server/endpoint/exceptions.py +++ b/tableauserverclient/server/endpoint/exceptions.py @@ -77,6 +77,8 @@ def __str__(self): class JobCancelledException(JobFailedException): pass + + class FlowRunFailedException(Exception): def __init__(self, flow_run): self.background_job_id = flow_run.background_job_id @@ -87,4 +89,4 @@ def __str__(self): class FlowRunCancelledException(FlowRunFailedException): - pass + pass diff --git a/tableauserverclient/server/endpoint/flow_runs_endpoint.py b/tableauserverclient/server/endpoint/flow_runs_endpoint.py index 2ae1973d4..e6784a62c 100644 --- a/tableauserverclient/server/endpoint/flow_runs_endpoint.py +++ b/tableauserverclient/server/endpoint/flow_runs_endpoint.py @@ -37,19 +37,17 @@ def get_by_id(self, flow_run_id): server_response = self.get_request(url) return FlowRunItem.from_response(server_response.content, self.parent_srv.namespace)[0] - # Cancel 1 flow run by id @api(version="3.10") def cancel(self, flow_run_id): if not flow_run_id: error = "Flow ID undefined." raise ValueError(error) - id_ = getattr(flow_run_id, 'id', flow_run_id) + id_ = getattr(flow_run_id, "id", flow_run_id) url = "{0}/{1}".format(self.baseurl, id_) self.put_request(url) logger.info("Deleted single flow (ID: {0})".format(id_)) - @api(version="3.10") def wait_for_job(self, flow_run_id, *, timeout=None): if isinstance(flow_run_id, FlowRunItem): @@ -73,4 +71,4 @@ def wait_for_job(self, flow_run_id, *, timeout=None): elif flow_run.status == "Cancelled": raise FlowRunCancelledException(flow_run) else: - raise AssertionError("Unexpected status in flow_run", flow_run) \ No newline at end of file + raise AssertionError("Unexpected status in flow_run", flow_run) diff --git a/tableauserverclient/server/endpoint/jobs_endpoint.py b/tableauserverclient/server/endpoint/jobs_endpoint.py index bb47141a1..6049f9ce1 100644 --- a/tableauserverclient/server/endpoint/jobs_endpoint.py +++ b/tableauserverclient/server/endpoint/jobs_endpoint.py @@ -11,7 +11,6 @@ from typing import List, Optional, Tuple, TYPE_CHECKING, Union - class Jobs(Endpoint): @property def baseurl(self): @@ -20,7 +19,7 @@ def baseurl(self): @api(version="2.6") def get( self, job_id: Optional[str] = None, req_options: Optional[RequestOptionsBase] = None - ) -> Tuple[List[BackgroundJobItem], PaginationItem]: + ) -> Tuple[List[BackgroundJobItem], PaginationItem]: # Backwards Compatibility fix until we rev the major version if job_id is not None and isinstance(job_id, str): import warnings diff --git a/tableauserverclient/server/endpoint/projects_endpoint.py b/tableauserverclient/server/endpoint/projects_endpoint.py index 782a21654..85db76722 100644 --- a/tableauserverclient/server/endpoint/projects_endpoint.py +++ b/tableauserverclient/server/endpoint/projects_endpoint.py @@ -45,7 +45,7 @@ def update(self, project_item, samples=False): error = "Project item missing ID." raise MissingRequiredFieldError(error) - params = {"params": {RequestOptions.Field.PublishSamples: samples }} + params = {"params": {RequestOptions.Field.PublishSamples: samples}} url = "{0}/{1}".format(self.baseurl, project_item.id) update_req = RequestFactory.Project.update_req(project_item) server_response = self.put_request(url, update_req, XML_CONTENT_TYPE, params) @@ -55,7 +55,7 @@ def update(self, project_item, samples=False): @api(version="2.0") def create(self, project_item, samples=False): - params = {"params": {RequestOptions.Field.PublishSamples: samples }} + params = {"params": {RequestOptions.Field.PublishSamples: samples}} url = self.baseurl create_req = RequestFactory.Project.create_req(project_item) server_response = self.post_request(url, create_req, XML_CONTENT_TYPE, params) diff --git a/tableauserverclient/server/endpoint/workbooks_endpoint.py b/tableauserverclient/server/endpoint/workbooks_endpoint.py index aa9fdf05c..93cf1bb90 100644 --- a/tableauserverclient/server/endpoint/workbooks_endpoint.py +++ b/tableauserverclient/server/endpoint/workbooks_endpoint.py @@ -440,20 +440,14 @@ def revisions_fetcher(): return self._get_workbook_revisions(workbook_item) workbook_item._set_revisions(revisions_fetcher) - logger.info( - "Populated revisions for workbook (ID: {0})".format(workbook_item.id) - ) + logger.info("Populated revisions for workbook (ID: {0})".format(workbook_item.id)) def _get_workbook_revisions( - self, - workbook_item: WorkbookItem, - req_options: Optional["RequestOptions"]=None + self, workbook_item: WorkbookItem, req_options: Optional["RequestOptions"] = None ) -> List[RevisionItem]: url = "{0}/{1}/revisions".format(self.baseurl, workbook_item.id) server_response = self.get_request(url, req_options) - revisions = RevisionItem.from_response( - server_response.content, self.parent_srv.namespace, workbook_item - ) + revisions = RevisionItem.from_response(server_response.content, self.parent_srv.namespace, workbook_item) return revisions # Download 1 workbook revision by revision number @@ -469,9 +463,7 @@ def download_revision( if not workbook_id: error = "Workbook ID undefined." raise ValueError(error) - url = "{0}/{1}/revisions/{2}/content".format( - self.baseurl, workbook_id, revision_number - ) + url = "{0}/{1}/revisions/{2}/content".format(self.baseurl, workbook_id, revision_number) if no_extract is False or no_extract is True: import warnings @@ -485,9 +477,7 @@ def download_revision( if not include_extract: url += "?includeExtract=False" - with closing( - self.get_request(url, parameters={"stream": True}) - ) as server_response: + with closing(self.get_request(url, parameters={"stream": True})) as server_response: _, params = cgi.parse_header(server_response.headers["Content-Disposition"]) filename = to_filename(os.path.basename(params["filename"])) @@ -497,9 +487,7 @@ def download_revision( for chunk in server_response.iter_content(1024): # 1KB f.write(chunk) logger.info( - "Downloaded workbook revision {0} to {1} (ID: {2})".format( - revision_number, download_path, workbook_id - ) + "Downloaded workbook revision {0} to {1} (ID: {2})".format(revision_number, download_path, workbook_id) ) return os.path.abspath(download_path) diff --git a/tableauserverclient/server/request_factory.py b/tableauserverclient/server/request_factory.py index 395971ed1..3880f432c 100644 --- a/tableauserverclient/server/request_factory.py +++ b/tableauserverclient/server/request_factory.py @@ -795,7 +795,7 @@ def _generate_xml( _add_connections_element(connections_element, connection) if workbook_item.hidden_views is not None: - views_element = ET.SubElement(workbook_element, 'views') + views_element = ET.SubElement(workbook_element, "views") for view_name in workbook_item.hidden_views: _add_hiddenview_element(views_element, view_name) diff --git a/tableauserverclient/server/server.py b/tableauserverclient/server/server.py index 0b2e9d053..c4c635a91 100644 --- a/tableauserverclient/server/server.py +++ b/tableauserverclient/server/server.py @@ -25,7 +25,7 @@ Favorites, DataAlerts, Fileuploads, - FlowRuns + FlowRuns, ) from .endpoint.exceptions import ( EndpointUnavailableError, diff --git a/test/_utils.py b/test/_utils.py index 626838f23..4ee919750 100644 --- a/test/_utils.py +++ b/test/_utils.py @@ -2,7 +2,7 @@ import unittest import os.path -TEST_ASSET_DIR = os.path.join(os.path.dirname(__file__), 'assets') +TEST_ASSET_DIR = os.path.join(os.path.dirname(__file__), "assets") def asset(filename): @@ -10,8 +10,8 @@ def asset(filename): def read_xml_asset(filename): - with open(asset(filename), 'rb') as f: - return f.read().decode('utf-8') + with open(asset(filename), "rb") as f: + return f.read().decode("utf-8") def read_xml_assets(*args): @@ -28,7 +28,7 @@ def sleep_mock(interval): def get_time(): return mock_time - + try: patch = unittest.mock.patch except AttributeError: diff --git a/test/test_auth.py b/test/test_auth.py index 3dbf87737..ff757909e 100644 --- a/test/test_auth.py +++ b/test/test_auth.py @@ -3,87 +3,89 @@ import requests_mock import tableauserverclient as TSC -TEST_ASSET_DIR = os.path.join(os.path.dirname(__file__), 'assets') +TEST_ASSET_DIR = os.path.join(os.path.dirname(__file__), "assets") -SIGN_IN_XML = os.path.join(TEST_ASSET_DIR, 'auth_sign_in.xml') -SIGN_IN_IMPERSONATE_XML = os.path.join(TEST_ASSET_DIR, 'auth_sign_in_impersonate.xml') -SIGN_IN_ERROR_XML = os.path.join(TEST_ASSET_DIR, 'auth_sign_in_error.xml') +SIGN_IN_XML = os.path.join(TEST_ASSET_DIR, "auth_sign_in.xml") +SIGN_IN_IMPERSONATE_XML = os.path.join(TEST_ASSET_DIR, "auth_sign_in_impersonate.xml") +SIGN_IN_ERROR_XML = os.path.join(TEST_ASSET_DIR, "auth_sign_in_error.xml") class AuthTests(unittest.TestCase): def setUp(self): - self.server = TSC.Server('http://test') + self.server = TSC.Server("http://test") self.baseurl = self.server.auth.baseurl def test_sign_in(self): - with open(SIGN_IN_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(SIGN_IN_XML, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: - m.post(self.baseurl + '/signin', text=response_xml) - tableau_auth = TSC.TableauAuth('testuser', 'password', site_id='Samples') + m.post(self.baseurl + "/signin", text=response_xml) + tableau_auth = TSC.TableauAuth("testuser", "password", site_id="Samples") self.server.auth.sign_in(tableau_auth) - self.assertEqual('eIX6mvFsqyansa4KqEI1UwOpS8ggRs2l', self.server.auth_token) - self.assertEqual('6b7179ba-b82b-4f0f-91ed-812074ac5da6', self.server.site_id) - self.assertEqual('1a96d216-e9b8-497b-a82a-0b899a965e01', self.server.user_id) + self.assertEqual("eIX6mvFsqyansa4KqEI1UwOpS8ggRs2l", self.server.auth_token) + self.assertEqual("6b7179ba-b82b-4f0f-91ed-812074ac5da6", self.server.site_id) + self.assertEqual("1a96d216-e9b8-497b-a82a-0b899a965e01", self.server.user_id) def test_sign_in_with_personal_access_tokens(self): - with open(SIGN_IN_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(SIGN_IN_XML, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: - m.post(self.baseurl + '/signin', text=response_xml) - tableau_auth = TSC.PersonalAccessTokenAuth(token_name='mytoken', - personal_access_token='Random123Generated', site_id='Samples') + m.post(self.baseurl + "/signin", text=response_xml) + tableau_auth = TSC.PersonalAccessTokenAuth( + token_name="mytoken", personal_access_token="Random123Generated", site_id="Samples" + ) self.server.auth.sign_in(tableau_auth) - self.assertEqual('eIX6mvFsqyansa4KqEI1UwOpS8ggRs2l', self.server.auth_token) - self.assertEqual('6b7179ba-b82b-4f0f-91ed-812074ac5da6', self.server.site_id) - self.assertEqual('1a96d216-e9b8-497b-a82a-0b899a965e01', self.server.user_id) + self.assertEqual("eIX6mvFsqyansa4KqEI1UwOpS8ggRs2l", self.server.auth_token) + self.assertEqual("6b7179ba-b82b-4f0f-91ed-812074ac5da6", self.server.site_id) + self.assertEqual("1a96d216-e9b8-497b-a82a-0b899a965e01", self.server.user_id) def test_sign_in_impersonate(self): - with open(SIGN_IN_IMPERSONATE_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(SIGN_IN_IMPERSONATE_XML, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: - m.post(self.baseurl + '/signin', text=response_xml) - tableau_auth = TSC.TableauAuth('testuser', 'password', - user_id_to_impersonate='dd2239f6-ddf1-4107-981a-4cf94e415794') + m.post(self.baseurl + "/signin", text=response_xml) + tableau_auth = TSC.TableauAuth( + "testuser", "password", user_id_to_impersonate="dd2239f6-ddf1-4107-981a-4cf94e415794" + ) self.server.auth.sign_in(tableau_auth) - self.assertEqual('MJonFA6HDyy2C3oqR13fRGqE6cmgzwq3', self.server.auth_token) - self.assertEqual('dad65087-b08b-4603-af4e-2887b8aafc67', self.server.site_id) - self.assertEqual('dd2239f6-ddf1-4107-981a-4cf94e415794', self.server.user_id) + self.assertEqual("MJonFA6HDyy2C3oqR13fRGqE6cmgzwq3", self.server.auth_token) + self.assertEqual("dad65087-b08b-4603-af4e-2887b8aafc67", self.server.site_id) + self.assertEqual("dd2239f6-ddf1-4107-981a-4cf94e415794", self.server.user_id) def test_sign_in_error(self): - with open(SIGN_IN_ERROR_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(SIGN_IN_ERROR_XML, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: - m.post(self.baseurl + '/signin', text=response_xml, status_code=401) - tableau_auth = TSC.TableauAuth('testuser', 'wrongpassword') + m.post(self.baseurl + "/signin", text=response_xml, status_code=401) + tableau_auth = TSC.TableauAuth("testuser", "wrongpassword") self.assertRaises(TSC.ServerResponseError, self.server.auth.sign_in, tableau_auth) def test_sign_in_invalid_token(self): - with open(SIGN_IN_ERROR_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(SIGN_IN_ERROR_XML, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: - m.post(self.baseurl + '/signin', text=response_xml, status_code=401) - tableau_auth = TSC.PersonalAccessTokenAuth(token_name='mytoken', personal_access_token='invalid') + m.post(self.baseurl + "/signin", text=response_xml, status_code=401) + tableau_auth = TSC.PersonalAccessTokenAuth(token_name="mytoken", personal_access_token="invalid") self.assertRaises(TSC.ServerResponseError, self.server.auth.sign_in, tableau_auth) def test_sign_in_without_auth(self): - with open(SIGN_IN_ERROR_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(SIGN_IN_ERROR_XML, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: - m.post(self.baseurl + '/signin', text=response_xml, status_code=401) - tableau_auth = TSC.TableauAuth('', '') + m.post(self.baseurl + "/signin", text=response_xml, status_code=401) + tableau_auth = TSC.TableauAuth("", "") self.assertRaises(TSC.ServerResponseError, self.server.auth.sign_in, tableau_auth) def test_sign_out(self): - with open(SIGN_IN_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(SIGN_IN_XML, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: - m.post(self.baseurl + '/signin', text=response_xml) - m.post(self.baseurl + '/signout', text='') - tableau_auth = TSC.TableauAuth('testuser', 'password') + m.post(self.baseurl + "/signin", text=response_xml) + m.post(self.baseurl + "/signout", text="") + tableau_auth = TSC.TableauAuth("testuser", "password") self.server.auth.sign_in(tableau_auth) self.server.auth.sign_out() @@ -92,33 +94,33 @@ def test_sign_out(self): self.assertIsNone(self.server._user_id) def test_switch_site(self): - self.server.version = '2.6' + self.server.version = "2.6" baseurl = self.server.auth.baseurl - site_id, user_id, auth_token = list('123') + site_id, user_id, auth_token = list("123") self.server._set_auth(site_id, user_id, auth_token) - with open(SIGN_IN_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(SIGN_IN_XML, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: - m.post(baseurl + '/switchSite', text=response_xml) - site = TSC.SiteItem('Samples', 'Samples') + m.post(baseurl + "/switchSite", text=response_xml) + site = TSC.SiteItem("Samples", "Samples") self.server.auth.switch_site(site) - self.assertEqual('eIX6mvFsqyansa4KqEI1UwOpS8ggRs2l', self.server.auth_token) - self.assertEqual('6b7179ba-b82b-4f0f-91ed-812074ac5da6', self.server.site_id) - self.assertEqual('1a96d216-e9b8-497b-a82a-0b899a965e01', self.server.user_id) + self.assertEqual("eIX6mvFsqyansa4KqEI1UwOpS8ggRs2l", self.server.auth_token) + self.assertEqual("6b7179ba-b82b-4f0f-91ed-812074ac5da6", self.server.site_id) + self.assertEqual("1a96d216-e9b8-497b-a82a-0b899a965e01", self.server.user_id) def test_revoke_all_server_admin_tokens(self): self.server.version = "3.10" baseurl = self.server.auth.baseurl - with open(SIGN_IN_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(SIGN_IN_XML, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: - m.post(baseurl + '/signin', text=response_xml) - m.post(baseurl + '/revokeAllServerAdminTokens', text='') - tableau_auth = TSC.TableauAuth('testuser', 'password') + m.post(baseurl + "/signin", text=response_xml) + m.post(baseurl + "/revokeAllServerAdminTokens", text="") + tableau_auth = TSC.TableauAuth("testuser", "password") self.server.auth.sign_in(tableau_auth) self.server.auth.revoke_all_server_admin_tokens() - self.assertEqual('eIX6mvFsqyansa4KqEI1UwOpS8ggRs2l', self.server.auth_token) - self.assertEqual('6b7179ba-b82b-4f0f-91ed-812074ac5da6', self.server.site_id) - self.assertEqual('1a96d216-e9b8-497b-a82a-0b899a965e01', self.server.user_id) + self.assertEqual("eIX6mvFsqyansa4KqEI1UwOpS8ggRs2l", self.server.auth_token) + self.assertEqual("6b7179ba-b82b-4f0f-91ed-812074ac5da6", self.server.site_id) + self.assertEqual("1a96d216-e9b8-497b-a82a-0b899a965e01", self.server.user_id) diff --git a/test/test_data_acceleration_report.py b/test/test_data_acceleration_report.py index 7722bf230..d3cf96db1 100644 --- a/test/test_data_acceleration_report.py +++ b/test/test_data_acceleration_report.py @@ -5,16 +5,16 @@ import tableauserverclient as TSC from ._utils import read_xml_asset, read_xml_assets, asset -GET_XML = 'data_acceleration_report.xml' +GET_XML = "data_acceleration_report.xml" class DataAccelerationReportTests(unittest.TestCase): def setUp(self): - self.server = TSC.Server('http://test') + self.server = TSC.Server("http://test") # Fake signin - self.server._site_id = 'dad65087-b08b-4603-af4e-2887b8aafc67' - self.server._auth_token = 'j80k54ll2lfMZ0tv97mlPvvSCRyD0DOM' + self.server._site_id = "dad65087-b08b-4603-af4e-2887b8aafc67" + self.server._auth_token = "j80k54ll2lfMZ0tv97mlPvvSCRyD0DOM" self.server.version = "3.8" self.baseurl = self.server.data_acceleration_report.baseurl diff --git a/test/test_dataalert.py b/test/test_dataalert.py index 7822d3000..a2810ce45 100644 --- a/test/test_dataalert.py +++ b/test/test_dataalert.py @@ -8,19 +8,19 @@ from tableauserverclient.server.request_factory import RequestFactory from ._utils import read_xml_asset, read_xml_assets, asset -GET_XML = 'data_alerts_get.xml' -GET_BY_ID_XML = 'data_alerts_get_by_id.xml' -ADD_USER_TO_ALERT = 'data_alerts_add_user.xml' -UPDATE_XML = 'data_alerts_update.xml' +GET_XML = "data_alerts_get.xml" +GET_BY_ID_XML = "data_alerts_get_by_id.xml" +ADD_USER_TO_ALERT = "data_alerts_add_user.xml" +UPDATE_XML = "data_alerts_update.xml" class DataAlertTests(unittest.TestCase): def setUp(self): - self.server = TSC.Server('http://test') + self.server = TSC.Server("http://test") # Fake signin - self.server._site_id = 'dad65087-b08b-4603-af4e-2887b8aafc67' - self.server._auth_token = 'j80k54ll2lfMZ0tv97mlPvvSCRyD0DOM' + self.server._site_id = "dad65087-b08b-4603-af4e-2887b8aafc67" + self.server._auth_token = "j80k54ll2lfMZ0tv97mlPvvSCRyD0DOM" self.server.version = "3.2" self.baseurl = self.server.data_alerts.baseurl @@ -32,69 +32,69 @@ def test_get(self): all_alerts, pagination_item = self.server.data_alerts.get() self.assertEqual(1, pagination_item.total_available) - self.assertEqual('5ea59b45-e497-5673-8809-bfe213236f75', all_alerts[0].id) - self.assertEqual('Data Alert test', all_alerts[0].subject) - self.assertEqual('5de011f8-5aa9-4d5b-b991-f462c8dd6bb7', all_alerts[0].creatorId) - self.assertEqual('2020-08-10T23:17:06Z', all_alerts[0].createdAt) - self.assertEqual('2020-08-10T23:17:06Z', all_alerts[0].updatedAt) - self.assertEqual('Daily', all_alerts[0].frequency) - self.assertEqual('true', all_alerts[0].public) - self.assertEqual('5de011f8-5aa9-4d5b-b991-f462c8dd6bb7', all_alerts[0].owner_id) - self.assertEqual('Bob', all_alerts[0].owner_name) - self.assertEqual('d79634e1-6063-4ec9-95ff-50acbf609ff5', all_alerts[0].view_id) - self.assertEqual('ENDANGERED SAFARI', all_alerts[0].view_name) - self.assertEqual('6d13b0ca-043d-4d42-8c9d-3f3313ea3a00', all_alerts[0].workbook_id) - self.assertEqual('Safari stats', all_alerts[0].workbook_name) - self.assertEqual('5241e88d-d384-4fd7-9c2f-648b5247efc5', all_alerts[0].project_id) - self.assertEqual('Default', all_alerts[0].project_name) + self.assertEqual("5ea59b45-e497-5673-8809-bfe213236f75", all_alerts[0].id) + self.assertEqual("Data Alert test", all_alerts[0].subject) + self.assertEqual("5de011f8-5aa9-4d5b-b991-f462c8dd6bb7", all_alerts[0].creatorId) + self.assertEqual("2020-08-10T23:17:06Z", all_alerts[0].createdAt) + self.assertEqual("2020-08-10T23:17:06Z", all_alerts[0].updatedAt) + self.assertEqual("Daily", all_alerts[0].frequency) + self.assertEqual("true", all_alerts[0].public) + self.assertEqual("5de011f8-5aa9-4d5b-b991-f462c8dd6bb7", all_alerts[0].owner_id) + self.assertEqual("Bob", all_alerts[0].owner_name) + self.assertEqual("d79634e1-6063-4ec9-95ff-50acbf609ff5", all_alerts[0].view_id) + self.assertEqual("ENDANGERED SAFARI", all_alerts[0].view_name) + self.assertEqual("6d13b0ca-043d-4d42-8c9d-3f3313ea3a00", all_alerts[0].workbook_id) + self.assertEqual("Safari stats", all_alerts[0].workbook_name) + self.assertEqual("5241e88d-d384-4fd7-9c2f-648b5247efc5", all_alerts[0].project_id) + self.assertEqual("Default", all_alerts[0].project_name) def test_get_by_id(self): response_xml = read_xml_asset(GET_BY_ID_XML) with requests_mock.mock() as m: - m.get(self.baseurl + '/5ea59b45-e497-5673-8809-bfe213236f75', text=response_xml) - alert = self.server.data_alerts.get_by_id('5ea59b45-e497-5673-8809-bfe213236f75') + m.get(self.baseurl + "/5ea59b45-e497-5673-8809-bfe213236f75", text=response_xml) + alert = self.server.data_alerts.get_by_id("5ea59b45-e497-5673-8809-bfe213236f75") self.assertTrue(isinstance(alert.recipients, list)) self.assertEqual(len(alert.recipients), 1) - self.assertEqual(alert.recipients[0], 'dd2239f6-ddf1-4107-981a-4cf94e415794') + self.assertEqual(alert.recipients[0], "dd2239f6-ddf1-4107-981a-4cf94e415794") def test_update(self): response_xml = read_xml_asset(UPDATE_XML) with requests_mock.mock() as m: - m.put(self.baseurl + '/5ea59b45-e497-5673-8809-bfe213236f75', text=response_xml) + m.put(self.baseurl + "/5ea59b45-e497-5673-8809-bfe213236f75", text=response_xml) single_alert = TSC.DataAlertItem() - single_alert._id = '5ea59b45-e497-5673-8809-bfe213236f75' - single_alert._subject = 'Data Alert test' - single_alert._frequency = 'Daily' + single_alert._id = "5ea59b45-e497-5673-8809-bfe213236f75" + single_alert._subject = "Data Alert test" + single_alert._frequency = "Daily" single_alert._public = "true" single_alert._owner_id = "5de011f8-5aa9-4d5b-b991-f462c8dd6bb7" single_alert = self.server.data_alerts.update(single_alert) - self.assertEqual('5ea59b45-e497-5673-8809-bfe213236f75', single_alert.id) - self.assertEqual('Data Alert test', single_alert.subject) - self.assertEqual('5de011f8-5aa9-4d5b-b991-f462c8dd6bb7', single_alert.creatorId) - self.assertEqual('2020-08-10T23:17:06Z', single_alert.createdAt) - self.assertEqual('2020-08-10T23:17:06Z', single_alert.updatedAt) - self.assertEqual('Daily', single_alert.frequency) - self.assertEqual('true', single_alert.public) - self.assertEqual('5de011f8-5aa9-4d5b-b991-f462c8dd6bb7', single_alert.owner_id) - self.assertEqual('Bob', single_alert.owner_name) - self.assertEqual('d79634e1-6063-4ec9-95ff-50acbf609ff5', single_alert.view_id) - self.assertEqual('ENDANGERED SAFARI', single_alert.view_name) - self.assertEqual('6d13b0ca-043d-4d42-8c9d-3f3313ea3a00', single_alert.workbook_id) - self.assertEqual('Safari stats', single_alert.workbook_name) - self.assertEqual('5241e88d-d384-4fd7-9c2f-648b5247efc5', single_alert.project_id) - self.assertEqual('Default', single_alert.project_name) + self.assertEqual("5ea59b45-e497-5673-8809-bfe213236f75", single_alert.id) + self.assertEqual("Data Alert test", single_alert.subject) + self.assertEqual("5de011f8-5aa9-4d5b-b991-f462c8dd6bb7", single_alert.creatorId) + self.assertEqual("2020-08-10T23:17:06Z", single_alert.createdAt) + self.assertEqual("2020-08-10T23:17:06Z", single_alert.updatedAt) + self.assertEqual("Daily", single_alert.frequency) + self.assertEqual("true", single_alert.public) + self.assertEqual("5de011f8-5aa9-4d5b-b991-f462c8dd6bb7", single_alert.owner_id) + self.assertEqual("Bob", single_alert.owner_name) + self.assertEqual("d79634e1-6063-4ec9-95ff-50acbf609ff5", single_alert.view_id) + self.assertEqual("ENDANGERED SAFARI", single_alert.view_name) + self.assertEqual("6d13b0ca-043d-4d42-8c9d-3f3313ea3a00", single_alert.workbook_id) + self.assertEqual("Safari stats", single_alert.workbook_name) + self.assertEqual("5241e88d-d384-4fd7-9c2f-648b5247efc5", single_alert.project_id) + self.assertEqual("Default", single_alert.project_name) def test_add_user_to_alert(self): response_xml = read_xml_asset(ADD_USER_TO_ALERT) single_alert = TSC.DataAlertItem() - single_alert._id = '0448d2ed-590d-4fa0-b272-a2a8a24555b5' - in_user = TSC.UserItem('Bob', TSC.UserItem.Roles.Explorer) - in_user._id = '5de011f8-5aa9-4d5b-b991-f462c8dd6bb7' + single_alert._id = "0448d2ed-590d-4fa0-b272-a2a8a24555b5" + in_user = TSC.UserItem("Bob", TSC.UserItem.Roles.Explorer) + in_user._id = "5de011f8-5aa9-4d5b-b991-f462c8dd6bb7" with requests_mock.mock() as m: - m.post(self.baseurl + '/0448d2ed-590d-4fa0-b272-a2a8a24555b5/users', text=response_xml) + m.post(self.baseurl + "/0448d2ed-590d-4fa0-b272-a2a8a24555b5/users", text=response_xml) out_user = self.server.data_alerts.add_user_to_alert(single_alert, in_user) @@ -104,12 +104,12 @@ def test_add_user_to_alert(self): def test_delete(self): with requests_mock.mock() as m: - m.delete(self.baseurl + '/0448d2ed-590d-4fa0-b272-a2a8a24555b5', status_code=204) - self.server.data_alerts.delete('0448d2ed-590d-4fa0-b272-a2a8a24555b5') + m.delete(self.baseurl + "/0448d2ed-590d-4fa0-b272-a2a8a24555b5", status_code=204) + self.server.data_alerts.delete("0448d2ed-590d-4fa0-b272-a2a8a24555b5") def test_delete_user_from_alert(self): - alert_id = '5ea59b45-e497-5673-8809-bfe213236f75' - user_id = '5de011f8-5aa9-4d5b-b991-f462c8dd6bb7' + alert_id = "5ea59b45-e497-5673-8809-bfe213236f75" + user_id = "5de011f8-5aa9-4d5b-b991-f462c8dd6bb7" with requests_mock.mock() as m: - m.delete(self.baseurl + '/{0}/users/{1}'.format(alert_id, user_id), status_code=204) + m.delete(self.baseurl + "/{0}/users/{1}".format(alert_id, user_id), status_code=204) self.server.data_alerts.delete_user_from_alert(alert_id, user_id) diff --git a/test/test_database.py b/test/test_database.py index e7c6a6fb6..8e27ccf52 100644 --- a/test/test_database.py +++ b/test/test_database.py @@ -8,18 +8,18 @@ from tableauserverclient.server.request_factory import RequestFactory from ._utils import read_xml_asset, read_xml_assets, asset -GET_XML = 'database_get.xml' -POPULATE_PERMISSIONS_XML = 'database_populate_permissions.xml' -UPDATE_XML = 'database_update.xml' +GET_XML = "database_get.xml" +POPULATE_PERMISSIONS_XML = "database_populate_permissions.xml" +UPDATE_XML = "database_update.xml" GET_DQW_BY_CONTENT = "dqw_by_content_type.xml" class DatabaseTests(unittest.TestCase): def setUp(self): - self.server = TSC.Server('http://test') + self.server = TSC.Server("http://test") # Fake signin - self.server._site_id = 'dad65087-b08b-4603-af4e-2887b8aafc67' - self.server._auth_token = 'j80k54ll2lfMZ0tv97mlPvvSCRyD0DOM' + self.server._site_id = "dad65087-b08b-4603-af4e-2887b8aafc67" + self.server._auth_token = "j80k54ll2lfMZ0tv97mlPvvSCRyD0DOM" self.server.version = "3.5" self.baseurl = self.server.databases.baseurl @@ -31,64 +31,72 @@ def test_get(self): all_databases, pagination_item = self.server.databases.get() self.assertEqual(5, pagination_item.total_available) - self.assertEqual('5ea59b45-e497-4827-8809-bfe213236f75', all_databases[0].id) - self.assertEqual('hyper', all_databases[0].connection_type) - self.assertEqual('hyper_0.hyper', all_databases[0].name) - - self.assertEqual('23591f2c-4802-4d6a-9e28-574a8ea9bc4c', all_databases[1].id) - self.assertEqual('sqlserver', all_databases[1].connection_type) - self.assertEqual('testv1', all_databases[1].name) - self.assertEqual('9324cf6b-ba72-4b8e-b895-ac3f28d2f0e0', all_databases[1].contact_id) + self.assertEqual("5ea59b45-e497-4827-8809-bfe213236f75", all_databases[0].id) + self.assertEqual("hyper", all_databases[0].connection_type) + self.assertEqual("hyper_0.hyper", all_databases[0].name) + + self.assertEqual("23591f2c-4802-4d6a-9e28-574a8ea9bc4c", all_databases[1].id) + self.assertEqual("sqlserver", all_databases[1].connection_type) + self.assertEqual("testv1", all_databases[1].name) + self.assertEqual("9324cf6b-ba72-4b8e-b895-ac3f28d2f0e0", all_databases[1].contact_id) self.assertEqual(True, all_databases[1].certified) def test_update(self): response_xml = read_xml_asset(UPDATE_XML) with requests_mock.mock() as m: - m.put(self.baseurl + '/23591f2c-4802-4d6a-9e28-574a8ea9bc4c', text=response_xml) - single_database = TSC.DatabaseItem('test') - single_database.contact_id = '9324cf6b-ba72-4b8e-b895-ac3f28d2f0e0' - single_database._id = '23591f2c-4802-4d6a-9e28-574a8ea9bc4c' + m.put(self.baseurl + "/23591f2c-4802-4d6a-9e28-574a8ea9bc4c", text=response_xml) + single_database = TSC.DatabaseItem("test") + single_database.contact_id = "9324cf6b-ba72-4b8e-b895-ac3f28d2f0e0" + single_database._id = "23591f2c-4802-4d6a-9e28-574a8ea9bc4c" single_database.certified = True single_database.certification_note = "Test" single_database = self.server.databases.update(single_database) - self.assertEqual('23591f2c-4802-4d6a-9e28-574a8ea9bc4c', single_database.id) - self.assertEqual('9324cf6b-ba72-4b8e-b895-ac3f28d2f0e0', single_database.contact_id) + self.assertEqual("23591f2c-4802-4d6a-9e28-574a8ea9bc4c", single_database.id) + self.assertEqual("9324cf6b-ba72-4b8e-b895-ac3f28d2f0e0", single_database.contact_id) self.assertEqual(True, single_database.certified) self.assertEqual("Test", single_database.certification_note) def test_populate_permissions(self): - with open(asset(POPULATE_PERMISSIONS_XML), 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(asset(POPULATE_PERMISSIONS_XML), "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: - m.get(self.baseurl + '/0448d2ed-590d-4fa0-b272-a2a8a24555b5/permissions', text=response_xml) - single_database = TSC.DatabaseItem('test') - single_database._id = '0448d2ed-590d-4fa0-b272-a2a8a24555b5' + m.get(self.baseurl + "/0448d2ed-590d-4fa0-b272-a2a8a24555b5/permissions", text=response_xml) + single_database = TSC.DatabaseItem("test") + single_database._id = "0448d2ed-590d-4fa0-b272-a2a8a24555b5" self.server.databases.populate_permissions(single_database) permissions = single_database.permissions - self.assertEqual(permissions[0].grantee.tag_name, 'group') - self.assertEqual(permissions[0].grantee.id, '5e5e1978-71fa-11e4-87dd-7382f5c437af') - self.assertDictEqual(permissions[0].capabilities, { - TSC.Permission.Capability.ChangePermissions: TSC.Permission.Mode.Deny, - TSC.Permission.Capability.Read: TSC.Permission.Mode.Allow, - }) - - self.assertEqual(permissions[1].grantee.tag_name, 'user') - self.assertEqual(permissions[1].grantee.id, '7c37ee24-c4b1-42b6-a154-eaeab7ee330a') - self.assertDictEqual(permissions[1].capabilities, { - TSC.Permission.Capability.Write: TSC.Permission.Mode.Allow, - }) + self.assertEqual(permissions[0].grantee.tag_name, "group") + self.assertEqual(permissions[0].grantee.id, "5e5e1978-71fa-11e4-87dd-7382f5c437af") + self.assertDictEqual( + permissions[0].capabilities, + { + TSC.Permission.Capability.ChangePermissions: TSC.Permission.Mode.Deny, + TSC.Permission.Capability.Read: TSC.Permission.Mode.Allow, + }, + ) + + self.assertEqual(permissions[1].grantee.tag_name, "user") + self.assertEqual(permissions[1].grantee.id, "7c37ee24-c4b1-42b6-a154-eaeab7ee330a") + self.assertDictEqual( + permissions[1].capabilities, + { + TSC.Permission.Capability.Write: TSC.Permission.Mode.Allow, + }, + ) def test_populate_data_quality_warning(self): - with open(asset(GET_DQW_BY_CONTENT), 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(asset(GET_DQW_BY_CONTENT), "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: - m.get(self.server.databases._data_quality_warnings.baseurl + '/94441d26-9a52-4a42-b0fb-3f94792d1aac', - text=response_xml) - single_database = TSC.DatabaseItem('test') - single_database._id = '94441d26-9a52-4a42-b0fb-3f94792d1aac' + m.get( + self.server.databases._data_quality_warnings.baseurl + "/94441d26-9a52-4a42-b0fb-3f94792d1aac", + text=response_xml, + ) + single_database = TSC.DatabaseItem("test") + single_database._id = "94441d26-9a52-4a42-b0fb-3f94792d1aac" self.server.databases.populate_dqw(single_database) dqws = single_database.dqws @@ -104,5 +112,5 @@ def test_populate_data_quality_warning(self): def test_delete(self): with requests_mock.mock() as m: - m.delete(self.baseurl + '/0448d2ed-590d-4fa0-b272-a2a8a24555b5', status_code=204) - self.server.databases.delete('0448d2ed-590d-4fa0-b272-a2a8a24555b5') + m.delete(self.baseurl + "/0448d2ed-590d-4fa0-b272-a2a8a24555b5", status_code=204) + self.server.databases.delete("0448d2ed-590d-4fa0-b272-a2a8a24555b5") diff --git a/test/test_datasource.py b/test/test_datasource.py index b943f341d..67b7b579c 100644 --- a/test/test_datasource.py +++ b/test/test_datasource.py @@ -13,29 +13,28 @@ from tableauserverclient.server.request_factory import RequestFactory from ._utils import read_xml_asset, read_xml_assets, asset - -ADD_TAGS_XML = 'datasource_add_tags.xml' -GET_XML = 'datasource_get.xml' -GET_EMPTY_XML = 'datasource_get_empty.xml' -GET_BY_ID_XML = 'datasource_get_by_id.xml' -POPULATE_CONNECTIONS_XML = 'datasource_populate_connections.xml' -POPULATE_PERMISSIONS_XML = 'datasource_populate_permissions.xml' -PUBLISH_XML = 'datasource_publish.xml' -PUBLISH_XML_ASYNC = 'datasource_publish_async.xml' -REFRESH_XML = 'datasource_refresh.xml' -REVISION_XML = 'datasource_revision.xml' -UPDATE_XML = 'datasource_update.xml' -UPDATE_HYPER_DATA_XML = 'datasource_data_update.xml' -UPDATE_CONNECTION_XML = 'datasource_connection_update.xml' +ADD_TAGS_XML = "datasource_add_tags.xml" +GET_XML = "datasource_get.xml" +GET_EMPTY_XML = "datasource_get_empty.xml" +GET_BY_ID_XML = "datasource_get_by_id.xml" +POPULATE_CONNECTIONS_XML = "datasource_populate_connections.xml" +POPULATE_PERMISSIONS_XML = "datasource_populate_permissions.xml" +PUBLISH_XML = "datasource_publish.xml" +PUBLISH_XML_ASYNC = "datasource_publish_async.xml" +REFRESH_XML = "datasource_refresh.xml" +REVISION_XML = "datasource_revision.xml" +UPDATE_XML = "datasource_update.xml" +UPDATE_HYPER_DATA_XML = "datasource_data_update.xml" +UPDATE_CONNECTION_XML = "datasource_connection_update.xml" class DatasourceTests(unittest.TestCase): def setUp(self) -> None: - self.server = TSC.Server('http://test') + self.server = TSC.Server("http://test") # Fake signin - self.server._site_id = 'dad65087-b08b-4603-af4e-2887b8aafc67' - self.server._auth_token = 'j80k54ll2lfMZ0tv97mlPvvSCRyD0DOM' + self.server._site_id = "dad65087-b08b-4603-af4e-2887b8aafc67" + self.server._auth_token = "j80k54ll2lfMZ0tv97mlPvvSCRyD0DOM" self.baseurl = self.server.datasources.baseurl @@ -46,33 +45,33 @@ def test_get(self) -> None: all_datasources, pagination_item = self.server.datasources.get() self.assertEqual(2, pagination_item.total_available) - self.assertEqual('e76a1461-3b1d-4588-bf1b-17551a879ad9', all_datasources[0].id) - self.assertEqual('dataengine', all_datasources[0].datasource_type) - self.assertEqual('SampleDsDescription', all_datasources[0].description) - self.assertEqual('SampleDS', all_datasources[0].content_url) - self.assertEqual('2016-08-11T21:22:40Z', format_datetime(all_datasources[0].created_at)) - self.assertEqual('2016-08-11T21:34:17Z', format_datetime(all_datasources[0].updated_at)) - self.assertEqual('default', all_datasources[0].project_name) - self.assertEqual('SampleDS', all_datasources[0].name) - self.assertEqual('ee8c6e70-43b6-11e6-af4f-f7b0d8e20760', all_datasources[0].project_id) - self.assertEqual('5de011f8-5aa9-4d5b-b991-f462c8dd6bb7', all_datasources[0].owner_id) - self.assertEqual('https://web.com', all_datasources[0].webpage_url) + self.assertEqual("e76a1461-3b1d-4588-bf1b-17551a879ad9", all_datasources[0].id) + self.assertEqual("dataengine", all_datasources[0].datasource_type) + self.assertEqual("SampleDsDescription", all_datasources[0].description) + self.assertEqual("SampleDS", all_datasources[0].content_url) + self.assertEqual("2016-08-11T21:22:40Z", format_datetime(all_datasources[0].created_at)) + self.assertEqual("2016-08-11T21:34:17Z", format_datetime(all_datasources[0].updated_at)) + self.assertEqual("default", all_datasources[0].project_name) + self.assertEqual("SampleDS", all_datasources[0].name) + self.assertEqual("ee8c6e70-43b6-11e6-af4f-f7b0d8e20760", all_datasources[0].project_id) + self.assertEqual("5de011f8-5aa9-4d5b-b991-f462c8dd6bb7", all_datasources[0].owner_id) + self.assertEqual("https://web.com", all_datasources[0].webpage_url) self.assertFalse(all_datasources[0].encrypt_extracts) self.assertTrue(all_datasources[0].has_extracts) self.assertFalse(all_datasources[0].use_remote_query_agent) - self.assertEqual('9dbd2263-16b5-46e1-9c43-a76bb8ab65fb', all_datasources[1].id) - self.assertEqual('dataengine', all_datasources[1].datasource_type) - self.assertEqual('description Sample', all_datasources[1].description) - self.assertEqual('Sampledatasource', all_datasources[1].content_url) - self.assertEqual('2016-08-04T21:31:55Z', format_datetime(all_datasources[1].created_at)) - self.assertEqual('2016-08-04T21:31:55Z', format_datetime(all_datasources[1].updated_at)) - self.assertEqual('default', all_datasources[1].project_name) - self.assertEqual('Sample datasource', all_datasources[1].name) - self.assertEqual('ee8c6e70-43b6-11e6-af4f-f7b0d8e20760', all_datasources[1].project_id) - self.assertEqual('5de011f8-5aa9-4d5b-b991-f462c8dd6bb7', all_datasources[1].owner_id) - self.assertEqual(set(['world', 'indicators', 'sample']), all_datasources[1].tags) - self.assertEqual('https://page.com', all_datasources[1].webpage_url) + self.assertEqual("9dbd2263-16b5-46e1-9c43-a76bb8ab65fb", all_datasources[1].id) + self.assertEqual("dataengine", all_datasources[1].datasource_type) + self.assertEqual("description Sample", all_datasources[1].description) + self.assertEqual("Sampledatasource", all_datasources[1].content_url) + self.assertEqual("2016-08-04T21:31:55Z", format_datetime(all_datasources[1].created_at)) + self.assertEqual("2016-08-04T21:31:55Z", format_datetime(all_datasources[1].updated_at)) + self.assertEqual("default", all_datasources[1].project_name) + self.assertEqual("Sample datasource", all_datasources[1].name) + self.assertEqual("ee8c6e70-43b6-11e6-af4f-f7b0d8e20760", all_datasources[1].project_id) + self.assertEqual("5de011f8-5aa9-4d5b-b991-f462c8dd6bb7", all_datasources[1].owner_id) + self.assertEqual(set(["world", "indicators", "sample"]), all_datasources[1].tags) + self.assertEqual("https://page.com", all_datasources[1].webpage_url) self.assertTrue(all_datasources[1].encrypt_extracts) self.assertFalse(all_datasources[1].has_extracts) self.assertTrue(all_datasources[1].use_remote_query_agent) @@ -93,30 +92,30 @@ def test_get_empty(self) -> None: def test_get_by_id(self) -> None: response_xml = read_xml_asset(GET_BY_ID_XML) with requests_mock.mock() as m: - m.get(self.baseurl + '/9dbd2263-16b5-46e1-9c43-a76bb8ab65fb', text=response_xml) - single_datasource = self.server.datasources.get_by_id('9dbd2263-16b5-46e1-9c43-a76bb8ab65fb') - - self.assertEqual('9dbd2263-16b5-46e1-9c43-a76bb8ab65fb', single_datasource.id) - self.assertEqual('dataengine', single_datasource.datasource_type) - self.assertEqual('abc description xyz', single_datasource.description) - self.assertEqual('Sampledatasource', single_datasource.content_url) - self.assertEqual('2016-08-04T21:31:55Z', format_datetime(single_datasource.created_at)) - self.assertEqual('2016-08-04T21:31:55Z', format_datetime(single_datasource.updated_at)) - self.assertEqual('default', single_datasource.project_name) - self.assertEqual('Sample datasource', single_datasource.name) - self.assertEqual('ee8c6e70-43b6-11e6-af4f-f7b0d8e20760', single_datasource.project_id) - self.assertEqual('5de011f8-5aa9-4d5b-b991-f462c8dd6bb7', single_datasource.owner_id) - self.assertEqual(set(['world', 'indicators', 'sample']), single_datasource.tags) + m.get(self.baseurl + "/9dbd2263-16b5-46e1-9c43-a76bb8ab65fb", text=response_xml) + single_datasource = self.server.datasources.get_by_id("9dbd2263-16b5-46e1-9c43-a76bb8ab65fb") + + self.assertEqual("9dbd2263-16b5-46e1-9c43-a76bb8ab65fb", single_datasource.id) + self.assertEqual("dataengine", single_datasource.datasource_type) + self.assertEqual("abc description xyz", single_datasource.description) + self.assertEqual("Sampledatasource", single_datasource.content_url) + self.assertEqual("2016-08-04T21:31:55Z", format_datetime(single_datasource.created_at)) + self.assertEqual("2016-08-04T21:31:55Z", format_datetime(single_datasource.updated_at)) + self.assertEqual("default", single_datasource.project_name) + self.assertEqual("Sample datasource", single_datasource.name) + self.assertEqual("ee8c6e70-43b6-11e6-af4f-f7b0d8e20760", single_datasource.project_id) + self.assertEqual("5de011f8-5aa9-4d5b-b991-f462c8dd6bb7", single_datasource.owner_id) + self.assertEqual(set(["world", "indicators", "sample"]), single_datasource.tags) self.assertEqual(TSC.DatasourceItem.AskDataEnablement.SiteDefault, single_datasource.ask_data_enablement) def test_update(self) -> None: response_xml = read_xml_asset(UPDATE_XML) with requests_mock.mock() as m: - m.put(self.baseurl + '/9dbd2263-16b5-46e1-9c43-a76bb8ab65fb', text=response_xml) - single_datasource = TSC.DatasourceItem('1d0304cd-3796-429f-b815-7258370b9b74', 'Sample datasource') - single_datasource.owner_id = 'dd2239f6-ddf1-4107-981a-4cf94e415794' - single_datasource._content_url = 'Sampledatasource' - single_datasource._id = '9dbd2263-16b5-46e1-9c43-a76bb8ab65fb' + m.put(self.baseurl + "/9dbd2263-16b5-46e1-9c43-a76bb8ab65fb", text=response_xml) + single_datasource = TSC.DatasourceItem("1d0304cd-3796-429f-b815-7258370b9b74", "Sample datasource") + single_datasource.owner_id = "dd2239f6-ddf1-4107-981a-4cf94e415794" + single_datasource._content_url = "Sampledatasource" + single_datasource._id = "9dbd2263-16b5-46e1-9c43-a76bb8ab65fb" single_datasource.certified = True single_datasource.certification_note = "Warning, here be dragons." updated_datasource = self.server.datasources.update(single_datasource) @@ -130,13 +129,13 @@ def test_update(self) -> None: self.assertEqual(updated_datasource.certification_note, single_datasource.certification_note) def test_update_copy_fields(self) -> None: - with open(asset(UPDATE_XML), 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(asset(UPDATE_XML), "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: - m.put(self.baseurl + '/9dbd2263-16b5-46e1-9c43-a76bb8ab65fb', text=response_xml) - single_datasource = TSC.DatasourceItem('1d0304cd-3796-429f-b815-7258370b9b74', 'test') - single_datasource._id = '9dbd2263-16b5-46e1-9c43-a76bb8ab65fb' - single_datasource._project_name = 'Tester' + m.put(self.baseurl + "/9dbd2263-16b5-46e1-9c43-a76bb8ab65fb", text=response_xml) + single_datasource = TSC.DatasourceItem("1d0304cd-3796-429f-b815-7258370b9b74", "test") + single_datasource._id = "9dbd2263-16b5-46e1-9c43-a76bb8ab65fb" + single_datasource._project_name = "Tester" updated_datasource = self.server.datasources.update(single_datasource) self.assertEqual(single_datasource.tags, updated_datasource.tags) @@ -145,14 +144,14 @@ def test_update_copy_fields(self) -> None: def test_update_tags(self) -> None: add_tags_xml, update_xml = read_xml_assets(ADD_TAGS_XML, UPDATE_XML) with requests_mock.mock() as m: - m.put(self.baseurl + '/9dbd2263-16b5-46e1-9c43-a76bb8ab65fb/tags', text=add_tags_xml) - m.delete(self.baseurl + '/9dbd2263-16b5-46e1-9c43-a76bb8ab65fb/tags/b', status_code=204) - m.delete(self.baseurl + '/9dbd2263-16b5-46e1-9c43-a76bb8ab65fb/tags/d', status_code=204) - m.put(self.baseurl + '/9dbd2263-16b5-46e1-9c43-a76bb8ab65fb', text=update_xml) - single_datasource = TSC.DatasourceItem('1d0304cd-3796-429f-b815-7258370b9b74') - single_datasource._id = '9dbd2263-16b5-46e1-9c43-a76bb8ab65fb' - single_datasource._initial_tags.update(['a', 'b', 'c', 'd']) - single_datasource.tags.update(['a', 'c', 'e']) + m.put(self.baseurl + "/9dbd2263-16b5-46e1-9c43-a76bb8ab65fb/tags", text=add_tags_xml) + m.delete(self.baseurl + "/9dbd2263-16b5-46e1-9c43-a76bb8ab65fb/tags/b", status_code=204) + m.delete(self.baseurl + "/9dbd2263-16b5-46e1-9c43-a76bb8ab65fb/tags/d", status_code=204) + m.put(self.baseurl + "/9dbd2263-16b5-46e1-9c43-a76bb8ab65fb", text=update_xml) + single_datasource = TSC.DatasourceItem("1d0304cd-3796-429f-b815-7258370b9b74") + single_datasource._id = "9dbd2263-16b5-46e1-9c43-a76bb8ab65fb" + single_datasource._initial_tags.update(["a", "b", "c", "d"]) + single_datasource.tags.update(["a", "c", "e"]) updated_datasource = self.server.datasources.update(single_datasource) self.assertEqual(single_datasource.tags, updated_datasource.tags) @@ -161,147 +160,148 @@ def test_update_tags(self) -> None: def test_populate_connections(self) -> None: response_xml = read_xml_asset(POPULATE_CONNECTIONS_XML) with requests_mock.mock() as m: - m.get(self.baseurl + '/9dbd2263-16b5-46e1-9c43-a76bb8ab65fb/connections', text=response_xml) - single_datasource = TSC.DatasourceItem('1d0304cd-3796-429f-b815-7258370b9b74', 'test') - single_datasource.owner_id = 'dd2239f6-ddf1-4107-981a-4cf94e415794' - single_datasource._id = '9dbd2263-16b5-46e1-9c43-a76bb8ab65fb' + m.get(self.baseurl + "/9dbd2263-16b5-46e1-9c43-a76bb8ab65fb/connections", text=response_xml) + single_datasource = TSC.DatasourceItem("1d0304cd-3796-429f-b815-7258370b9b74", "test") + single_datasource.owner_id = "dd2239f6-ddf1-4107-981a-4cf94e415794" + single_datasource._id = "9dbd2263-16b5-46e1-9c43-a76bb8ab65fb" self.server.datasources.populate_connections(single_datasource) - self.assertEqual('9dbd2263-16b5-46e1-9c43-a76bb8ab65fb', single_datasource.id) + self.assertEqual("9dbd2263-16b5-46e1-9c43-a76bb8ab65fb", single_datasource.id) connections = single_datasource.connections self.assertTrue(connections) ds1, ds2 = connections - self.assertEqual('be786ae0-d2bf-4a4b-9b34-e2de8d2d4488', ds1.id) - self.assertEqual('textscan', ds1.connection_type) - self.assertEqual('forty-two.net', ds1.server_address) - self.assertEqual('duo', ds1.username) + self.assertEqual("be786ae0-d2bf-4a4b-9b34-e2de8d2d4488", ds1.id) + self.assertEqual("textscan", ds1.connection_type) + self.assertEqual("forty-two.net", ds1.server_address) + self.assertEqual("duo", ds1.username) self.assertEqual(True, ds1.embed_password) - self.assertEqual('970e24bc-e200-4841-a3e9-66e7d122d77e', ds2.id) - self.assertEqual('sqlserver', ds2.connection_type) - self.assertEqual('database.com', ds2.server_address) - self.assertEqual('heero', ds2.username) + self.assertEqual("970e24bc-e200-4841-a3e9-66e7d122d77e", ds2.id) + self.assertEqual("sqlserver", ds2.connection_type) + self.assertEqual("database.com", ds2.server_address) + self.assertEqual("heero", ds2.username) self.assertEqual(False, ds2.embed_password) def test_update_connection(self) -> None: populate_xml, response_xml = read_xml_assets(POPULATE_CONNECTIONS_XML, UPDATE_CONNECTION_XML) with requests_mock.mock() as m: - m.get(self.baseurl + '/9dbd2263-16b5-46e1-9c43-a76bb8ab65fb/connections', text=populate_xml) - m.put(self.baseurl + - '/9dbd2263-16b5-46e1-9c43-a76bb8ab65fb/connections/be786ae0-d2bf-4a4b-9b34-e2de8d2d4488', - text=response_xml) - single_datasource = TSC.DatasourceItem('1d0304cd-3796-429f-b815-7258370b9b74') - single_datasource.owner_id = 'dd2239f6-ddf1-4107-981a-4cf94e415794' - single_datasource._id = '9dbd2263-16b5-46e1-9c43-a76bb8ab65fb' + m.get(self.baseurl + "/9dbd2263-16b5-46e1-9c43-a76bb8ab65fb/connections", text=populate_xml) + m.put( + self.baseurl + "/9dbd2263-16b5-46e1-9c43-a76bb8ab65fb/connections/be786ae0-d2bf-4a4b-9b34-e2de8d2d4488", + text=response_xml, + ) + single_datasource = TSC.DatasourceItem("1d0304cd-3796-429f-b815-7258370b9b74") + single_datasource.owner_id = "dd2239f6-ddf1-4107-981a-4cf94e415794" + single_datasource._id = "9dbd2263-16b5-46e1-9c43-a76bb8ab65fb" self.server.datasources.populate_connections(single_datasource) connection = single_datasource.connections[0] # type: ignore[index] - connection.server_address = 'bar' - connection.server_port = '9876' - connection.username = 'foo' + connection.server_address = "bar" + connection.server_port = "9876" + connection.username = "foo" new_connection = self.server.datasources.update_connection(single_datasource, connection) self.assertEqual(connection.id, new_connection.id) self.assertEqual(connection.connection_type, new_connection.connection_type) - self.assertEqual('bar', new_connection.server_address) - self.assertEqual('9876', new_connection.server_port) - self.assertEqual('foo', new_connection.username) + self.assertEqual("bar", new_connection.server_address) + self.assertEqual("9876", new_connection.server_port) + self.assertEqual("foo", new_connection.username) def test_populate_permissions(self) -> None: - with open(asset(POPULATE_PERMISSIONS_XML), 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(asset(POPULATE_PERMISSIONS_XML), "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: - m.get(self.baseurl + '/0448d2ed-590d-4fa0-b272-a2a8a24555b5/permissions', text=response_xml) - single_datasource = TSC.DatasourceItem('1d0304cd-3796-429f-b815-7258370b9b74', 'test') - single_datasource._id = '0448d2ed-590d-4fa0-b272-a2a8a24555b5' + m.get(self.baseurl + "/0448d2ed-590d-4fa0-b272-a2a8a24555b5/permissions", text=response_xml) + single_datasource = TSC.DatasourceItem("1d0304cd-3796-429f-b815-7258370b9b74", "test") + single_datasource._id = "0448d2ed-590d-4fa0-b272-a2a8a24555b5" self.server.datasources.populate_permissions(single_datasource) permissions = single_datasource.permissions - self.assertEqual(permissions[0].grantee.tag_name, 'group') # type: ignore[index] - self.assertEqual(permissions[0].grantee.id, '5e5e1978-71fa-11e4-87dd-7382f5c437af') # type: ignore[index] - self.assertDictEqual(permissions[0].capabilities, { # type: ignore[index] - TSC.Permission.Capability.Delete: TSC.Permission.Mode.Deny, - TSC.Permission.Capability.ChangePermissions: TSC.Permission.Mode.Deny, - TSC.Permission.Capability.Connect: TSC.Permission.Mode.Allow, - TSC.Permission.Capability.Read: TSC.Permission.Mode.Allow, - }) - - self.assertEqual(permissions[1].grantee.tag_name, 'user') # type: ignore[index] - self.assertEqual(permissions[1].grantee.id, '7c37ee24-c4b1-42b6-a154-eaeab7ee330a') # type: ignore[index] - self.assertDictEqual(permissions[1].capabilities, { # type: ignore[index] - TSC.Permission.Capability.Write: TSC.Permission.Mode.Allow, - }) + self.assertEqual(permissions[0].grantee.tag_name, "group") # type: ignore[index] + self.assertEqual(permissions[0].grantee.id, "5e5e1978-71fa-11e4-87dd-7382f5c437af") # type: ignore[index] + self.assertDictEqual( + permissions[0].capabilities, # type: ignore[index] + { + TSC.Permission.Capability.Delete: TSC.Permission.Mode.Deny, + TSC.Permission.Capability.ChangePermissions: TSC.Permission.Mode.Deny, + TSC.Permission.Capability.Connect: TSC.Permission.Mode.Allow, + TSC.Permission.Capability.Read: TSC.Permission.Mode.Allow, + }, + ) + + self.assertEqual(permissions[1].grantee.tag_name, "user") # type: ignore[index] + self.assertEqual(permissions[1].grantee.id, "7c37ee24-c4b1-42b6-a154-eaeab7ee330a") # type: ignore[index] + self.assertDictEqual( + permissions[1].capabilities, # type: ignore[index] + { + TSC.Permission.Capability.Write: TSC.Permission.Mode.Allow, + }, + ) def test_publish(self) -> None: response_xml = read_xml_asset(PUBLISH_XML) with requests_mock.mock() as m: m.post(self.baseurl, text=response_xml) - new_datasource = TSC.DatasourceItem('ee8c6e70-43b6-11e6-af4f-f7b0d8e20760', 'SampleDS') + new_datasource = TSC.DatasourceItem("ee8c6e70-43b6-11e6-af4f-f7b0d8e20760", "SampleDS") publish_mode = self.server.PublishMode.CreateNew - new_datasource = self.server.datasources.publish(new_datasource, - asset('SampleDS.tds'), - mode=publish_mode) + new_datasource = self.server.datasources.publish(new_datasource, asset("SampleDS.tds"), mode=publish_mode) - self.assertEqual('e76a1461-3b1d-4588-bf1b-17551a879ad9', new_datasource.id) - self.assertEqual('SampleDS', new_datasource.name) - self.assertEqual('SampleDS', new_datasource.content_url) - self.assertEqual('dataengine', new_datasource.datasource_type) - self.assertEqual('2016-08-11T21:22:40Z', format_datetime(new_datasource.created_at)) - self.assertEqual('2016-08-17T23:37:08Z', format_datetime(new_datasource.updated_at)) - self.assertEqual('ee8c6e70-43b6-11e6-af4f-f7b0d8e20760', new_datasource.project_id) - self.assertEqual('default', new_datasource.project_name) - self.assertEqual('5de011f8-5aa9-4d5b-b991-f462c8dd6bb7', new_datasource.owner_id) + self.assertEqual("e76a1461-3b1d-4588-bf1b-17551a879ad9", new_datasource.id) + self.assertEqual("SampleDS", new_datasource.name) + self.assertEqual("SampleDS", new_datasource.content_url) + self.assertEqual("dataengine", new_datasource.datasource_type) + self.assertEqual("2016-08-11T21:22:40Z", format_datetime(new_datasource.created_at)) + self.assertEqual("2016-08-17T23:37:08Z", format_datetime(new_datasource.updated_at)) + self.assertEqual("ee8c6e70-43b6-11e6-af4f-f7b0d8e20760", new_datasource.project_id) + self.assertEqual("default", new_datasource.project_name) + self.assertEqual("5de011f8-5aa9-4d5b-b991-f462c8dd6bb7", new_datasource.owner_id) def test_publish_a_non_packaged_file_object(self) -> None: response_xml = read_xml_asset(PUBLISH_XML) with requests_mock.mock() as m: m.post(self.baseurl, text=response_xml) - new_datasource = TSC.DatasourceItem('ee8c6e70-43b6-11e6-af4f-f7b0d8e20760', 'SampleDS') + new_datasource = TSC.DatasourceItem("ee8c6e70-43b6-11e6-af4f-f7b0d8e20760", "SampleDS") publish_mode = self.server.PublishMode.CreateNew - with open(asset('SampleDS.tds'), 'rb') as file_object: - new_datasource = self.server.datasources.publish(new_datasource, - file_object, - mode=publish_mode) - - self.assertEqual('e76a1461-3b1d-4588-bf1b-17551a879ad9', new_datasource.id) - self.assertEqual('SampleDS', new_datasource.name) - self.assertEqual('SampleDS', new_datasource.content_url) - self.assertEqual('dataengine', new_datasource.datasource_type) - self.assertEqual('2016-08-11T21:22:40Z', format_datetime(new_datasource.created_at)) - self.assertEqual('2016-08-17T23:37:08Z', format_datetime(new_datasource.updated_at)) - self.assertEqual('ee8c6e70-43b6-11e6-af4f-f7b0d8e20760', new_datasource.project_id) - self.assertEqual('default', new_datasource.project_name) - self.assertEqual('5de011f8-5aa9-4d5b-b991-f462c8dd6bb7', new_datasource.owner_id) + with open(asset("SampleDS.tds"), "rb") as file_object: + new_datasource = self.server.datasources.publish(new_datasource, file_object, mode=publish_mode) + + self.assertEqual("e76a1461-3b1d-4588-bf1b-17551a879ad9", new_datasource.id) + self.assertEqual("SampleDS", new_datasource.name) + self.assertEqual("SampleDS", new_datasource.content_url) + self.assertEqual("dataengine", new_datasource.datasource_type) + self.assertEqual("2016-08-11T21:22:40Z", format_datetime(new_datasource.created_at)) + self.assertEqual("2016-08-17T23:37:08Z", format_datetime(new_datasource.updated_at)) + self.assertEqual("ee8c6e70-43b6-11e6-af4f-f7b0d8e20760", new_datasource.project_id) + self.assertEqual("default", new_datasource.project_name) + self.assertEqual("5de011f8-5aa9-4d5b-b991-f462c8dd6bb7", new_datasource.owner_id) def test_publish_a_packaged_file_object(self) -> None: response_xml = read_xml_asset(PUBLISH_XML) with requests_mock.mock() as m: m.post(self.baseurl, text=response_xml) - new_datasource = TSC.DatasourceItem('ee8c6e70-43b6-11e6-af4f-f7b0d8e20760', 'SampleDS') + new_datasource = TSC.DatasourceItem("ee8c6e70-43b6-11e6-af4f-f7b0d8e20760", "SampleDS") publish_mode = self.server.PublishMode.CreateNew # Create a dummy tdsx file in memory with BytesIO() as zip_archive: - with ZipFile(zip_archive, 'w') as zf: - zf.write(asset('SampleDS.tds')) + with ZipFile(zip_archive, "w") as zf: + zf.write(asset("SampleDS.tds")) zip_archive.seek(0) - new_datasource = self.server.datasources.publish(new_datasource, - zip_archive, - mode=publish_mode) + new_datasource = self.server.datasources.publish(new_datasource, zip_archive, mode=publish_mode) - self.assertEqual('e76a1461-3b1d-4588-bf1b-17551a879ad9', new_datasource.id) - self.assertEqual('SampleDS', new_datasource.name) - self.assertEqual('SampleDS', new_datasource.content_url) - self.assertEqual('dataengine', new_datasource.datasource_type) - self.assertEqual('2016-08-11T21:22:40Z', format_datetime(new_datasource.created_at)) - self.assertEqual('2016-08-17T23:37:08Z', format_datetime(new_datasource.updated_at)) - self.assertEqual('ee8c6e70-43b6-11e6-af4f-f7b0d8e20760', new_datasource.project_id) - self.assertEqual('default', new_datasource.project_name) - self.assertEqual('5de011f8-5aa9-4d5b-b991-f462c8dd6bb7', new_datasource.owner_id) + self.assertEqual("e76a1461-3b1d-4588-bf1b-17551a879ad9", new_datasource.id) + self.assertEqual("SampleDS", new_datasource.name) + self.assertEqual("SampleDS", new_datasource.content_url) + self.assertEqual("dataengine", new_datasource.datasource_type) + self.assertEqual("2016-08-11T21:22:40Z", format_datetime(new_datasource.created_at)) + self.assertEqual("2016-08-17T23:37:08Z", format_datetime(new_datasource.updated_at)) + self.assertEqual("ee8c6e70-43b6-11e6-af4f-f7b0d8e20760", new_datasource.project_id) + self.assertEqual("default", new_datasource.project_name) + self.assertEqual("5de011f8-5aa9-4d5b-b991-f462c8dd6bb7", new_datasource.owner_id) def test_publish_async(self) -> None: self.server.version = "3.0" @@ -309,75 +309,74 @@ def test_publish_async(self) -> None: response_xml = read_xml_asset(PUBLISH_XML_ASYNC) with requests_mock.mock() as m: m.post(baseurl, text=response_xml) - new_datasource = TSC.DatasourceItem('ee8c6e70-43b6-11e6-af4f-f7b0d8e20760', 'SampleDS') + new_datasource = TSC.DatasourceItem("ee8c6e70-43b6-11e6-af4f-f7b0d8e20760", "SampleDS") publish_mode = self.server.PublishMode.CreateNew - new_job = self.server.datasources.publish(new_datasource, - asset('SampleDS.tds'), - mode=publish_mode, - as_job=True) + new_job = self.server.datasources.publish( + new_datasource, asset("SampleDS.tds"), mode=publish_mode, as_job=True + ) - self.assertEqual('9a373058-af5f-4f83-8662-98b3e0228a73', new_job.id) - self.assertEqual('PublishDatasource', new_job.type) - self.assertEqual('0', new_job.progress) - self.assertEqual('2018-06-30T00:54:54Z', format_datetime(new_job.created_at)) + self.assertEqual("9a373058-af5f-4f83-8662-98b3e0228a73", new_job.id) + self.assertEqual("PublishDatasource", new_job.type) + self.assertEqual("0", new_job.progress) + self.assertEqual("2018-06-30T00:54:54Z", format_datetime(new_job.created_at)) self.assertEqual(1, new_job.finish_code) def test_publish_unnamed_file_object(self) -> None: - new_datasource = TSC.DatasourceItem('test') + new_datasource = TSC.DatasourceItem("test") publish_mode = self.server.PublishMode.CreateNew - with open(asset('SampleDS.tds'), 'rb') as file_object: - self.assertRaises(ValueError, self.server.datasources.publish, - new_datasource, file_object, publish_mode - ) + with open(asset("SampleDS.tds"), "rb") as file_object: + self.assertRaises(ValueError, self.server.datasources.publish, new_datasource, file_object, publish_mode) def test_refresh_id(self) -> None: - self.server.version = '2.8' + self.server.version = "2.8" self.baseurl = self.server.datasources.baseurl response_xml = read_xml_asset(REFRESH_XML) with requests_mock.mock() as m: - m.post(self.baseurl + '/9dbd2263-16b5-46e1-9c43-a76bb8ab65fb/refresh', - status_code=202, text=response_xml) - new_job = self.server.datasources.refresh('9dbd2263-16b5-46e1-9c43-a76bb8ab65fb') + m.post(self.baseurl + "/9dbd2263-16b5-46e1-9c43-a76bb8ab65fb/refresh", status_code=202, text=response_xml) + new_job = self.server.datasources.refresh("9dbd2263-16b5-46e1-9c43-a76bb8ab65fb") - self.assertEqual('7c3d599e-949f-44c3-94a1-f30ba85757e4', new_job.id) - self.assertEqual('RefreshExtract', new_job.type) + self.assertEqual("7c3d599e-949f-44c3-94a1-f30ba85757e4", new_job.id) + self.assertEqual("RefreshExtract", new_job.type) self.assertEqual(None, new_job.progress) - self.assertEqual('2020-03-05T22:05:32Z', format_datetime(new_job.created_at)) + self.assertEqual("2020-03-05T22:05:32Z", format_datetime(new_job.created_at)) self.assertEqual(-1, new_job.finish_code) def test_refresh_object(self) -> None: - self.server.version = '2.8' + self.server.version = "2.8" self.baseurl = self.server.datasources.baseurl - datasource = TSC.DatasourceItem('') - datasource._id = '9dbd2263-16b5-46e1-9c43-a76bb8ab65fb' + datasource = TSC.DatasourceItem("") + datasource._id = "9dbd2263-16b5-46e1-9c43-a76bb8ab65fb" response_xml = read_xml_asset(REFRESH_XML) with requests_mock.mock() as m: - m.post(self.baseurl + '/9dbd2263-16b5-46e1-9c43-a76bb8ab65fb/refresh', - status_code=202, text=response_xml) + m.post(self.baseurl + "/9dbd2263-16b5-46e1-9c43-a76bb8ab65fb/refresh", status_code=202, text=response_xml) new_job = self.server.datasources.refresh(datasource) # We only check the `id`; remaining fields are already tested in `test_refresh_id` - self.assertEqual('7c3d599e-949f-44c3-94a1-f30ba85757e4', new_job.id) + self.assertEqual("7c3d599e-949f-44c3-94a1-f30ba85757e4", new_job.id) def test_update_hyper_data_datasource_object(self) -> None: """Calling `update_hyper_data` with a `DatasourceItem` should update that datasource""" self.server.version = "3.13" self.baseurl = self.server.datasources.baseurl - datasource = TSC.DatasourceItem('') - datasource._id = '9dbd2263-16b5-46e1-9c43-a76bb8ab65fb' + datasource = TSC.DatasourceItem("") + datasource._id = "9dbd2263-16b5-46e1-9c43-a76bb8ab65fb" response_xml = read_xml_asset(UPDATE_HYPER_DATA_XML) with requests_mock.mock() as m: - m.patch(self.baseurl + '/9dbd2263-16b5-46e1-9c43-a76bb8ab65fb/data', - status_code=202, headers={"requestid": "test_id"}, text=response_xml) + m.patch( + self.baseurl + "/9dbd2263-16b5-46e1-9c43-a76bb8ab65fb/data", + status_code=202, + headers={"requestid": "test_id"}, + text=response_xml, + ) new_job = self.server.datasources.update_hyper_data(datasource, request_id="test_id", actions=[]) - self.assertEqual('5c0ba560-c959-424e-b08a-f32ef0bfb737', new_job.id) - self.assertEqual('UpdateUploadedFile', new_job.type) + self.assertEqual("5c0ba560-c959-424e-b08a-f32ef0bfb737", new_job.id) + self.assertEqual("UpdateUploadedFile", new_job.type) self.assertEqual(None, new_job.progress) - self.assertEqual('2021-09-18T09:40:12Z', format_datetime(new_job.created_at)) + self.assertEqual("2021-09-18T09:40:12Z", format_datetime(new_job.created_at)) self.assertEqual(-1, new_job.finish_code) def test_update_hyper_data_connection_object(self) -> None: @@ -386,71 +385,87 @@ def test_update_hyper_data_connection_object(self) -> None: self.baseurl = self.server.datasources.baseurl connection = TSC.ConnectionItem() - connection._datasource_id = '9dbd2263-16b5-46e1-9c43-a76bb8ab65fb' - connection._id = '7ecaccd8-39b0-4875-a77d-094f6e930019' + connection._datasource_id = "9dbd2263-16b5-46e1-9c43-a76bb8ab65fb" + connection._id = "7ecaccd8-39b0-4875-a77d-094f6e930019" response_xml = read_xml_asset(UPDATE_HYPER_DATA_XML) with requests_mock.mock() as m: - m.patch(self.baseurl + '/9dbd2263-16b5-46e1-9c43-a76bb8ab65fb/connections/7ecaccd8-39b0-4875-a77d-094f6e930019/data', - status_code=202, headers={"requestid": "test_id"}, text=response_xml) + m.patch( + self.baseurl + + "/9dbd2263-16b5-46e1-9c43-a76bb8ab65fb/connections/7ecaccd8-39b0-4875-a77d-094f6e930019/data", + status_code=202, + headers={"requestid": "test_id"}, + text=response_xml, + ) new_job = self.server.datasources.update_hyper_data(connection, request_id="test_id", actions=[]) # We only check the `id`; remaining fields are already tested in `test_update_hyper_data_datasource_object` - self.assertEqual('5c0ba560-c959-424e-b08a-f32ef0bfb737', new_job.id) + self.assertEqual("5c0ba560-c959-424e-b08a-f32ef0bfb737", new_job.id) def test_update_hyper_data_datasource_string(self) -> None: """For convenience, calling `update_hyper_data` with a `str` should update the datasource with the corresponding UUID""" self.server.version = "3.13" self.baseurl = self.server.datasources.baseurl - datasource_id = '9dbd2263-16b5-46e1-9c43-a76bb8ab65fb' + datasource_id = "9dbd2263-16b5-46e1-9c43-a76bb8ab65fb" response_xml = read_xml_asset(UPDATE_HYPER_DATA_XML) with requests_mock.mock() as m: - m.patch(self.baseurl + '/9dbd2263-16b5-46e1-9c43-a76bb8ab65fb/data', - status_code=202, headers={"requestid": "test_id"}, text=response_xml) + m.patch( + self.baseurl + "/9dbd2263-16b5-46e1-9c43-a76bb8ab65fb/data", + status_code=202, + headers={"requestid": "test_id"}, + text=response_xml, + ) new_job = self.server.datasources.update_hyper_data(datasource_id, request_id="test_id", actions=[]) # We only check the `id`; remaining fields are already tested in `test_update_hyper_data_datasource_object` - self.assertEqual('5c0ba560-c959-424e-b08a-f32ef0bfb737', new_job.id) + self.assertEqual("5c0ba560-c959-424e-b08a-f32ef0bfb737", new_job.id) def test_update_hyper_data_datasource_payload_file(self) -> None: """If `payload` is present, we upload it and associate the job with it""" self.server.version = "3.13" self.baseurl = self.server.datasources.baseurl - datasource_id = '9dbd2263-16b5-46e1-9c43-a76bb8ab65fb' - mock_upload_id = '10051:c3e56879876842d4b3600f20c1f79876-0:0' + datasource_id = "9dbd2263-16b5-46e1-9c43-a76bb8ab65fb" + mock_upload_id = "10051:c3e56879876842d4b3600f20c1f79876-0:0" response_xml = read_xml_asset(UPDATE_HYPER_DATA_XML) - with requests_mock.mock() as rm, \ - unittest.mock.patch.object(Fileuploads, "upload", return_value=mock_upload_id): - rm.patch(self.baseurl + '/9dbd2263-16b5-46e1-9c43-a76bb8ab65fb/data?uploadSessionId=' + mock_upload_id, - status_code=202, headers={"requestid": "test_id"}, text=response_xml) - new_job = self.server.datasources.update_hyper_data(datasource_id, request_id="test_id", - actions=[], payload=asset('World Indicators.hyper')) + with requests_mock.mock() as rm, unittest.mock.patch.object(Fileuploads, "upload", return_value=mock_upload_id): + rm.patch( + self.baseurl + "/9dbd2263-16b5-46e1-9c43-a76bb8ab65fb/data?uploadSessionId=" + mock_upload_id, + status_code=202, + headers={"requestid": "test_id"}, + text=response_xml, + ) + new_job = self.server.datasources.update_hyper_data( + datasource_id, request_id="test_id", actions=[], payload=asset("World Indicators.hyper") + ) # We only check the `id`; remaining fields are already tested in `test_update_hyper_data_datasource_object` - self.assertEqual('5c0ba560-c959-424e-b08a-f32ef0bfb737', new_job.id) + self.assertEqual("5c0ba560-c959-424e-b08a-f32ef0bfb737", new_job.id) def test_update_hyper_data_datasource_invalid_payload_file(self) -> None: """If `payload` points to a non-existing file, we report an error""" self.server.version = "3.13" self.baseurl = self.server.datasources.baseurl - datasource_id = '9dbd2263-16b5-46e1-9c43-a76bb8ab65fb' + datasource_id = "9dbd2263-16b5-46e1-9c43-a76bb8ab65fb" with self.assertRaises(IOError) as cm: - self.server.datasources.update_hyper_data(datasource_id, request_id="test_id", - actions=[], payload='no/such/file.missing') + self.server.datasources.update_hyper_data( + datasource_id, request_id="test_id", actions=[], payload="no/such/file.missing" + ) exception = cm.exception self.assertEqual(str(exception), "File path does not lead to an existing file.") def test_delete(self) -> None: with requests_mock.mock() as m: - m.delete(self.baseurl + '/9dbd2263-16b5-46e1-9c43-a76bb8ab65fb', status_code=204) - self.server.datasources.delete('9dbd2263-16b5-46e1-9c43-a76bb8ab65fb') + m.delete(self.baseurl + "/9dbd2263-16b5-46e1-9c43-a76bb8ab65fb", status_code=204) + self.server.datasources.delete("9dbd2263-16b5-46e1-9c43-a76bb8ab65fb") def test_download(self) -> None: with requests_mock.mock() as m: - m.get(self.baseurl + '/9dbd2263-16b5-46e1-9c43-a76bb8ab65fb/content', - headers={'Content-Disposition': 'name="tableau_datasource"; filename="Sample datasource.tds"'}) - file_path = self.server.datasources.download('9dbd2263-16b5-46e1-9c43-a76bb8ab65fb') + m.get( + self.baseurl + "/9dbd2263-16b5-46e1-9c43-a76bb8ab65fb/content", + headers={"Content-Disposition": 'name="tableau_datasource"; filename="Sample datasource.tds"'}, + ) + file_path = self.server.datasources.download("9dbd2263-16b5-46e1-9c43-a76bb8ab65fb") self.assertTrue(os.path.exists(file_path)) os.remove(file_path) @@ -458,9 +473,11 @@ def test_download_sanitizes_name(self) -> None: filename = "Name,With,Commas.tds" disposition = 'name="tableau_workbook"; filename="{}"'.format(filename) with requests_mock.mock() as m: - m.get(self.baseurl + '/1f951daf-4061-451a-9df1-69a8062664f2/content', - headers={'Content-Disposition': disposition}) - file_path = self.server.datasources.download('1f951daf-4061-451a-9df1-69a8062664f2') + m.get( + self.baseurl + "/1f951daf-4061-451a-9df1-69a8062664f2/content", + headers={"Content-Disposition": disposition}, + ) + file_path = self.server.datasources.download("1f951daf-4061-451a-9df1-69a8062664f2") self.assertEqual(os.path.basename(file_path), "NameWithCommas.tds") self.assertTrue(os.path.exists(file_path)) os.remove(file_path) @@ -471,117 +488,132 @@ def test_download_extract_only(self) -> None: self.baseurl = self.server.datasources.baseurl with requests_mock.mock() as m: - m.get(self.baseurl + '/9dbd2263-16b5-46e1-9c43-a76bb8ab65fb/content?includeExtract=False', - headers={'Content-Disposition': 'name="tableau_datasource"; filename="Sample datasource.tds"'}, - complete_qs=True) - file_path = self.server.datasources.download('9dbd2263-16b5-46e1-9c43-a76bb8ab65fb', include_extract=False) + m.get( + self.baseurl + "/9dbd2263-16b5-46e1-9c43-a76bb8ab65fb/content?includeExtract=False", + headers={"Content-Disposition": 'name="tableau_datasource"; filename="Sample datasource.tds"'}, + complete_qs=True, + ) + file_path = self.server.datasources.download("9dbd2263-16b5-46e1-9c43-a76bb8ab65fb", include_extract=False) self.assertTrue(os.path.exists(file_path)) os.remove(file_path) def test_update_missing_id(self) -> None: - single_datasource = TSC.DatasourceItem('ee8c6e70-43b6-11e6-af4f-f7b0d8e20760', 'test') + single_datasource = TSC.DatasourceItem("ee8c6e70-43b6-11e6-af4f-f7b0d8e20760", "test") self.assertRaises(TSC.MissingRequiredFieldError, self.server.datasources.update, single_datasource) def test_publish_missing_path(self) -> None: - new_datasource = TSC.DatasourceItem('ee8c6e70-43b6-11e6-af4f-f7b0d8e20760', 'test') - self.assertRaises(IOError, self.server.datasources.publish, new_datasource, - '', self.server.PublishMode.CreateNew) + new_datasource = TSC.DatasourceItem("ee8c6e70-43b6-11e6-af4f-f7b0d8e20760", "test") + self.assertRaises( + IOError, self.server.datasources.publish, new_datasource, "", self.server.PublishMode.CreateNew + ) def test_publish_missing_mode(self) -> None: - new_datasource = TSC.DatasourceItem('ee8c6e70-43b6-11e6-af4f-f7b0d8e20760', 'test') - self.assertRaises(ValueError, self.server.datasources.publish, new_datasource, - asset('SampleDS.tds'), None) + new_datasource = TSC.DatasourceItem("ee8c6e70-43b6-11e6-af4f-f7b0d8e20760", "test") + self.assertRaises(ValueError, self.server.datasources.publish, new_datasource, asset("SampleDS.tds"), None) def test_publish_invalid_file_type(self) -> None: - new_datasource = TSC.DatasourceItem('ee8c6e70-43b6-11e6-af4f-f7b0d8e20760', 'test') - self.assertRaises(ValueError, self.server.datasources.publish, new_datasource, - asset('SampleWB.twbx'), self.server.PublishMode.Append) + new_datasource = TSC.DatasourceItem("ee8c6e70-43b6-11e6-af4f-f7b0d8e20760", "test") + self.assertRaises( + ValueError, + self.server.datasources.publish, + new_datasource, + asset("SampleWB.twbx"), + self.server.PublishMode.Append, + ) def test_publish_hyper_file_object_raises_exception(self) -> None: - new_datasource = TSC.DatasourceItem('ee8c6e70-43b6-11e6-af4f-f7b0d8e20760', 'test') - with open(asset('World Indicators.hyper'), 'rb') as file_object: - self.assertRaises(ValueError, self.server.datasources.publish, new_datasource, - file_object, self.server.PublishMode.Append) + new_datasource = TSC.DatasourceItem("ee8c6e70-43b6-11e6-af4f-f7b0d8e20760", "test") + with open(asset("World Indicators.hyper"), "rb") as file_object: + self.assertRaises( + ValueError, self.server.datasources.publish, new_datasource, file_object, self.server.PublishMode.Append + ) def test_publish_tde_file_object_raises_exception(self) -> None: - new_datasource = TSC.DatasourceItem('ee8c6e70-43b6-11e6-af4f-f7b0d8e20760', 'test') - tds_asset = asset(os.path.join('Data', 'Tableau Samples', 'World Indicators.tde')) - with open(tds_asset, 'rb') as file_object: - self.assertRaises(ValueError, self.server.datasources.publish, new_datasource, - file_object, self.server.PublishMode.Append) + new_datasource = TSC.DatasourceItem("ee8c6e70-43b6-11e6-af4f-f7b0d8e20760", "test") + tds_asset = asset(os.path.join("Data", "Tableau Samples", "World Indicators.tde")) + with open(tds_asset, "rb") as file_object: + self.assertRaises( + ValueError, self.server.datasources.publish, new_datasource, file_object, self.server.PublishMode.Append + ) def test_publish_file_object_of_unknown_type_raises_exception(self) -> None: - new_datasource = TSC.DatasourceItem('ee8c6e70-43b6-11e6-af4f-f7b0d8e20760', 'test') + new_datasource = TSC.DatasourceItem("ee8c6e70-43b6-11e6-af4f-f7b0d8e20760", "test") with BytesIO() as file_object: - file_object.write(bytes.fromhex('89504E470D0A1A0A')) + file_object.write(bytes.fromhex("89504E470D0A1A0A")) file_object.seek(0) - self.assertRaises(ValueError, self.server.datasources.publish, new_datasource, - file_object, self.server.PublishMode.Append) + self.assertRaises( + ValueError, self.server.datasources.publish, new_datasource, file_object, self.server.PublishMode.Append + ) def test_publish_multi_connection(self) -> None: - new_datasource = TSC.DatasourceItem(name='Sample', project_id='ee8c6e70-43b6-11e6-af4f-f7b0d8e20760') + new_datasource = TSC.DatasourceItem(name="Sample", project_id="ee8c6e70-43b6-11e6-af4f-f7b0d8e20760") connection1 = TSC.ConnectionItem() - connection1.server_address = 'mysql.test.com' - connection1.connection_credentials = TSC.ConnectionCredentials('test', 'secret', True) + connection1.server_address = "mysql.test.com" + connection1.connection_credentials = TSC.ConnectionCredentials("test", "secret", True) connection2 = TSC.ConnectionItem() - connection2.server_address = 'pgsql.test.com' - connection2.connection_credentials = TSC.ConnectionCredentials('test', 'secret', True) + connection2.server_address = "pgsql.test.com" + connection2.connection_credentials = TSC.ConnectionCredentials("test", "secret", True) response = RequestFactory.Datasource._generate_xml(new_datasource, connections=[connection1, connection2]) # Can't use ConnectionItem parser due to xml namespace problems - connection_results = ET.fromstring(response).findall('.//connection') + connection_results = ET.fromstring(response).findall(".//connection") - self.assertEqual(connection_results[0].get('serverAddress', None), 'mysql.test.com') - self.assertEqual(connection_results[0].find('connectionCredentials').get('name', None), 'test') # type: ignore[union-attr] - self.assertEqual(connection_results[1].get('serverAddress', None), 'pgsql.test.com') - self.assertEqual(connection_results[1].find('connectionCredentials').get('password', None), 'secret') # type: ignore[union-attr] + self.assertEqual(connection_results[0].get("serverAddress", None), "mysql.test.com") + self.assertEqual(connection_results[0].find("connectionCredentials").get("name", None), "test") # type: ignore[union-attr] + self.assertEqual(connection_results[1].get("serverAddress", None), "pgsql.test.com") + self.assertEqual(connection_results[1].find("connectionCredentials").get("password", None), "secret") # type: ignore[union-attr] def test_publish_single_connection(self) -> None: - new_datasource = TSC.DatasourceItem(name='Sample', project_id='ee8c6e70-43b6-11e6-af4f-f7b0d8e20760') - connection_creds = TSC.ConnectionCredentials('test', 'secret', True) + new_datasource = TSC.DatasourceItem(name="Sample", project_id="ee8c6e70-43b6-11e6-af4f-f7b0d8e20760") + connection_creds = TSC.ConnectionCredentials("test", "secret", True) response = RequestFactory.Datasource._generate_xml(new_datasource, connection_credentials=connection_creds) # Can't use ConnectionItem parser due to xml namespace problems - credentials = ET.fromstring(response).findall('.//connectionCredentials') + credentials = ET.fromstring(response).findall(".//connectionCredentials") self.assertEqual(len(credentials), 1) - self.assertEqual(credentials[0].get('name', None), 'test') - self.assertEqual(credentials[0].get('password', None), 'secret') - self.assertEqual(credentials[0].get('embed', None), 'true') + self.assertEqual(credentials[0].get("name", None), "test") + self.assertEqual(credentials[0].get("password", None), "secret") + self.assertEqual(credentials[0].get("embed", None), "true") def test_credentials_and_multi_connect_raises_exception(self) -> None: - new_datasource = TSC.DatasourceItem(name='Sample', project_id='ee8c6e70-43b6-11e6-af4f-f7b0d8e20760') + new_datasource = TSC.DatasourceItem(name="Sample", project_id="ee8c6e70-43b6-11e6-af4f-f7b0d8e20760") - connection_creds = TSC.ConnectionCredentials('test', 'secret', True) + connection_creds = TSC.ConnectionCredentials("test", "secret", True) connection1 = TSC.ConnectionItem() - connection1.server_address = 'mysql.test.com' - connection1.connection_credentials = TSC.ConnectionCredentials('test', 'secret', True) + connection1.server_address = "mysql.test.com" + connection1.connection_credentials = TSC.ConnectionCredentials("test", "secret", True) with self.assertRaises(RuntimeError): - response = RequestFactory.Datasource._generate_xml(new_datasource, - connection_credentials=connection_creds, - connections=[connection1]) + response = RequestFactory.Datasource._generate_xml( + new_datasource, connection_credentials=connection_creds, connections=[connection1] + ) def test_synchronous_publish_timeout_error(self) -> None: with requests_mock.mock() as m: - m.register_uri('POST', self.baseurl, status_code=504) + m.register_uri("POST", self.baseurl, status_code=504) - new_datasource = TSC.DatasourceItem(project_id='') + new_datasource = TSC.DatasourceItem(project_id="") publish_mode = self.server.PublishMode.CreateNew - self.assertRaisesRegex(InternalServerError, 'Please use asynchronous publishing to avoid timeouts.', - self.server.datasources.publish, new_datasource, - asset('SampleDS.tds'), publish_mode) + self.assertRaisesRegex( + InternalServerError, + "Please use asynchronous publishing to avoid timeouts.", + self.server.datasources.publish, + new_datasource, + asset("SampleDS.tds"), + publish_mode, + ) def test_delete_extracts(self) -> None: self.server.version = "3.10" self.baseurl = self.server.datasources.baseurl with requests_mock.mock() as m: - m.post(self.baseurl + '/3cc6cd06-89ce-4fdc-b935-5294135d6d42/deleteExtract', status_code=200) - self.server.datasources.delete_extract('3cc6cd06-89ce-4fdc-b935-5294135d6d42') + m.post(self.baseurl + "/3cc6cd06-89ce-4fdc-b935-5294135d6d42/deleteExtract", status_code=200) + self.server.datasources.delete_extract("3cc6cd06-89ce-4fdc-b935-5294135d6d42") def test_create_extracts(self) -> None: self.server.version = "3.10" @@ -589,9 +621,10 @@ def test_create_extracts(self) -> None: response_xml = read_xml_asset(PUBLISH_XML_ASYNC) with requests_mock.mock() as m: - m.post(self.baseurl + '/3cc6cd06-89ce-4fdc-b935-5294135d6d42/createExtract', - status_code=200, text=response_xml) - self.server.datasources.create_extract('3cc6cd06-89ce-4fdc-b935-5294135d6d42') + m.post( + self.baseurl + "/3cc6cd06-89ce-4fdc-b935-5294135d6d42/createExtract", status_code=200, text=response_xml + ) + self.server.datasources.create_extract("3cc6cd06-89ce-4fdc-b935-5294135d6d42") def test_create_extracts_encrypted(self) -> None: self.server.version = "3.10" @@ -599,13 +632,14 @@ def test_create_extracts_encrypted(self) -> None: response_xml = read_xml_asset(PUBLISH_XML_ASYNC) with requests_mock.mock() as m: - m.post(self.baseurl + '/3cc6cd06-89ce-4fdc-b935-5294135d6d42/createExtract', - status_code=200, text=response_xml) - self.server.datasources.create_extract('3cc6cd06-89ce-4fdc-b935-5294135d6d42', True) + m.post( + self.baseurl + "/3cc6cd06-89ce-4fdc-b935-5294135d6d42/createExtract", status_code=200, text=response_xml + ) + self.server.datasources.create_extract("3cc6cd06-89ce-4fdc-b935-5294135d6d42", True) def test_revisions(self) -> None: - datasource = TSC.DatasourceItem('project', 'test') - datasource._id = '06b944d2-959d-4604-9305-12323c95e70e' + datasource = TSC.DatasourceItem("project", "test") + datasource._id = "06b944d2-959d-4604-9305-12323c95e70e" response_xml = read_xml_asset(REVISION_XML) with requests_mock.mock() as m: @@ -633,8 +667,8 @@ def test_revisions(self) -> None: self.assertEqual("5de011f8-5aa9-4d5b-b991-f462c8dd6bb7", revisions[2].user_id) def test_delete_revision(self) -> None: - datasource = TSC.DatasourceItem('project', 'test') - datasource._id = '06b944d2-959d-4604-9305-12323c95e70e' + datasource = TSC.DatasourceItem("project", "test") + datasource._id = "06b944d2-959d-4604-9305-12323c95e70e" with requests_mock.mock() as m: m.delete("{0}/{1}/revisions/3".format(self.baseurl, datasource.id)) @@ -642,7 +676,9 @@ def test_delete_revision(self) -> None: def test_download_revision(self) -> None: with requests_mock.mock() as m, tempfile.TemporaryDirectory() as td: - m.get(self.baseurl + '/9dbd2263-16b5-46e1-9c43-a76bb8ab65fb/revisions/3/content', - headers={'Content-Disposition': 'name="tableau_datasource"; filename="Sample datasource.tds"'}) - file_path = self.server.datasources.download_revision('9dbd2263-16b5-46e1-9c43-a76bb8ab65fb', "3", td) + m.get( + self.baseurl + "/9dbd2263-16b5-46e1-9c43-a76bb8ab65fb/revisions/3/content", + headers={"Content-Disposition": 'name="tableau_datasource"; filename="Sample datasource.tds"'}, + ) + file_path = self.server.datasources.download_revision("9dbd2263-16b5-46e1-9c43-a76bb8ab65fb", "3", td) self.assertTrue(os.path.exists(file_path)) diff --git a/test/test_exponential_backoff.py b/test/test_exponential_backoff.py index 57229d4ce..98618843c 100644 --- a/test/test_exponential_backoff.py +++ b/test/test_exponential_backoff.py @@ -21,7 +21,6 @@ def test_exponential(self): exponentialBackoff.sleep() self.assertAlmostEqual(mock_time(), 5.4728) - def test_exponential_saturation(self): with mocked_time() as mock_time: exponentialBackoff = ExponentialBackoffTimer() @@ -36,7 +35,6 @@ def test_exponential_saturation(self): slept = mock_time() - s self.assertAlmostEqual(slept, 30) - def test_timeout(self): with mocked_time() as mock_time: exponentialBackoff = ExponentialBackoffTimer(timeout=4.5) @@ -52,11 +50,10 @@ def test_timeout(self): with self.assertRaises(TimeoutError): exponentialBackoff.sleep() - def test_timeout_zero(self): with mocked_time() as mock_time: # The construction of the timer doesn't throw, yet - exponentialBackoff = ExponentialBackoffTimer(timeout = 0) + exponentialBackoff = ExponentialBackoffTimer(timeout=0) # But the first `sleep` immediately throws with self.assertRaises(TimeoutError): exponentialBackoff.sleep() diff --git a/test/test_favorites.py b/test/test_favorites.py index f76517b64..d92fa7392 100644 --- a/test/test_favorites.py +++ b/test/test_favorites.py @@ -8,122 +8,113 @@ from tableauserverclient.server.request_factory import RequestFactory from ._utils import read_xml_asset, read_xml_assets, asset -GET_FAVORITES_XML = 'favorites_get.xml' -ADD_FAVORITE_WORKBOOK_XML = 'favorites_add_workbook.xml' -ADD_FAVORITE_VIEW_XML = 'favorites_add_view.xml' -ADD_FAVORITE_DATASOURCE_XML = 'favorites_add_datasource.xml' -ADD_FAVORITE_PROJECT_XML = 'favorites_add_project.xml' +GET_FAVORITES_XML = "favorites_get.xml" +ADD_FAVORITE_WORKBOOK_XML = "favorites_add_workbook.xml" +ADD_FAVORITE_VIEW_XML = "favorites_add_view.xml" +ADD_FAVORITE_DATASOURCE_XML = "favorites_add_datasource.xml" +ADD_FAVORITE_PROJECT_XML = "favorites_add_project.xml" class FavoritesTests(unittest.TestCase): def setUp(self): - self.server = TSC.Server('http://test') - self.server.version = '2.5' + self.server = TSC.Server("http://test") + self.server.version = "2.5" # Fake signin - self.server._site_id = 'dad65087-b08b-4603-af4e-2887b8aafc67' - self.server._auth_token = 'j80k54ll2lfMZ0tv97mlPvvSCRyD0DOM' + self.server._site_id = "dad65087-b08b-4603-af4e-2887b8aafc67" + self.server._auth_token = "j80k54ll2lfMZ0tv97mlPvvSCRyD0DOM" self.baseurl = self.server.favorites.baseurl - self.user = TSC.UserItem('alice', TSC.UserItem.Roles.Viewer) - self.user._id = 'dd2239f6-ddf1-4107-981a-4cf94e415794' + self.user = TSC.UserItem("alice", TSC.UserItem.Roles.Viewer) + self.user._id = "dd2239f6-ddf1-4107-981a-4cf94e415794" def test_get(self): response_xml = read_xml_asset(GET_FAVORITES_XML) with requests_mock.mock() as m: - m.get('{0}/{1}'.format(self.baseurl, self.user.id), - text=response_xml) + m.get("{0}/{1}".format(self.baseurl, self.user.id), text=response_xml) self.server.favorites.get(self.user) self.assertIsNotNone(self.user._favorites) - self.assertEqual(len(self.user.favorites['workbooks']), 1) - self.assertEqual(len(self.user.favorites['views']), 1) - self.assertEqual(len(self.user.favorites['projects']), 1) - self.assertEqual(len(self.user.favorites['datasources']), 1) + self.assertEqual(len(self.user.favorites["workbooks"]), 1) + self.assertEqual(len(self.user.favorites["views"]), 1) + self.assertEqual(len(self.user.favorites["projects"]), 1) + self.assertEqual(len(self.user.favorites["datasources"]), 1) - workbook = self.user.favorites['workbooks'][0] - view = self.user.favorites['views'][0] - datasource = self.user.favorites['datasources'][0] - project = self.user.favorites['projects'][0] + workbook = self.user.favorites["workbooks"][0] + view = self.user.favorites["views"][0] + datasource = self.user.favorites["datasources"][0] + project = self.user.favorites["projects"][0] - self.assertEqual(workbook.id, '6d13b0ca-043d-4d42-8c9d-3f3313ea3a00') - self.assertEqual(view.id, 'd79634e1-6063-4ec9-95ff-50acbf609ff5') - self.assertEqual(datasource.id, 'e76a1461-3b1d-4588-bf1b-17551a879ad9') - self.assertEqual(project.id, '1d0304cd-3796-429f-b815-7258370b9b74') + self.assertEqual(workbook.id, "6d13b0ca-043d-4d42-8c9d-3f3313ea3a00") + self.assertEqual(view.id, "d79634e1-6063-4ec9-95ff-50acbf609ff5") + self.assertEqual(datasource.id, "e76a1461-3b1d-4588-bf1b-17551a879ad9") + self.assertEqual(project.id, "1d0304cd-3796-429f-b815-7258370b9b74") def test_add_favorite_workbook(self): response_xml = read_xml_asset(ADD_FAVORITE_WORKBOOK_XML) - workbook = TSC.WorkbookItem('') - workbook._id = '6d13b0ca-043d-4d42-8c9d-3f3313ea3a00' - workbook.name = 'Superstore' + workbook = TSC.WorkbookItem("") + workbook._id = "6d13b0ca-043d-4d42-8c9d-3f3313ea3a00" + workbook.name = "Superstore" with requests_mock.mock() as m: - m.put('{0}/{1}'.format(self.baseurl, self.user.id), - text=response_xml) + m.put("{0}/{1}".format(self.baseurl, self.user.id), text=response_xml) self.server.favorites.add_favorite_workbook(self.user, workbook) def test_add_favorite_view(self): response_xml = read_xml_asset(ADD_FAVORITE_VIEW_XML) view = TSC.ViewItem() - view._id = 'd79634e1-6063-4ec9-95ff-50acbf609ff5' - view._name = 'ENDANGERED SAFARI' + view._id = "d79634e1-6063-4ec9-95ff-50acbf609ff5" + view._name = "ENDANGERED SAFARI" with requests_mock.mock() as m: - m.put('{0}/{1}'.format(self.baseurl, self.user.id), - text=response_xml) + m.put("{0}/{1}".format(self.baseurl, self.user.id), text=response_xml) self.server.favorites.add_favorite_view(self.user, view) def test_add_favorite_datasource(self): response_xml = read_xml_asset(ADD_FAVORITE_DATASOURCE_XML) - datasource = TSC.DatasourceItem('ee8c6e70-43b6-11e6-af4f-f7b0d8e20760') - datasource._id = 'e76a1461-3b1d-4588-bf1b-17551a879ad9' - datasource.name = 'SampleDS' + datasource = TSC.DatasourceItem("ee8c6e70-43b6-11e6-af4f-f7b0d8e20760") + datasource._id = "e76a1461-3b1d-4588-bf1b-17551a879ad9" + datasource.name = "SampleDS" with requests_mock.mock() as m: - m.put('{0}/{1}'.format(self.baseurl, self.user.id), - text=response_xml) + m.put("{0}/{1}".format(self.baseurl, self.user.id), text=response_xml) self.server.favorites.add_favorite_datasource(self.user, datasource) def test_add_favorite_project(self): - self.server.version = '3.1' + self.server.version = "3.1" baseurl = self.server.favorites.baseurl response_xml = read_xml_asset(ADD_FAVORITE_PROJECT_XML) - project = TSC.ProjectItem('Tableau') - project._id = '1d0304cd-3796-429f-b815-7258370b9b74' + project = TSC.ProjectItem("Tableau") + project._id = "1d0304cd-3796-429f-b815-7258370b9b74" with requests_mock.mock() as m: - m.put('{0}/{1}'.format(baseurl, self.user.id), - text=response_xml) + m.put("{0}/{1}".format(baseurl, self.user.id), text=response_xml) self.server.favorites.add_favorite_project(self.user, project) def test_delete_favorite_workbook(self): - workbook = TSC.WorkbookItem('') - workbook._id = '6d13b0ca-043d-4d42-8c9d-3f3313ea3a00' - workbook.name = 'Superstore' + workbook = TSC.WorkbookItem("") + workbook._id = "6d13b0ca-043d-4d42-8c9d-3f3313ea3a00" + workbook.name = "Superstore" with requests_mock.mock() as m: - m.delete('{0}/{1}/workbooks/{2}'.format(self.baseurl, self.user.id, - workbook.id)) + m.delete("{0}/{1}/workbooks/{2}".format(self.baseurl, self.user.id, workbook.id)) self.server.favorites.delete_favorite_workbook(self.user, workbook) def test_delete_favorite_view(self): view = TSC.ViewItem() - view._id = 'd79634e1-6063-4ec9-95ff-50acbf609ff5' - view._name = 'ENDANGERED SAFARI' + view._id = "d79634e1-6063-4ec9-95ff-50acbf609ff5" + view._name = "ENDANGERED SAFARI" with requests_mock.mock() as m: - m.delete('{0}/{1}/views/{2}'.format(self.baseurl, self.user.id, - view.id)) + m.delete("{0}/{1}/views/{2}".format(self.baseurl, self.user.id, view.id)) self.server.favorites.delete_favorite_view(self.user, view) def test_delete_favorite_datasource(self): - datasource = TSC.DatasourceItem('ee8c6e70-43b6-11e6-af4f-f7b0d8e20760') - datasource._id = 'e76a1461-3b1d-4588-bf1b-17551a879ad9' - datasource.name = 'SampleDS' + datasource = TSC.DatasourceItem("ee8c6e70-43b6-11e6-af4f-f7b0d8e20760") + datasource._id = "e76a1461-3b1d-4588-bf1b-17551a879ad9" + datasource.name = "SampleDS" with requests_mock.mock() as m: - m.delete('{0}/{1}/datasources/{2}'.format(self.baseurl, self.user.id, - datasource.id)) + m.delete("{0}/{1}/datasources/{2}".format(self.baseurl, self.user.id, datasource.id)) self.server.favorites.delete_favorite_datasource(self.user, datasource) def test_delete_favorite_project(self): - self.server.version = '3.1' + self.server.version = "3.1" baseurl = self.server.favorites.baseurl - project = TSC.ProjectItem('Tableau') - project._id = '1d0304cd-3796-429f-b815-7258370b9b74' + project = TSC.ProjectItem("Tableau") + project._id = "1d0304cd-3796-429f-b815-7258370b9b74" with requests_mock.mock() as m: - m.delete('{0}/{1}/projects/{2}'.format(baseurl, self.user.id, - project.id)) + m.delete("{0}/{1}/projects/{2}".format(baseurl, self.user.id, project.id)) self.server.favorites.delete_favorite_project(self.user, project) diff --git a/test/test_filesys_helpers.py b/test/test_filesys_helpers.py index 82fce8476..e86e68847 100644 --- a/test/test_filesys_helpers.py +++ b/test/test_filesys_helpers.py @@ -9,7 +9,6 @@ class FilesysTests(unittest.TestCase): - def test_get_file_size_returns_correct_size(self): target_size = 1000 # bytes @@ -30,9 +29,9 @@ def test_get_file_size_returns_zero_for_empty_file(self): def test_get_file_size_coincides_with_built_in_method(self): - asset_path = asset('SampleWB.twbx') + asset_path = asset("SampleWB.twbx") target_size = os.path.getsize(asset_path) - with open(asset_path, 'rb') as f: + with open(asset_path, "rb") as f: file_size = get_file_object_size(f) self.assertEqual(file_size, target_size) @@ -40,61 +39,60 @@ def test_get_file_size_coincides_with_built_in_method(self): def test_get_file_type_identifies_a_zip_file(self): with BytesIO() as file_object: - with ZipFile(file_object, 'w') as zf: + with ZipFile(file_object, "w") as zf: with BytesIO() as stream: - stream.write('This is a zip file'.encode()) - zf.writestr('dummy_file', stream.getbuffer()) + stream.write("This is a zip file".encode()) + zf.writestr("dummy_file", stream.getbuffer()) file_object.seek(0) file_type = get_file_type(file_object) - self.assertEqual(file_type, 'zip') + self.assertEqual(file_type, "zip") def test_get_file_type_identifies_tdsx_as_zip_file(self): - with open(asset('World Indicators.tdsx'), 'rb') as file_object: + with open(asset("World Indicators.tdsx"), "rb") as file_object: file_type = get_file_type(file_object) - self.assertEqual(file_type, 'zip') + self.assertEqual(file_type, "zip") def test_get_file_type_identifies_twbx_as_zip_file(self): - with open(asset('SampleWB.twbx'), 'rb') as file_object: + with open(asset("SampleWB.twbx"), "rb") as file_object: file_type = get_file_type(file_object) - self.assertEqual(file_type, 'zip') + self.assertEqual(file_type, "zip") def test_get_file_type_identifies_xml_file(self): - root = ET.Element('root') - child = ET.SubElement(root, 'child') + root = ET.Element("root") + child = ET.SubElement(root, "child") child.text = "This is a child element" etree = ET.ElementTree(root) with BytesIO() as file_object: - etree.write(file_object, encoding='utf-8', - xml_declaration=True) + etree.write(file_object, encoding="utf-8", xml_declaration=True) file_object.seek(0) file_type = get_file_type(file_object) - self.assertEqual(file_type, 'xml') + self.assertEqual(file_type, "xml") def test_get_file_type_identifies_tds_as_xml_file(self): - with open(asset('World Indicators.tds'), 'rb') as file_object: + with open(asset("World Indicators.tds"), "rb") as file_object: file_type = get_file_type(file_object) - self.assertEqual(file_type, 'xml') + self.assertEqual(file_type, "xml") def test_get_file_type_identifies_twb_as_xml_file(self): - with open(asset('RESTAPISample.twb'), 'rb') as file_object: + with open(asset("RESTAPISample.twb"), "rb") as file_object: file_type = get_file_type(file_object) - self.assertEqual(file_type, 'xml') + self.assertEqual(file_type, "xml") def test_get_file_type_identifies_hyper_file(self): - with open(asset('World Indicators.hyper'), 'rb') as file_object: + with open(asset("World Indicators.hyper"), "rb") as file_object: file_type = get_file_type(file_object) - self.assertEqual(file_type, 'hyper') + self.assertEqual(file_type, "hyper") def test_get_file_type_identifies_tde_file(self): - asset_path = os.path.join(TEST_ASSET_DIR, 'Data', 'Tableau Samples', 'World Indicators.tde') - with open(asset_path, 'rb') as file_object: + asset_path = os.path.join(TEST_ASSET_DIR, "Data", "Tableau Samples", "World Indicators.tde") + with open(asset_path, "rb") as file_object: file_type = get_file_type(file_object) - self.assertEqual(file_type, 'tde') + self.assertEqual(file_type, "tde") def test_get_file_type_handles_unknown_file_type(self): diff --git a/test/test_fileuploads.py b/test/test_fileuploads.py index 51662e4a2..cd94c1ece 100644 --- a/test/test_fileuploads.py +++ b/test/test_fileuploads.py @@ -5,59 +5,59 @@ from ._utils import asset from tableauserverclient.server import Server -TEST_ASSET_DIR = os.path.join(os.path.dirname(__file__), 'assets') -FILEUPLOAD_INITIALIZE = os.path.join(TEST_ASSET_DIR, 'fileupload_initialize.xml') -FILEUPLOAD_APPEND = os.path.join(TEST_ASSET_DIR, 'fileupload_append.xml') +TEST_ASSET_DIR = os.path.join(os.path.dirname(__file__), "assets") +FILEUPLOAD_INITIALIZE = os.path.join(TEST_ASSET_DIR, "fileupload_initialize.xml") +FILEUPLOAD_APPEND = os.path.join(TEST_ASSET_DIR, "fileupload_append.xml") class FileuploadsTests(unittest.TestCase): def setUp(self): - self.server = Server('http://test') + self.server = Server("http://test") # Fake sign in - self.server._site_id = 'dad65087-b08b-4603-af4e-2887b8aafc67' - self.server._auth_token = 'j80k54ll2lfMZ0tv97mlPvvSCRyD0DOM' + self.server._site_id = "dad65087-b08b-4603-af4e-2887b8aafc67" + self.server._auth_token = "j80k54ll2lfMZ0tv97mlPvvSCRyD0DOM" - self.baseurl = '{}/sites/{}/fileUploads'.format(self.server.baseurl, self.server.site_id) + self.baseurl = "{}/sites/{}/fileUploads".format(self.server.baseurl, self.server.site_id) def test_read_chunks_file_path(self): - file_path = asset('SampleWB.twbx') + file_path = asset("SampleWB.twbx") chunks = self.server.fileuploads._read_chunks(file_path) for chunk in chunks: self.assertIsNotNone(chunk) def test_read_chunks_file_object(self): - with open(asset('SampleWB.twbx'), 'rb') as f: + with open(asset("SampleWB.twbx"), "rb") as f: chunks = self.server.fileuploads._read_chunks(f) for chunk in chunks: self.assertIsNotNone(chunk) def test_upload_chunks_file_path(self): - file_path = asset('SampleWB.twbx') - upload_id = '7720:170fe6b1c1c7422dadff20f944d58a52-1:0' + file_path = asset("SampleWB.twbx") + upload_id = "7720:170fe6b1c1c7422dadff20f944d58a52-1:0" - with open(FILEUPLOAD_INITIALIZE, 'rb') as f: - initialize_response_xml = f.read().decode('utf-8') - with open(FILEUPLOAD_APPEND, 'rb') as f: - append_response_xml = f.read().decode('utf-8') + with open(FILEUPLOAD_INITIALIZE, "rb") as f: + initialize_response_xml = f.read().decode("utf-8") + with open(FILEUPLOAD_APPEND, "rb") as f: + append_response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: m.post(self.baseurl, text=initialize_response_xml) - m.put(self.baseurl + '/' + upload_id, text=append_response_xml) + m.put(self.baseurl + "/" + upload_id, text=append_response_xml) actual = self.server.fileuploads.upload(file_path) self.assertEqual(upload_id, actual) def test_upload_chunks_file_object(self): - upload_id = '7720:170fe6b1c1c7422dadff20f944d58a52-1:0' + upload_id = "7720:170fe6b1c1c7422dadff20f944d58a52-1:0" - with open(asset('SampleWB.twbx'), 'rb') as file_content: - with open(FILEUPLOAD_INITIALIZE, 'rb') as f: - initialize_response_xml = f.read().decode('utf-8') - with open(FILEUPLOAD_APPEND, 'rb') as f: - append_response_xml = f.read().decode('utf-8') + with open(asset("SampleWB.twbx"), "rb") as file_content: + with open(FILEUPLOAD_INITIALIZE, "rb") as f: + initialize_response_xml = f.read().decode("utf-8") + with open(FILEUPLOAD_APPEND, "rb") as f: + append_response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: m.post(self.baseurl, text=initialize_response_xml) - m.put(self.baseurl + '/' + upload_id, text=append_response_xml) + m.put(self.baseurl + "/" + upload_id, text=append_response_xml) actual = self.server.fileuploads.upload(file_content) self.assertEqual(upload_id, actual) diff --git a/test/test_flow.py b/test/test_flow.py index 545623d03..c762223c8 100644 --- a/test/test_flow.py +++ b/test/test_flow.py @@ -8,20 +8,20 @@ from tableauserverclient.server.request_factory import RequestFactory from ._utils import read_xml_asset, read_xml_assets, asset -GET_XML = 'flow_get.xml' -POPULATE_CONNECTIONS_XML = 'flow_populate_connections.xml' -POPULATE_PERMISSIONS_XML = 'flow_populate_permissions.xml' -UPDATE_XML = 'flow_update.xml' -REFRESH_XML = 'flow_refresh.xml' +GET_XML = "flow_get.xml" +POPULATE_CONNECTIONS_XML = "flow_populate_connections.xml" +POPULATE_PERMISSIONS_XML = "flow_populate_permissions.xml" +UPDATE_XML = "flow_update.xml" +REFRESH_XML = "flow_refresh.xml" class FlowTests(unittest.TestCase): def setUp(self): - self.server = TSC.Server('http://test') + self.server = TSC.Server("http://test") # Fake signin - self.server._site_id = 'dad65087-b08b-4603-af4e-2887b8aafc67' - self.server._auth_token = 'j80k54ll2lfMZ0tv97mlPvvSCRyD0DOM' + self.server._site_id = "dad65087-b08b-4603-af4e-2887b8aafc67" + self.server._auth_token = "j80k54ll2lfMZ0tv97mlPvvSCRyD0DOM" self.server.version = "3.5" self.baseurl = self.server.flows.baseurl @@ -33,103 +33,105 @@ def test_get(self): all_flows, pagination_item = self.server.flows.get() self.assertEqual(5, pagination_item.total_available) - self.assertEqual('587daa37-b84d-4400-a9a2-aa90e0be7837', all_flows[0].id) - self.assertEqual('http://tableauserver/#/flows/1', all_flows[0].webpage_url) - self.assertEqual('2019-06-16T21:43:28Z', format_datetime(all_flows[0].created_at)) - self.assertEqual('2019-06-16T21:43:28Z', format_datetime(all_flows[0].updated_at)) - self.assertEqual('Default', all_flows[0].project_name) - self.assertEqual('FlowOne', all_flows[0].name) - self.assertEqual('aa23f4ac-906f-11e9-86fb-3f0f71412e77', all_flows[0].project_id) - self.assertEqual('7ebb3f20-0fd2-4f27-a2f6-c539470999e2', all_flows[0].owner_id) - self.assertEqual({'i_love_tags'}, all_flows[0].tags) - self.assertEqual('Descriptive', all_flows[0].description) - - self.assertEqual('5c36be69-eb30-461b-b66e-3e2a8e27cc35', all_flows[1].id) - self.assertEqual('http://tableauserver/#/flows/4', all_flows[1].webpage_url) - self.assertEqual('2019-06-18T03:08:19Z', format_datetime(all_flows[1].created_at)) - self.assertEqual('2019-06-18T03:08:19Z', format_datetime(all_flows[1].updated_at)) - self.assertEqual('Default', all_flows[1].project_name) - self.assertEqual('FlowTwo', all_flows[1].name) - self.assertEqual('aa23f4ac-906f-11e9-86fb-3f0f71412e77', all_flows[1].project_id) - self.assertEqual('9127d03f-d996-405f-b392-631b25183a0f', all_flows[1].owner_id) + self.assertEqual("587daa37-b84d-4400-a9a2-aa90e0be7837", all_flows[0].id) + self.assertEqual("http://tableauserver/#/flows/1", all_flows[0].webpage_url) + self.assertEqual("2019-06-16T21:43:28Z", format_datetime(all_flows[0].created_at)) + self.assertEqual("2019-06-16T21:43:28Z", format_datetime(all_flows[0].updated_at)) + self.assertEqual("Default", all_flows[0].project_name) + self.assertEqual("FlowOne", all_flows[0].name) + self.assertEqual("aa23f4ac-906f-11e9-86fb-3f0f71412e77", all_flows[0].project_id) + self.assertEqual("7ebb3f20-0fd2-4f27-a2f6-c539470999e2", all_flows[0].owner_id) + self.assertEqual({"i_love_tags"}, all_flows[0].tags) + self.assertEqual("Descriptive", all_flows[0].description) + + self.assertEqual("5c36be69-eb30-461b-b66e-3e2a8e27cc35", all_flows[1].id) + self.assertEqual("http://tableauserver/#/flows/4", all_flows[1].webpage_url) + self.assertEqual("2019-06-18T03:08:19Z", format_datetime(all_flows[1].created_at)) + self.assertEqual("2019-06-18T03:08:19Z", format_datetime(all_flows[1].updated_at)) + self.assertEqual("Default", all_flows[1].project_name) + self.assertEqual("FlowTwo", all_flows[1].name) + self.assertEqual("aa23f4ac-906f-11e9-86fb-3f0f71412e77", all_flows[1].project_id) + self.assertEqual("9127d03f-d996-405f-b392-631b25183a0f", all_flows[1].owner_id) def test_update(self): response_xml = read_xml_asset(UPDATE_XML) with requests_mock.mock() as m: - m.put(self.baseurl + '/587daa37-b84d-4400-a9a2-aa90e0be7837', text=response_xml) - single_datasource = TSC.FlowItem('test', 'aa23f4ac-906f-11e9-86fb-3f0f71412e77') - single_datasource.owner_id = '7ebb3f20-0fd2-4f27-a2f6-c539470999e2' - single_datasource._id = '587daa37-b84d-4400-a9a2-aa90e0be7837' + m.put(self.baseurl + "/587daa37-b84d-4400-a9a2-aa90e0be7837", text=response_xml) + single_datasource = TSC.FlowItem("test", "aa23f4ac-906f-11e9-86fb-3f0f71412e77") + single_datasource.owner_id = "7ebb3f20-0fd2-4f27-a2f6-c539470999e2" + single_datasource._id = "587daa37-b84d-4400-a9a2-aa90e0be7837" single_datasource.description = "So fun to see" single_datasource = self.server.flows.update(single_datasource) - self.assertEqual('587daa37-b84d-4400-a9a2-aa90e0be7837', single_datasource.id) - self.assertEqual('aa23f4ac-906f-11e9-86fb-3f0f71412e77', single_datasource.project_id) - self.assertEqual('7ebb3f20-0fd2-4f27-a2f6-c539470999e2', single_datasource.owner_id) + self.assertEqual("587daa37-b84d-4400-a9a2-aa90e0be7837", single_datasource.id) + self.assertEqual("aa23f4ac-906f-11e9-86fb-3f0f71412e77", single_datasource.project_id) + self.assertEqual("7ebb3f20-0fd2-4f27-a2f6-c539470999e2", single_datasource.owner_id) self.assertEqual("So fun to see", single_datasource.description) def test_populate_connections(self): response_xml = read_xml_asset(POPULATE_CONNECTIONS_XML) with requests_mock.mock() as m: - m.get(self.baseurl + '/9dbd2263-16b5-46e1-9c43-a76bb8ab65fb/connections', text=response_xml) - single_datasource = TSC.FlowItem('test', 'aa23f4ac-906f-11e9-86fb-3f0f71412e77') - single_datasource.owner_id = 'dd2239f6-ddf1-4107-981a-4cf94e415794' - single_datasource._id = '9dbd2263-16b5-46e1-9c43-a76bb8ab65fb' + m.get(self.baseurl + "/9dbd2263-16b5-46e1-9c43-a76bb8ab65fb/connections", text=response_xml) + single_datasource = TSC.FlowItem("test", "aa23f4ac-906f-11e9-86fb-3f0f71412e77") + single_datasource.owner_id = "dd2239f6-ddf1-4107-981a-4cf94e415794" + single_datasource._id = "9dbd2263-16b5-46e1-9c43-a76bb8ab65fb" self.server.flows.populate_connections(single_datasource) - self.assertEqual('9dbd2263-16b5-46e1-9c43-a76bb8ab65fb', single_datasource.id) + self.assertEqual("9dbd2263-16b5-46e1-9c43-a76bb8ab65fb", single_datasource.id) connections = single_datasource.connections self.assertTrue(connections) conn1, conn2, conn3 = connections - self.assertEqual('405c1e4b-60c9-499f-9c47-a4ef1af69359', conn1.id) - self.assertEqual('excel-direct', conn1.connection_type) - self.assertEqual('', conn1.server_address) - self.assertEqual('', conn1.username) + self.assertEqual("405c1e4b-60c9-499f-9c47-a4ef1af69359", conn1.id) + self.assertEqual("excel-direct", conn1.connection_type) + self.assertEqual("", conn1.server_address) + self.assertEqual("", conn1.username) self.assertEqual(False, conn1.embed_password) - self.assertEqual('b47f41b1-2c47-41a3-8b17-a38ebe8b340c', conn2.id) - self.assertEqual('sqlserver', conn2.connection_type) - self.assertEqual('test.database.com', conn2.server_address) - self.assertEqual('bob', conn2.username) + self.assertEqual("b47f41b1-2c47-41a3-8b17-a38ebe8b340c", conn2.id) + self.assertEqual("sqlserver", conn2.connection_type) + self.assertEqual("test.database.com", conn2.server_address) + self.assertEqual("bob", conn2.username) self.assertEqual(False, conn2.embed_password) - self.assertEqual('4f4a3b78-0554-43a7-b327-9605e9df9dd2', conn3.id) - self.assertEqual('tableau-server-site', conn3.connection_type) - self.assertEqual('http://tableauserver', conn3.server_address) - self.assertEqual('sally', conn3.username) + self.assertEqual("4f4a3b78-0554-43a7-b327-9605e9df9dd2", conn3.id) + self.assertEqual("tableau-server-site", conn3.connection_type) + self.assertEqual("http://tableauserver", conn3.server_address) + self.assertEqual("sally", conn3.username) self.assertEqual(True, conn3.embed_password) def test_populate_permissions(self): - with open(asset(POPULATE_PERMISSIONS_XML), 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(asset(POPULATE_PERMISSIONS_XML), "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: - m.get(self.baseurl + '/0448d2ed-590d-4fa0-b272-a2a8a24555b5/permissions', text=response_xml) - single_datasource = TSC.FlowItem('test') - single_datasource._id = '0448d2ed-590d-4fa0-b272-a2a8a24555b5' + m.get(self.baseurl + "/0448d2ed-590d-4fa0-b272-a2a8a24555b5/permissions", text=response_xml) + single_datasource = TSC.FlowItem("test") + single_datasource._id = "0448d2ed-590d-4fa0-b272-a2a8a24555b5" self.server.flows.populate_permissions(single_datasource) permissions = single_datasource.permissions - self.assertEqual(permissions[0].grantee.tag_name, 'group') - self.assertEqual(permissions[0].grantee.id, 'aa42f384-906f-11e9-86fc-bb24278874b9') - self.assertDictEqual(permissions[0].capabilities, { - TSC.Permission.Capability.Write: TSC.Permission.Mode.Allow, - TSC.Permission.Capability.Read: TSC.Permission.Mode.Allow, - }) + self.assertEqual(permissions[0].grantee.tag_name, "group") + self.assertEqual(permissions[0].grantee.id, "aa42f384-906f-11e9-86fc-bb24278874b9") + self.assertDictEqual( + permissions[0].capabilities, + { + TSC.Permission.Capability.Write: TSC.Permission.Mode.Allow, + TSC.Permission.Capability.Read: TSC.Permission.Mode.Allow, + }, + ) def test_refresh(self): - with open(asset(REFRESH_XML), 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(asset(REFRESH_XML), "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: - m.post(self.baseurl + '/92967d2d-c7e2-46d0-8847-4802df58f484/run', text=response_xml) - flow_item = TSC.FlowItem('test') - flow_item._id = '92967d2d-c7e2-46d0-8847-4802df58f484' + m.post(self.baseurl + "/92967d2d-c7e2-46d0-8847-4802df58f484/run", text=response_xml) + flow_item = TSC.FlowItem("test") + flow_item._id = "92967d2d-c7e2-46d0-8847-4802df58f484" refresh_job = self.server.flows.refresh(flow_item) - self.assertEqual(refresh_job.id, 'd1b2ccd0-6dfa-444a-aee4-723dbd6b7c9d') - self.assertEqual(refresh_job.mode, 'Asynchronous') - self.assertEqual(refresh_job.type, 'RunFlow') - self.assertEqual(format_datetime(refresh_job.created_at), '2018-05-22T13:00:29Z') + self.assertEqual(refresh_job.id, "d1b2ccd0-6dfa-444a-aee4-723dbd6b7c9d") + self.assertEqual(refresh_job.mode, "Asynchronous") + self.assertEqual(refresh_job.type, "RunFlow") + self.assertEqual(format_datetime(refresh_job.created_at), "2018-05-22T13:00:29Z") self.assertIsInstance(refresh_job.flow_run, TSC.FlowRunItem) - self.assertEqual(refresh_job.flow_run.id, 'e0c3067f-2333-4eee-8028-e0a56ca496f6') - self.assertEqual(refresh_job.flow_run.flow_id, '92967d2d-c7e2-46d0-8847-4802df58f484') - self.assertEqual(format_datetime(refresh_job.flow_run.started_at), '2018-05-22T13:00:29Z') - + self.assertEqual(refresh_job.flow_run.id, "e0c3067f-2333-4eee-8028-e0a56ca496f6") + self.assertEqual(refresh_job.flow_run.flow_id, "92967d2d-c7e2-46d0-8847-4802df58f484") + self.assertEqual(format_datetime(refresh_job.flow_run.started_at), "2018-05-22T13:00:29Z") diff --git a/test/test_flowruns.py b/test/test_flowruns.py index d2e72f31a..239d46687 100644 --- a/test/test_flowruns.py +++ b/test/test_flowruns.py @@ -8,19 +8,19 @@ from tableauserverclient.server.request_factory import RequestFactory from ._utils import read_xml_asset, mocked_time -GET_XML = 'flow_runs_get.xml' -GET_BY_ID_XML = 'flow_runs_get_by_id.xml' -GET_BY_ID_FAILED_XML = 'flow_runs_get_by_id_failed.xml' -GET_BY_ID_INPROGRESS_XML = 'flow_runs_get_by_id_inprogress.xml' +GET_XML = "flow_runs_get.xml" +GET_BY_ID_XML = "flow_runs_get_by_id.xml" +GET_BY_ID_FAILED_XML = "flow_runs_get_by_id_failed.xml" +GET_BY_ID_INPROGRESS_XML = "flow_runs_get_by_id_inprogress.xml" class FlowRunTests(unittest.TestCase): def setUp(self): - self.server = TSC.Server('http://test') + self.server = TSC.Server("http://test") # Fake signin - self.server._site_id = 'dad65087-b08b-4603-af4e-2887b8aafc67' - self.server._auth_token = 'j80k54ll2lfMZ0tv97mlPvvSCRyD0DOM' + self.server._site_id = "dad65087-b08b-4603-af4e-2887b8aafc67" + self.server._auth_token = "j80k54ll2lfMZ0tv97mlPvvSCRyD0DOM" self.server.version = "3.10" self.baseurl = self.server.flow_runs.baseurl @@ -32,73 +32,70 @@ def test_get(self): all_flow_runs, pagination_item = self.server.flow_runs.get() self.assertEqual(2, pagination_item.total_available) - self.assertEqual('cc2e652d-4a9b-4476-8c93-b238c45db968', all_flow_runs[0].id) - self.assertEqual('2021-02-11T01:42:55Z', format_datetime(all_flow_runs[0].started_at)) - self.assertEqual('2021-02-11T01:57:38Z', format_datetime(all_flow_runs[0].completed_at)) - self.assertEqual('Success', all_flow_runs[0].status) - self.assertEqual('100', all_flow_runs[0].progress) - self.assertEqual('aa23f4ac-906f-11e9-86fb-3f0f71412e77', all_flow_runs[0].background_job_id) - - self.assertEqual('a3104526-c0c6-4ea5-8362-e03fc7cbd7ee', all_flow_runs[1].id) - self.assertEqual('2021-02-13T04:05:30Z', format_datetime(all_flow_runs[1].started_at)) - self.assertEqual('2021-02-13T04:05:35Z', format_datetime(all_flow_runs[1].completed_at)) - self.assertEqual('Failed', all_flow_runs[1].status) - self.assertEqual('100', all_flow_runs[1].progress) - self.assertEqual('1ad21a9d-2530-4fbf-9064-efd3c736e023', all_flow_runs[1].background_job_id) + self.assertEqual("cc2e652d-4a9b-4476-8c93-b238c45db968", all_flow_runs[0].id) + self.assertEqual("2021-02-11T01:42:55Z", format_datetime(all_flow_runs[0].started_at)) + self.assertEqual("2021-02-11T01:57:38Z", format_datetime(all_flow_runs[0].completed_at)) + self.assertEqual("Success", all_flow_runs[0].status) + self.assertEqual("100", all_flow_runs[0].progress) + self.assertEqual("aa23f4ac-906f-11e9-86fb-3f0f71412e77", all_flow_runs[0].background_job_id) + + self.assertEqual("a3104526-c0c6-4ea5-8362-e03fc7cbd7ee", all_flow_runs[1].id) + self.assertEqual("2021-02-13T04:05:30Z", format_datetime(all_flow_runs[1].started_at)) + self.assertEqual("2021-02-13T04:05:35Z", format_datetime(all_flow_runs[1].completed_at)) + self.assertEqual("Failed", all_flow_runs[1].status) + self.assertEqual("100", all_flow_runs[1].progress) + self.assertEqual("1ad21a9d-2530-4fbf-9064-efd3c736e023", all_flow_runs[1].background_job_id) def test_get_by_id(self): response_xml = read_xml_asset(GET_BY_ID_XML) with requests_mock.mock() as m: m.get(self.baseurl + "/cc2e652d-4a9b-4476-8c93-b238c45db968", text=response_xml) flow_run = self.server.flow_runs.get_by_id("cc2e652d-4a9b-4476-8c93-b238c45db968") - - self.assertEqual('cc2e652d-4a9b-4476-8c93-b238c45db968', flow_run.id) - self.assertEqual('2021-02-11T01:42:55Z', format_datetime(flow_run.started_at)) - self.assertEqual('2021-02-11T01:57:38Z', format_datetime(flow_run.completed_at)) - self.assertEqual('Success', flow_run.status) - self.assertEqual('100', flow_run.progress) - self.assertEqual('1ad21a9d-2530-4fbf-9064-efd3c736e023', flow_run.background_job_id) + + self.assertEqual("cc2e652d-4a9b-4476-8c93-b238c45db968", flow_run.id) + self.assertEqual("2021-02-11T01:42:55Z", format_datetime(flow_run.started_at)) + self.assertEqual("2021-02-11T01:57:38Z", format_datetime(flow_run.completed_at)) + self.assertEqual("Success", flow_run.status) + self.assertEqual("100", flow_run.progress) + self.assertEqual("1ad21a9d-2530-4fbf-9064-efd3c736e023", flow_run.background_job_id) def test_cancel_id(self): with requests_mock.mock() as m: - m.put(self.baseurl + '/ee8c6e70-43b6-11e6-af4f-f7b0d8e20760', status_code=204) - self.server.flow_runs.cancel('ee8c6e70-43b6-11e6-af4f-f7b0d8e20760') + m.put(self.baseurl + "/ee8c6e70-43b6-11e6-af4f-f7b0d8e20760", status_code=204) + self.server.flow_runs.cancel("ee8c6e70-43b6-11e6-af4f-f7b0d8e20760") def test_cancel_item(self): run = TSC.FlowRunItem() - run._id = 'ee8c6e70-43b6-11e6-af4f-f7b0d8e20760' + run._id = "ee8c6e70-43b6-11e6-af4f-f7b0d8e20760" with requests_mock.mock() as m: - m.put(self.baseurl + '/ee8c6e70-43b6-11e6-af4f-f7b0d8e20760', status_code=204) + m.put(self.baseurl + "/ee8c6e70-43b6-11e6-af4f-f7b0d8e20760", status_code=204) self.server.flow_runs.cancel(run) - def test_wait_for_job_finished(self): # Waiting for an already finished job, directly returns that job's info response_xml = read_xml_asset(GET_BY_ID_XML) - flow_run_id = 'cc2e652d-4a9b-4476-8c93-b238c45db968' + flow_run_id = "cc2e652d-4a9b-4476-8c93-b238c45db968" with mocked_time(), requests_mock.mock() as m: - m.get('{0}/{1}'.format(self.baseurl, flow_run_id), text=response_xml) + m.get("{0}/{1}".format(self.baseurl, flow_run_id), text=response_xml) flow_run = self.server.flow_runs.wait_for_job(flow_run_id) self.assertEqual(flow_run_id, flow_run.id) self.assertEqual(flow_run.progress, "100") - def test_wait_for_job_failed(self): # Waiting for a failed job raises an exception response_xml = read_xml_asset(GET_BY_ID_FAILED_XML) - flow_run_id = 'c2b35d5a-e130-471a-aec8-7bc5435fe0e7' + flow_run_id = "c2b35d5a-e130-471a-aec8-7bc5435fe0e7" with mocked_time(), requests_mock.mock() as m: - m.get('{0}/{1}'.format(self.baseurl, flow_run_id), text=response_xml) + m.get("{0}/{1}".format(self.baseurl, flow_run_id), text=response_xml) with self.assertRaises(FlowRunFailedException): self.server.flow_runs.wait_for_job(flow_run_id) - def test_wait_for_job_timeout(self): # Waiting for a job which doesn't terminate will throw an exception response_xml = read_xml_asset(GET_BY_ID_INPROGRESS_XML) - flow_run_id = '71afc22c-9c06-40be-8d0f-4c4166d29e6c' + flow_run_id = "71afc22c-9c06-40be-8d0f-4c4166d29e6c" with mocked_time(), requests_mock.mock() as m: - m.get('{0}/{1}'.format(self.baseurl, flow_run_id), text=response_xml) + m.get("{0}/{1}".format(self.baseurl, flow_run_id), text=response_xml) with self.assertRaises(TimeoutError): self.server.flow_runs.wait_for_job(flow_run_id, timeout=30) diff --git a/test/test_group.py b/test/test_group.py index 082a63ba3..63155c6ea 100644 --- a/test/test_group.py +++ b/test/test_group.py @@ -5,230 +5,245 @@ import tableauserverclient as TSC from tableauserverclient.datetime_helpers import format_datetime -TEST_ASSET_DIR = os.path.join(os.path.dirname(__file__), 'assets') +TEST_ASSET_DIR = os.path.join(os.path.dirname(__file__), "assets") -GET_XML = os.path.join(TEST_ASSET_DIR, 'group_get.xml') -POPULATE_USERS = os.path.join(TEST_ASSET_DIR, 'group_populate_users.xml') -POPULATE_USERS_EMPTY = os.path.join(TEST_ASSET_DIR, 'group_populate_users_empty.xml') -ADD_USER = os.path.join(TEST_ASSET_DIR, 'group_add_user.xml') -ADD_USER_POPULATE = os.path.join(TEST_ASSET_DIR, 'group_users_added.xml') -CREATE_GROUP = os.path.join(TEST_ASSET_DIR, 'group_create.xml') -CREATE_GROUP_AD = os.path.join(TEST_ASSET_DIR, 'group_create_ad.xml') -CREATE_GROUP_ASYNC = os.path.join(TEST_ASSET_DIR, 'group_create_async.xml') -UPDATE_XML = os.path.join(TEST_ASSET_DIR, 'group_update.xml') +GET_XML = os.path.join(TEST_ASSET_DIR, "group_get.xml") +POPULATE_USERS = os.path.join(TEST_ASSET_DIR, "group_populate_users.xml") +POPULATE_USERS_EMPTY = os.path.join(TEST_ASSET_DIR, "group_populate_users_empty.xml") +ADD_USER = os.path.join(TEST_ASSET_DIR, "group_add_user.xml") +ADD_USER_POPULATE = os.path.join(TEST_ASSET_DIR, "group_users_added.xml") +CREATE_GROUP = os.path.join(TEST_ASSET_DIR, "group_create.xml") +CREATE_GROUP_AD = os.path.join(TEST_ASSET_DIR, "group_create_ad.xml") +CREATE_GROUP_ASYNC = os.path.join(TEST_ASSET_DIR, "group_create_async.xml") +UPDATE_XML = os.path.join(TEST_ASSET_DIR, "group_update.xml") class GroupTests(unittest.TestCase): def setUp(self): - self.server = TSC.Server('http://test') + self.server = TSC.Server("http://test") # Fake signin - self.server._site_id = 'dad65087-b08b-4603-af4e-2887b8aafc67' - self.server._auth_token = 'j80k54ll2lfMZ0tv97mlPvvSCRyD0DOM' + self.server._site_id = "dad65087-b08b-4603-af4e-2887b8aafc67" + self.server._auth_token = "j80k54ll2lfMZ0tv97mlPvvSCRyD0DOM" self.baseurl = self.server.groups.baseurl def test_get(self): - with open(GET_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(GET_XML, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: m.get(self.baseurl, text=response_xml) all_groups, pagination_item = self.server.groups.get() self.assertEqual(3, pagination_item.total_available) - self.assertEqual('ef8b19c0-43b6-11e6-af50-63f5805dbe3c', all_groups[0].id) - self.assertEqual('All Users', all_groups[0].name) - self.assertEqual('local', all_groups[0].domain_name) + self.assertEqual("ef8b19c0-43b6-11e6-af50-63f5805dbe3c", all_groups[0].id) + self.assertEqual("All Users", all_groups[0].name) + self.assertEqual("local", all_groups[0].domain_name) - self.assertEqual('e7833b48-c6f7-47b5-a2a7-36e7dd232758', all_groups[1].id) - self.assertEqual('Another group', all_groups[1].name) - self.assertEqual('local', all_groups[1].domain_name) + self.assertEqual("e7833b48-c6f7-47b5-a2a7-36e7dd232758", all_groups[1].id) + self.assertEqual("Another group", all_groups[1].name) + self.assertEqual("local", all_groups[1].domain_name) - self.assertEqual('86a66d40-f289-472a-83d0-927b0f954dc8', all_groups[2].id) - self.assertEqual('TableauExample', all_groups[2].name) - self.assertEqual('local', all_groups[2].domain_name) + self.assertEqual("86a66d40-f289-472a-83d0-927b0f954dc8", all_groups[2].id) + self.assertEqual("TableauExample", all_groups[2].name) + self.assertEqual("local", all_groups[2].domain_name) def test_get_before_signin(self): self.server._auth_token = None self.assertRaises(TSC.NotSignedInError, self.server.groups.get) def test_populate_users(self): - with open(POPULATE_USERS, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(POPULATE_USERS, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: - m.get(self.baseurl + '/e7833b48-c6f7-47b5-a2a7-36e7dd232758/users?pageNumber=1&pageSize=100', - text=response_xml, complete_qs=True) - single_group = TSC.GroupItem(name='Test Group') - single_group._id = 'e7833b48-c6f7-47b5-a2a7-36e7dd232758' + m.get( + self.baseurl + "/e7833b48-c6f7-47b5-a2a7-36e7dd232758/users?pageNumber=1&pageSize=100", + text=response_xml, + complete_qs=True, + ) + single_group = TSC.GroupItem(name="Test Group") + single_group._id = "e7833b48-c6f7-47b5-a2a7-36e7dd232758" self.server.groups.populate_users(single_group) self.assertEqual(1, len(list(single_group.users))) user = list(single_group.users).pop() - self.assertEqual('dd2239f6-ddf1-4107-981a-4cf94e415794', user.id) - self.assertEqual('alice', user.name) - self.assertEqual('Publisher', user.site_role) - self.assertEqual('2016-08-16T23:17:06Z', format_datetime(user.last_login)) + self.assertEqual("dd2239f6-ddf1-4107-981a-4cf94e415794", user.id) + self.assertEqual("alice", user.name) + self.assertEqual("Publisher", user.site_role) + self.assertEqual("2016-08-16T23:17:06Z", format_datetime(user.last_login)) def test_delete(self): with requests_mock.mock() as m: - m.delete(self.baseurl + '/e7833b48-c6f7-47b5-a2a7-36e7dd232758', status_code=204) - self.server.groups.delete('e7833b48-c6f7-47b5-a2a7-36e7dd232758') + m.delete(self.baseurl + "/e7833b48-c6f7-47b5-a2a7-36e7dd232758", status_code=204) + self.server.groups.delete("e7833b48-c6f7-47b5-a2a7-36e7dd232758") def test_remove_user(self): - with open(POPULATE_USERS, 'rb') as f: - response_xml_populate = f.read().decode('utf-8') + with open(POPULATE_USERS, "rb") as f: + response_xml_populate = f.read().decode("utf-8") - with open(POPULATE_USERS_EMPTY, 'rb') as f: - response_xml_empty = f.read().decode('utf-8') + with open(POPULATE_USERS_EMPTY, "rb") as f: + response_xml_empty = f.read().decode("utf-8") with requests_mock.mock() as m: - url = self.baseurl + '/e7833b48-c6f7-47b5-a2a7-36e7dd232758/users' \ - '/dd2239f6-ddf1-4107-981a-4cf94e415794' + url = self.baseurl + "/e7833b48-c6f7-47b5-a2a7-36e7dd232758/users" "/dd2239f6-ddf1-4107-981a-4cf94e415794" m.delete(url, status_code=204) # We register the get endpoint twice. The first time we have 1 user, the second we have 'removed' them. - m.get(self.baseurl + '/e7833b48-c6f7-47b5-a2a7-36e7dd232758/users', text=response_xml_populate) + m.get(self.baseurl + "/e7833b48-c6f7-47b5-a2a7-36e7dd232758/users", text=response_xml_populate) - single_group = TSC.GroupItem('test') - single_group._id = 'e7833b48-c6f7-47b5-a2a7-36e7dd232758' + single_group = TSC.GroupItem("test") + single_group._id = "e7833b48-c6f7-47b5-a2a7-36e7dd232758" self.server.groups.populate_users(single_group) self.assertEqual(1, len(list(single_group.users))) - self.server.groups.remove_user(single_group, 'dd2239f6-ddf1-4107-981a-4cf94e415794') + self.server.groups.remove_user(single_group, "dd2239f6-ddf1-4107-981a-4cf94e415794") - m.get(self.baseurl + '/e7833b48-c6f7-47b5-a2a7-36e7dd232758/users', text=response_xml_empty) + m.get(self.baseurl + "/e7833b48-c6f7-47b5-a2a7-36e7dd232758/users", text=response_xml_empty) self.assertEqual(0, len(list(single_group.users))) def test_add_user(self): - with open(ADD_USER, 'rb') as f: - response_xml_add = f.read().decode('utf-8') - with open(ADD_USER_POPULATE, 'rb') as f: - response_xml_populate = f.read().decode('utf-8') + with open(ADD_USER, "rb") as f: + response_xml_add = f.read().decode("utf-8") + with open(ADD_USER_POPULATE, "rb") as f: + response_xml_populate = f.read().decode("utf-8") with requests_mock.mock() as m: - m.post(self.baseurl + '/e7833b48-c6f7-47b5-a2a7-36e7dd232758/users', text=response_xml_add) - m.get(self.baseurl + '/e7833b48-c6f7-47b5-a2a7-36e7dd232758/users', text=response_xml_populate) - single_group = TSC.GroupItem('test') - single_group._id = 'e7833b48-c6f7-47b5-a2a7-36e7dd232758' + m.post(self.baseurl + "/e7833b48-c6f7-47b5-a2a7-36e7dd232758/users", text=response_xml_add) + m.get(self.baseurl + "/e7833b48-c6f7-47b5-a2a7-36e7dd232758/users", text=response_xml_populate) + single_group = TSC.GroupItem("test") + single_group._id = "e7833b48-c6f7-47b5-a2a7-36e7dd232758" - self.server.groups.add_user(single_group, '5de011f8-5aa9-4d5b-b991-f462c8dd6bb7') + self.server.groups.add_user(single_group, "5de011f8-5aa9-4d5b-b991-f462c8dd6bb7") self.server.groups.populate_users(single_group) self.assertEqual(1, len(list(single_group.users))) user = list(single_group.users).pop() - self.assertEqual('5de011f8-5aa9-4d5b-b991-f462c8dd6bb7', user.id) - self.assertEqual('testuser', user.name) - self.assertEqual('ServerAdministrator', user.site_role) + self.assertEqual("5de011f8-5aa9-4d5b-b991-f462c8dd6bb7", user.id) + self.assertEqual("testuser", user.name) + self.assertEqual("ServerAdministrator", user.site_role) def test_add_user_before_populating(self): - with open(GET_XML, 'rb') as f: - get_xml_response = f.read().decode('utf-8') - with open(ADD_USER, 'rb') as f: - add_user_response = f.read().decode('utf-8') + with open(GET_XML, "rb") as f: + get_xml_response = f.read().decode("utf-8") + with open(ADD_USER, "rb") as f: + add_user_response = f.read().decode("utf-8") with requests_mock.mock() as m: m.get(self.baseurl, text=get_xml_response) - m.post('http://test/api/2.3/sites/dad65087-b08b-4603-af4e-2887b8aafc67/groups/ef8b19c0-43b6-11e6-af50' - '-63f5805dbe3c/users', text=add_user_response) + m.post( + "http://test/api/2.3/sites/dad65087-b08b-4603-af4e-2887b8aafc67/groups/ef8b19c0-43b6-11e6-af50" + "-63f5805dbe3c/users", + text=add_user_response, + ) all_groups, pagination_item = self.server.groups.get() single_group = all_groups[0] - self.server.groups.add_user(single_group, '5de011f8-5aa9-4d5b-b991-f462c8dd6bb7') + self.server.groups.add_user(single_group, "5de011f8-5aa9-4d5b-b991-f462c8dd6bb7") def test_add_user_missing_user_id(self): - with open(POPULATE_USERS, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(POPULATE_USERS, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: - m.get(self.baseurl + '/e7833b48-c6f7-47b5-a2a7-36e7dd232758/users', text=response_xml) - single_group = TSC.GroupItem(name='Test Group') - single_group._id = 'e7833b48-c6f7-47b5-a2a7-36e7dd232758' + m.get(self.baseurl + "/e7833b48-c6f7-47b5-a2a7-36e7dd232758/users", text=response_xml) + single_group = TSC.GroupItem(name="Test Group") + single_group._id = "e7833b48-c6f7-47b5-a2a7-36e7dd232758" self.server.groups.populate_users(single_group) - self.assertRaises(ValueError, self.server.groups.add_user, single_group, '') + self.assertRaises(ValueError, self.server.groups.add_user, single_group, "") def test_add_user_missing_group_id(self): - single_group = TSC.GroupItem('test') + single_group = TSC.GroupItem("test") single_group._users = [] - self.assertRaises(TSC.MissingRequiredFieldError, self.server.groups.add_user, single_group, - '5de011f8-5aa9-4d5b-b991-f462c8dd6bb7') + self.assertRaises( + TSC.MissingRequiredFieldError, + self.server.groups.add_user, + single_group, + "5de011f8-5aa9-4d5b-b991-f462c8dd6bb7", + ) def test_remove_user_before_populating(self): - with open(GET_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(GET_XML, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: m.get(self.baseurl, text=response_xml) - m.delete('http://test/api/2.3/sites/dad65087-b08b-4603-af4e-2887b8aafc67/groups/ef8b19c0-43b6-11e6-af50' - '-63f5805dbe3c/users/5de011f8-5aa9-4d5b-b991-f462c8dd6bb7', - text='ok') + m.delete( + "http://test/api/2.3/sites/dad65087-b08b-4603-af4e-2887b8aafc67/groups/ef8b19c0-43b6-11e6-af50" + "-63f5805dbe3c/users/5de011f8-5aa9-4d5b-b991-f462c8dd6bb7", + text="ok", + ) all_groups, pagination_item = self.server.groups.get() single_group = all_groups[0] - self.server.groups.remove_user(single_group, '5de011f8-5aa9-4d5b-b991-f462c8dd6bb7') + self.server.groups.remove_user(single_group, "5de011f8-5aa9-4d5b-b991-f462c8dd6bb7") def test_remove_user_missing_user_id(self): - with open(POPULATE_USERS, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(POPULATE_USERS, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: - m.get(self.baseurl + '/e7833b48-c6f7-47b5-a2a7-36e7dd232758/users', text=response_xml) - single_group = TSC.GroupItem(name='Test Group') - single_group._id = 'e7833b48-c6f7-47b5-a2a7-36e7dd232758' + m.get(self.baseurl + "/e7833b48-c6f7-47b5-a2a7-36e7dd232758/users", text=response_xml) + single_group = TSC.GroupItem(name="Test Group") + single_group._id = "e7833b48-c6f7-47b5-a2a7-36e7dd232758" self.server.groups.populate_users(single_group) - self.assertRaises(ValueError, self.server.groups.remove_user, single_group, '') + self.assertRaises(ValueError, self.server.groups.remove_user, single_group, "") def test_remove_user_missing_group_id(self): - single_group = TSC.GroupItem('test') + single_group = TSC.GroupItem("test") single_group._users = [] - self.assertRaises(TSC.MissingRequiredFieldError, self.server.groups.remove_user, single_group, - '5de011f8-5aa9-4d5b-b991-f462c8dd6bb7') + self.assertRaises( + TSC.MissingRequiredFieldError, + self.server.groups.remove_user, + single_group, + "5de011f8-5aa9-4d5b-b991-f462c8dd6bb7", + ) def test_create_group(self): - with open(CREATE_GROUP, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(CREATE_GROUP, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: m.post(self.baseurl, text=response_xml) - group_to_create = TSC.GroupItem(u'試供品') + group_to_create = TSC.GroupItem(u"試供品") group = self.server.groups.create(group_to_create) - self.assertEqual(group.name, u'試供品') - self.assertEqual(group.id, '3e4a9ea0-a07a-4fe6-b50f-c345c8c81034') + self.assertEqual(group.name, u"試供品") + self.assertEqual(group.id, "3e4a9ea0-a07a-4fe6-b50f-c345c8c81034") def test_create_ad_group(self): - with open(CREATE_GROUP_AD, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(CREATE_GROUP_AD, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: m.post(self.baseurl, text=response_xml) - group_to_create = TSC.GroupItem(u'試供品') - group_to_create.domain_name = 'just-has-to-exist' + group_to_create = TSC.GroupItem(u"試供品") + group_to_create.domain_name = "just-has-to-exist" group = self.server.groups.create_AD_group(group_to_create, False) - self.assertEqual(group.name, u'試供品') - self.assertEqual(group.license_mode, 'onLogin') - self.assertEqual(group.minimum_site_role, 'Creator') - self.assertEqual(group.domain_name, 'active-directory-domain-name') + self.assertEqual(group.name, u"試供品") + self.assertEqual(group.license_mode, "onLogin") + self.assertEqual(group.minimum_site_role, "Creator") + self.assertEqual(group.domain_name, "active-directory-domain-name") def test_create_group_async(self): - with open(CREATE_GROUP_ASYNC, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(CREATE_GROUP_ASYNC, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: m.post(self.baseurl, text=response_xml) - group_to_create = TSC.GroupItem(u'試供品') - group_to_create.domain_name = 'woohoo' + group_to_create = TSC.GroupItem(u"試供品") + group_to_create.domain_name = "woohoo" job = self.server.groups.create_AD_group(group_to_create, True) - self.assertEqual(job.mode, 'Asynchronous') - self.assertEqual(job.type, 'GroupImport') + self.assertEqual(job.mode, "Asynchronous") + self.assertEqual(job.type, "GroupImport") def test_update(self): - with open(UPDATE_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(UPDATE_XML, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: - m.put(self.baseurl + '/ef8b19c0-43b6-11e6-af50-63f5805dbe3c', text=response_xml) - group = TSC.GroupItem(name='Test Group') - group._domain_name = 'local' - group._id = 'ef8b19c0-43b6-11e6-af50-63f5805dbe3c' + m.put(self.baseurl + "/ef8b19c0-43b6-11e6-af50-63f5805dbe3c", text=response_xml) + group = TSC.GroupItem(name="Test Group") + group._domain_name = "local" + group._id = "ef8b19c0-43b6-11e6-af50-63f5805dbe3c" group = self.server.groups.update(group) - self.assertEqual('ef8b19c0-43b6-11e6-af50-63f5805dbe3c', group.id) - self.assertEqual('Group updated name', group.name) - self.assertEqual('ExplorerCanPublish', group.minimum_site_role) - self.assertEqual('onLogin', group.license_mode) + self.assertEqual("ef8b19c0-43b6-11e6-af50-63f5805dbe3c", group.id) + self.assertEqual("Group updated name", group.name) + self.assertEqual("ExplorerCanPublish", group.minimum_site_role) + self.assertEqual("onLogin", group.license_mode) # async update is not supported for local groups def test_update_local_async(self): group = TSC.GroupItem("myGroup") - group._id = 'ef8b19c0-43b6-11e6-af50-63f5805dbe3c' + group._id = "ef8b19c0-43b6-11e6-af50-63f5805dbe3c" self.assertRaises(ValueError, self.server.groups.update, group, as_job=True) # mimic group returned from server where domain name is set to 'local' diff --git a/test/test_job.py b/test/test_job.py index 03ad9b535..71c48d18d 100644 --- a/test/test_job.py +++ b/test/test_job.py @@ -7,23 +7,23 @@ from tableauserverclient.server.endpoint.exceptions import JobFailedException from ._utils import read_xml_asset, mocked_time -TEST_ASSET_DIR = os.path.join(os.path.dirname(__file__), 'assets') +TEST_ASSET_DIR = os.path.join(os.path.dirname(__file__), "assets") -GET_XML = 'job_get.xml' -GET_BY_ID_XML = 'job_get_by_id.xml' -GET_BY_ID_FAILED_XML = 'job_get_by_id_failed.xml' -GET_BY_ID_CANCELLED_XML = 'job_get_by_id_cancelled.xml' -GET_BY_ID_INPROGRESS_XML = 'job_get_by_id_inprogress.xml' +GET_XML = "job_get.xml" +GET_BY_ID_XML = "job_get_by_id.xml" +GET_BY_ID_FAILED_XML = "job_get_by_id_failed.xml" +GET_BY_ID_CANCELLED_XML = "job_get_by_id_cancelled.xml" +GET_BY_ID_INPROGRESS_XML = "job_get_by_id_inprogress.xml" class JobTests(unittest.TestCase): def setUp(self) -> None: - self.server = TSC.Server('http://test') - self.server.version = '3.1' + self.server = TSC.Server("http://test") + self.server.version = "3.1" # Fake signin - self.server._site_id = 'dad65087-b08b-4603-af4e-2887b8aafc67' - self.server._auth_token = 'j80k54ll2lfMZ0tv97mlPvvSCRyD0DOM' + self.server._site_id = "dad65087-b08b-4603-af4e-2887b8aafc67" + self.server._auth_token = "j80k54ll2lfMZ0tv97mlPvvSCRyD0DOM" self.baseurl = self.server.jobs.baseurl @@ -38,23 +38,23 @@ def test_get(self) -> None: ended_at = datetime(2018, 5, 22, 13, 0, 45, tzinfo=utc) self.assertEqual(1, pagination_item.total_available) - self.assertEqual('2eef4225-aa0c-41c4-8662-a76d89ed7336', job.id) - self.assertEqual('Success', job.status) - self.assertEqual('50', job.priority) - self.assertEqual('single_subscription_notify', job.type) + self.assertEqual("2eef4225-aa0c-41c4-8662-a76d89ed7336", job.id) + self.assertEqual("Success", job.status) + self.assertEqual("50", job.priority) + self.assertEqual("single_subscription_notify", job.type) self.assertEqual(created_at, job.created_at) self.assertEqual(started_at, job.started_at) self.assertEqual(ended_at, job.ended_at) def test_get_by_id(self) -> None: response_xml = read_xml_asset(GET_BY_ID_XML) - job_id = '2eef4225-aa0c-41c4-8662-a76d89ed7336' + job_id = "2eef4225-aa0c-41c4-8662-a76d89ed7336" with requests_mock.mock() as m: - m.get('{0}/{1}'.format(self.baseurl, job_id), text=response_xml) + m.get("{0}/{1}".format(self.baseurl, job_id), text=response_xml) job = self.server.jobs.get_by_id(job_id) self.assertEqual(job_id, job.id) - self.assertListEqual(job.notes, ['Job detail notes']) + self.assertListEqual(job.notes, ["Job detail notes"]) def test_get_before_signin(self) -> None: self.server._auth_token = None @@ -62,46 +62,42 @@ def test_get_before_signin(self) -> None: def test_cancel_id(self) -> None: with requests_mock.mock() as m: - m.put(self.baseurl + '/ee8c6e70-43b6-11e6-af4f-f7b0d8e20760', status_code=204) - self.server.jobs.cancel('ee8c6e70-43b6-11e6-af4f-f7b0d8e20760') + m.put(self.baseurl + "/ee8c6e70-43b6-11e6-af4f-f7b0d8e20760", status_code=204) + self.server.jobs.cancel("ee8c6e70-43b6-11e6-af4f-f7b0d8e20760") def test_cancel_item(self) -> None: created_at = datetime(2018, 5, 22, 13, 0, 29, tzinfo=utc) started_at = datetime(2018, 5, 22, 13, 0, 37, tzinfo=utc) - job = TSC.JobItem('ee8c6e70-43b6-11e6-af4f-f7b0d8e20760', 'backgroundJob', - "0", created_at, started_at, None, 0) + job = TSC.JobItem("ee8c6e70-43b6-11e6-af4f-f7b0d8e20760", "backgroundJob", "0", created_at, started_at, None, 0) with requests_mock.mock() as m: - m.put(self.baseurl + '/ee8c6e70-43b6-11e6-af4f-f7b0d8e20760', status_code=204) + m.put(self.baseurl + "/ee8c6e70-43b6-11e6-af4f-f7b0d8e20760", status_code=204) self.server.jobs.cancel(job) - def test_wait_for_job_finished(self) -> None: # Waiting for an already finished job, directly returns that job's info response_xml = read_xml_asset(GET_BY_ID_XML) - job_id = '2eef4225-aa0c-41c4-8662-a76d89ed7336' + job_id = "2eef4225-aa0c-41c4-8662-a76d89ed7336" with mocked_time(), requests_mock.mock() as m: - m.get('{0}/{1}'.format(self.baseurl, job_id), text=response_xml) + m.get("{0}/{1}".format(self.baseurl, job_id), text=response_xml) job = self.server.jobs.wait_for_job(job_id) self.assertEqual(job_id, job.id) - self.assertListEqual(job.notes, ['Job detail notes']) - + self.assertListEqual(job.notes, ["Job detail notes"]) def test_wait_for_job_failed(self) -> None: # Waiting for a failed job raises an exception response_xml = read_xml_asset(GET_BY_ID_FAILED_XML) - job_id = '77d5e57a-2517-479f-9a3c-a32025f2b64d' + job_id = "77d5e57a-2517-479f-9a3c-a32025f2b64d" with mocked_time(), requests_mock.mock() as m: - m.get('{0}/{1}'.format(self.baseurl, job_id), text=response_xml) + m.get("{0}/{1}".format(self.baseurl, job_id), text=response_xml) with self.assertRaises(JobFailedException): self.server.jobs.wait_for_job(job_id) - def test_wait_for_job_timeout(self) -> None: # Waiting for a job which doesn't terminate will throw an exception response_xml = read_xml_asset(GET_BY_ID_INPROGRESS_XML) - job_id = '77d5e57a-2517-479f-9a3c-a32025f2b64d' + job_id = "77d5e57a-2517-479f-9a3c-a32025f2b64d" with mocked_time(), requests_mock.mock() as m: - m.get('{0}/{1}'.format(self.baseurl, job_id), text=response_xml) + m.get("{0}/{1}".format(self.baseurl, job_id), text=response_xml) with self.assertRaises(TimeoutError): self.server.jobs.wait_for_job(job_id, timeout=30) diff --git a/test/test_metadata.py b/test/test_metadata.py index 1c0846d73..3510128c8 100644 --- a/test/test_metadata.py +++ b/test/test_metadata.py @@ -6,93 +6,96 @@ from tableauserverclient.server.endpoint.exceptions import GraphQLError -TEST_ASSET_DIR = os.path.join(os.path.dirname(__file__), 'assets') +TEST_ASSET_DIR = os.path.join(os.path.dirname(__file__), "assets") -METADATA_QUERY_SUCCESS = os.path.join(TEST_ASSET_DIR, 'metadata_query_success.json') -METADATA_QUERY_ERROR = os.path.join(TEST_ASSET_DIR, 'metadata_query_error.json') -EXPECTED_PAGED_DICT = os.path.join(TEST_ASSET_DIR, 'metadata_query_expected_dict.dict') +METADATA_QUERY_SUCCESS = os.path.join(TEST_ASSET_DIR, "metadata_query_success.json") +METADATA_QUERY_ERROR = os.path.join(TEST_ASSET_DIR, "metadata_query_error.json") +EXPECTED_PAGED_DICT = os.path.join(TEST_ASSET_DIR, "metadata_query_expected_dict.dict") -METADATA_PAGE_1 = os.path.join(TEST_ASSET_DIR, 'metadata_paged_1.json') -METADATA_PAGE_2 = os.path.join(TEST_ASSET_DIR, 'metadata_paged_2.json') -METADATA_PAGE_3 = os.path.join(TEST_ASSET_DIR, 'metadata_paged_3.json') +METADATA_PAGE_1 = os.path.join(TEST_ASSET_DIR, "metadata_paged_1.json") +METADATA_PAGE_2 = os.path.join(TEST_ASSET_DIR, "metadata_paged_2.json") +METADATA_PAGE_3 = os.path.join(TEST_ASSET_DIR, "metadata_paged_3.json") -EXPECTED_DICT = {'publishedDatasources': - [{'id': '01cf92b2-2d17-b656-fc48-5c25ef6d5352', 'name': 'Batters (TestV1)'}, - {'id': '020ae1cd-c356-f1ad-a846-b0094850d22a', 'name': 'SharePoint_List_sharepoint2010.test.tsi.lan'}, - {'id': '061493a0-c3b2-6f39-d08c-bc3f842b44af', 'name': 'Batters_mongodb'}, - {'id': '089fe515-ad2f-89bc-94bd-69f55f69a9c2', 'name': 'Sample - Superstore'}]} +EXPECTED_DICT = { + "publishedDatasources": [ + {"id": "01cf92b2-2d17-b656-fc48-5c25ef6d5352", "name": "Batters (TestV1)"}, + {"id": "020ae1cd-c356-f1ad-a846-b0094850d22a", "name": "SharePoint_List_sharepoint2010.test.tsi.lan"}, + {"id": "061493a0-c3b2-6f39-d08c-bc3f842b44af", "name": "Batters_mongodb"}, + {"id": "089fe515-ad2f-89bc-94bd-69f55f69a9c2", "name": "Sample - Superstore"}, + ] +} -EXPECTED_DICT_ERROR = [ - { - "message": "Reached time limit of PT5S for query execution.", - "path": None, - "extensions": None - } -] +EXPECTED_DICT_ERROR = [{"message": "Reached time limit of PT5S for query execution.", "path": None, "extensions": None}] class MetadataTests(unittest.TestCase): def setUp(self): - self.server = TSC.Server('http://test') + self.server = TSC.Server("http://test") self.baseurl = self.server.metadata.baseurl self.server.version = "3.5" - self.server._site_id = 'dad65087-b08b-4603-af4e-2887b8aafc67' - self.server._auth_token = 'j80k54ll2lfMZ0tv97mlPvvSCRyD0DOM' + self.server._site_id = "dad65087-b08b-4603-af4e-2887b8aafc67" + self.server._auth_token = "j80k54ll2lfMZ0tv97mlPvvSCRyD0DOM" def test_metadata_query(self): - with open(METADATA_QUERY_SUCCESS, 'rb') as f: + with open(METADATA_QUERY_SUCCESS, "rb") as f: response_json = json.loads(f.read().decode()) with requests_mock.mock() as m: m.post(self.baseurl, json=response_json) - actual = self.server.metadata.query('fake query') + actual = self.server.metadata.query("fake query") - datasources = actual['data'] + datasources = actual["data"] self.assertDictEqual(EXPECTED_DICT, datasources) def test_paged_metadata_query(self): - with open(EXPECTED_PAGED_DICT, 'rb') as f: + with open(EXPECTED_PAGED_DICT, "rb") as f: expected = eval(f.read()) # prepare the 3 pages of results - with open(METADATA_PAGE_1, 'rb') as f: + with open(METADATA_PAGE_1, "rb") as f: result_1 = f.read().decode() - with open(METADATA_PAGE_2, 'rb') as f: + with open(METADATA_PAGE_2, "rb") as f: result_2 = f.read().decode() - with open(METADATA_PAGE_3, 'rb') as f: + with open(METADATA_PAGE_3, "rb") as f: result_3 = f.read().decode() with requests_mock.mock() as m: - m.post(self.baseurl, [{'text': result_1, 'status_code': 200}, - {'text': result_2, 'status_code': 200}, - {'text': result_3, 'status_code': 200}]) + m.post( + self.baseurl, + [ + {"text": result_1, "status_code": 200}, + {"text": result_2, "status_code": 200}, + {"text": result_3, "status_code": 200}, + ], + ) # validation checks for endCursor and hasNextPage, # but the query text doesn't matter for the test - actual = self.server.metadata.paginated_query('fake query endCursor hasNextPage', - variables={'first': 1, 'afterToken': None}) + actual = self.server.metadata.paginated_query( + "fake query endCursor hasNextPage", variables={"first": 1, "afterToken": None} + ) self.assertDictEqual(expected, actual) def test_metadata_query_ignore_error(self): - with open(METADATA_QUERY_ERROR, 'rb') as f: + with open(METADATA_QUERY_ERROR, "rb") as f: response_json = json.loads(f.read().decode()) with requests_mock.mock() as m: m.post(self.baseurl, json=response_json) - actual = self.server.metadata.query('fake query') - datasources = actual['data'] + actual = self.server.metadata.query("fake query") + datasources = actual["data"] - self.assertNotEqual(actual.get('errors', None), None) - self.assertListEqual(EXPECTED_DICT_ERROR, actual['errors']) + self.assertNotEqual(actual.get("errors", None), None) + self.assertListEqual(EXPECTED_DICT_ERROR, actual["errors"]) self.assertDictEqual(EXPECTED_DICT, datasources) def test_metadata_query_abort_on_error(self): - with open(METADATA_QUERY_ERROR, 'rb') as f: + with open(METADATA_QUERY_ERROR, "rb") as f: response_json = json.loads(f.read().decode()) with requests_mock.mock() as m: m.post(self.baseurl, json=response_json) with self.assertRaises(GraphQLError) as e: - self.server.metadata.query('fake query', abort_on_error=True) + self.server.metadata.query("fake query", abort_on_error=True) self.assertListEqual(e.error, EXPECTED_DICT_ERROR) diff --git a/test/test_pager.py b/test/test_pager.py index 52089180d..21b49bcf0 100644 --- a/test/test_pager.py +++ b/test/test_pager.py @@ -3,30 +3,30 @@ import requests_mock import tableauserverclient as TSC -TEST_ASSET_DIR = os.path.join(os.path.dirname(__file__), 'assets') +TEST_ASSET_DIR = os.path.join(os.path.dirname(__file__), "assets") -GET_XML_PAGE1 = os.path.join(TEST_ASSET_DIR, 'workbook_get_page_1.xml') -GET_XML_PAGE2 = os.path.join(TEST_ASSET_DIR, 'workbook_get_page_2.xml') -GET_XML_PAGE3 = os.path.join(TEST_ASSET_DIR, 'workbook_get_page_3.xml') +GET_XML_PAGE1 = os.path.join(TEST_ASSET_DIR, "workbook_get_page_1.xml") +GET_XML_PAGE2 = os.path.join(TEST_ASSET_DIR, "workbook_get_page_2.xml") +GET_XML_PAGE3 = os.path.join(TEST_ASSET_DIR, "workbook_get_page_3.xml") class PagerTests(unittest.TestCase): def setUp(self): - self.server = TSC.Server('http://test') + self.server = TSC.Server("http://test") # Fake sign in - self.server._site_id = 'dad65087-b08b-4603-af4e-2887b8aafc67' - self.server._auth_token = 'j80k54ll2lfMZ0tv97mlPvvSCRyD0DOM' + self.server._site_id = "dad65087-b08b-4603-af4e-2887b8aafc67" + self.server._auth_token = "j80k54ll2lfMZ0tv97mlPvvSCRyD0DOM" self.baseurl = self.server.workbooks.baseurl def test_pager_with_no_options(self): - with open(GET_XML_PAGE1, 'rb') as f: - page_1 = f.read().decode('utf-8') - with open(GET_XML_PAGE2, 'rb') as f: - page_2 = f.read().decode('utf-8') - with open(GET_XML_PAGE3, 'rb') as f: - page_3 = f.read().decode('utf-8') + with open(GET_XML_PAGE1, "rb") as f: + page_1 = f.read().decode("utf-8") + with open(GET_XML_PAGE2, "rb") as f: + page_2 = f.read().decode("utf-8") + with open(GET_XML_PAGE3, "rb") as f: + page_3 = f.read().decode("utf-8") with requests_mock.mock() as m: # Register Pager with default request options m.get(self.baseurl, text=page_1) @@ -42,17 +42,17 @@ def test_pager_with_no_options(self): # Let's check that workbook items aren't duplicates wb1, wb2, wb3 = workbooks - self.assertEqual(wb1.name, 'Page1Workbook') - self.assertEqual(wb2.name, 'Page2Workbook') - self.assertEqual(wb3.name, 'Page3Workbook') + self.assertEqual(wb1.name, "Page1Workbook") + self.assertEqual(wb2.name, "Page2Workbook") + self.assertEqual(wb3.name, "Page3Workbook") def test_pager_with_options(self): - with open(GET_XML_PAGE1, 'rb') as f: - page_1 = f.read().decode('utf-8') - with open(GET_XML_PAGE2, 'rb') as f: - page_2 = f.read().decode('utf-8') - with open(GET_XML_PAGE3, 'rb') as f: - page_3 = f.read().decode('utf-8') + with open(GET_XML_PAGE1, "rb") as f: + page_1 = f.read().decode("utf-8") + with open(GET_XML_PAGE2, "rb") as f: + page_2 = f.read().decode("utf-8") + with open(GET_XML_PAGE3, "rb") as f: + page_3 = f.read().decode("utf-8") with requests_mock.mock() as m: # Register Pager with some pages m.get(self.baseurl + "?pageNumber=1&pageSize=1", complete_qs=True, text=page_1) @@ -67,17 +67,17 @@ def test_pager_with_options(self): # Check that the workbooks are the 2 we think they should be wb2, wb3 = workbooks - self.assertEqual(wb2.name, 'Page2Workbook') - self.assertEqual(wb3.name, 'Page3Workbook') + self.assertEqual(wb2.name, "Page2Workbook") + self.assertEqual(wb3.name, "Page3Workbook") # Starting on 1 with pagesize of 3 should get all 3 opts = TSC.RequestOptions(1, 3) workbooks = list(TSC.Pager(self.server.workbooks, opts)) self.assertTrue(len(workbooks) == 3) wb1, wb2, wb3 = workbooks - self.assertEqual(wb1.name, 'Page1Workbook') - self.assertEqual(wb2.name, 'Page2Workbook') - self.assertEqual(wb3.name, 'Page3Workbook') + self.assertEqual(wb1.name, "Page1Workbook") + self.assertEqual(wb2.name, "Page2Workbook") + self.assertEqual(wb3.name, "Page3Workbook") # Starting on 3 with pagesize of 1 should get the last item opts = TSC.RequestOptions(3, 1) @@ -85,4 +85,4 @@ def test_pager_with_options(self): self.assertTrue(len(workbooks) == 1) # Should have the last workbook wb3 = workbooks.pop() - self.assertEqual(wb3.name, 'Page3Workbook') + self.assertEqual(wb3.name, "Page3Workbook") diff --git a/test/test_project.py b/test/test_project.py index be43b063e..c8812e399 100644 --- a/test/test_project.py +++ b/test/test_project.py @@ -5,54 +5,53 @@ from ._utils import read_xml_asset, read_xml_assets, asset -TEST_ASSET_DIR = os.path.join(os.path.dirname(__file__), 'assets') +TEST_ASSET_DIR = os.path.join(os.path.dirname(__file__), "assets") -GET_XML = asset('project_get.xml') -UPDATE_XML = asset('project_update.xml') -SET_CONTENT_PERMISSIONS_XML = asset('project_content_permission.xml') -CREATE_XML = asset('project_create.xml') -POPULATE_PERMISSIONS_XML = 'project_populate_permissions.xml' -POPULATE_WORKBOOK_DEFAULT_PERMISSIONS_XML = 'project_populate_workbook_default_permissions.xml' -UPDATE_DATASOURCE_DEFAULT_PERMISSIONS_XML = 'project_update_datasource_default_permissions.xml' +GET_XML = asset("project_get.xml") +UPDATE_XML = asset("project_update.xml") +SET_CONTENT_PERMISSIONS_XML = asset("project_content_permission.xml") +CREATE_XML = asset("project_create.xml") +POPULATE_PERMISSIONS_XML = "project_populate_permissions.xml" +POPULATE_WORKBOOK_DEFAULT_PERMISSIONS_XML = "project_populate_workbook_default_permissions.xml" +UPDATE_DATASOURCE_DEFAULT_PERMISSIONS_XML = "project_update_datasource_default_permissions.xml" class ProjectTests(unittest.TestCase): def setUp(self): - self.server = TSC.Server('http://test') + self.server = TSC.Server("http://test") # Fake signin - self.server._site_id = 'dad65087-b08b-4603-af4e-2887b8aafc67' - self.server._auth_token = 'j80k54ll2lfMZ0tv97mlPvvSCRyD0DOM' + self.server._site_id = "dad65087-b08b-4603-af4e-2887b8aafc67" + self.server._auth_token = "j80k54ll2lfMZ0tv97mlPvvSCRyD0DOM" self.baseurl = self.server.projects.baseurl def test_get(self): - with open(GET_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(GET_XML, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: m.get(self.baseurl, text=response_xml) all_projects, pagination_item = self.server.projects.get() self.assertEqual(3, pagination_item.total_available) - self.assertEqual('ee8c6e70-43b6-11e6-af4f-f7b0d8e20760', all_projects[0].id) - self.assertEqual('default', all_projects[0].name) - self.assertEqual('The default project that was automatically created by Tableau.', - all_projects[0].description) - self.assertEqual('ManagedByOwner', all_projects[0].content_permissions) + self.assertEqual("ee8c6e70-43b6-11e6-af4f-f7b0d8e20760", all_projects[0].id) + self.assertEqual("default", all_projects[0].name) + self.assertEqual("The default project that was automatically created by Tableau.", all_projects[0].description) + self.assertEqual("ManagedByOwner", all_projects[0].content_permissions) self.assertEqual(None, all_projects[0].parent_id) - self.assertEqual('dd2239f6-ddf1-4107-981a-4cf94e415794', all_projects[0].owner_id) + self.assertEqual("dd2239f6-ddf1-4107-981a-4cf94e415794", all_projects[0].owner_id) - self.assertEqual('1d0304cd-3796-429f-b815-7258370b9b74', all_projects[1].id) - self.assertEqual('Tableau', all_projects[1].name) - self.assertEqual('ManagedByOwner', all_projects[1].content_permissions) + self.assertEqual("1d0304cd-3796-429f-b815-7258370b9b74", all_projects[1].id) + self.assertEqual("Tableau", all_projects[1].name) + self.assertEqual("ManagedByOwner", all_projects[1].content_permissions) self.assertEqual(None, all_projects[1].parent_id) - self.assertEqual('2a47bbf8-8900-4ebb-b0a4-2723bd7c46c3', all_projects[1].owner_id) + self.assertEqual("2a47bbf8-8900-4ebb-b0a4-2723bd7c46c3", all_projects[1].owner_id) - self.assertEqual('4cc52973-5e3a-4d1f-a4fb-5b5f73796edf', all_projects[2].id) - self.assertEqual('Tableau > Child 1', all_projects[2].name) - self.assertEqual('ManagedByOwner', all_projects[2].content_permissions) - self.assertEqual('1d0304cd-3796-429f-b815-7258370b9b74', all_projects[2].parent_id) - self.assertEqual('dd2239f6-ddf1-4107-981a-4cf94e415794', all_projects[2].owner_id) + self.assertEqual("4cc52973-5e3a-4d1f-a4fb-5b5f73796edf", all_projects[2].id) + self.assertEqual("Tableau > Child 1", all_projects[2].name) + self.assertEqual("ManagedByOwner", all_projects[2].content_permissions) + self.assertEqual("1d0304cd-3796-429f-b815-7258370b9b74", all_projects[2].parent_id) + self.assertEqual("dd2239f6-ddf1-4107-981a-4cf94e415794", all_projects[2].owner_id) def test_get_before_signin(self): self.server._auth_token = None @@ -60,161 +59,171 @@ def test_get_before_signin(self): def test_delete(self): with requests_mock.mock() as m: - m.delete(self.baseurl + '/ee8c6e70-43b6-11e6-af4f-f7b0d8e20760', status_code=204) - self.server.projects.delete('ee8c6e70-43b6-11e6-af4f-f7b0d8e20760') + m.delete(self.baseurl + "/ee8c6e70-43b6-11e6-af4f-f7b0d8e20760", status_code=204) + self.server.projects.delete("ee8c6e70-43b6-11e6-af4f-f7b0d8e20760") def test_delete_missing_id(self): - self.assertRaises(ValueError, self.server.projects.delete, '') + self.assertRaises(ValueError, self.server.projects.delete, "") def test_update(self): - with open(UPDATE_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(UPDATE_XML, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: - m.put(self.baseurl + '/1d0304cd-3796-429f-b815-7258370b9b74', text=response_xml) - single_project = TSC.ProjectItem(name='Test Project', - content_permissions='LockedToProject', - description='Project created for testing', - parent_id='9a8f2265-70f3-4494-96c5-e5949d7a1120') - single_project._id = '1d0304cd-3796-429f-b815-7258370b9b74' + m.put(self.baseurl + "/1d0304cd-3796-429f-b815-7258370b9b74", text=response_xml) + single_project = TSC.ProjectItem( + name="Test Project", + content_permissions="LockedToProject", + description="Project created for testing", + parent_id="9a8f2265-70f3-4494-96c5-e5949d7a1120", + ) + single_project._id = "1d0304cd-3796-429f-b815-7258370b9b74" single_project = self.server.projects.update(single_project) - self.assertEqual('1d0304cd-3796-429f-b815-7258370b9b74', single_project.id) - self.assertEqual('Test Project', single_project.name) - self.assertEqual('Project created for testing', single_project.description) - self.assertEqual('LockedToProject', single_project.content_permissions) - self.assertEqual('9a8f2265-70f3-4494-96c5-e5949d7a1120', single_project.parent_id) + self.assertEqual("1d0304cd-3796-429f-b815-7258370b9b74", single_project.id) + self.assertEqual("Test Project", single_project.name) + self.assertEqual("Project created for testing", single_project.description) + self.assertEqual("LockedToProject", single_project.content_permissions) + self.assertEqual("9a8f2265-70f3-4494-96c5-e5949d7a1120", single_project.parent_id) def test_content_permission_locked_to_project_without_nested(self): - with open(SET_CONTENT_PERMISSIONS_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(SET_CONTENT_PERMISSIONS_XML, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: - m.put(self.baseurl + '/cb3759e5-da4a-4ade-b916-7e2b4ea7ec86', text=response_xml) - project_item = TSC.ProjectItem(name='Test Project Permissions', - content_permissions='LockedToProjectWithoutNested', - description='Project created for testing', - parent_id='7687bc43-a543-42f3-b86f-80caed03a813') - project_item._id = 'cb3759e5-da4a-4ade-b916-7e2b4ea7ec86' + m.put(self.baseurl + "/cb3759e5-da4a-4ade-b916-7e2b4ea7ec86", text=response_xml) + project_item = TSC.ProjectItem( + name="Test Project Permissions", + content_permissions="LockedToProjectWithoutNested", + description="Project created for testing", + parent_id="7687bc43-a543-42f3-b86f-80caed03a813", + ) + project_item._id = "cb3759e5-da4a-4ade-b916-7e2b4ea7ec86" project_item = self.server.projects.update(project_item) - self.assertEqual('cb3759e5-da4a-4ade-b916-7e2b4ea7ec86', project_item.id) - self.assertEqual('Test Project Permissions', project_item.name) - self.assertEqual('Project created for testing', project_item.description) - self.assertEqual('LockedToProjectWithoutNested', project_item.content_permissions) - self.assertEqual('7687bc43-a543-42f3-b86f-80caed03a813', project_item.parent_id) + self.assertEqual("cb3759e5-da4a-4ade-b916-7e2b4ea7ec86", project_item.id) + self.assertEqual("Test Project Permissions", project_item.name) + self.assertEqual("Project created for testing", project_item.description) + self.assertEqual("LockedToProjectWithoutNested", project_item.content_permissions) + self.assertEqual("7687bc43-a543-42f3-b86f-80caed03a813", project_item.parent_id) def test_update_datasource_default_permission(self): response_xml = read_xml_asset(UPDATE_DATASOURCE_DEFAULT_PERMISSIONS_XML) with requests_mock.mock() as m: - m.put(self.baseurl + '/b4065286-80f0-11ea-af1b-cb7191f48e45/default-permissions/datasources', - text=response_xml) - project = TSC.ProjectItem('test-project') - project._id = 'b4065286-80f0-11ea-af1b-cb7191f48e45' + m.put( + self.baseurl + "/b4065286-80f0-11ea-af1b-cb7191f48e45/default-permissions/datasources", + text=response_xml, + ) + project = TSC.ProjectItem("test-project") + project._id = "b4065286-80f0-11ea-af1b-cb7191f48e45" - group = TSC.GroupItem('test-group') - group._id = 'b4488bce-80f0-11ea-af1c-976d0c1dab39' + group = TSC.GroupItem("test-group") + group._id = "b4488bce-80f0-11ea-af1c-976d0c1dab39" capabilities = {TSC.Permission.Capability.ExportXml: TSC.Permission.Mode.Deny} - rules = [TSC.PermissionsRule( - grantee=group, - capabilities=capabilities - )] + rules = [TSC.PermissionsRule(grantee=group, capabilities=capabilities)] new_rules = self.server.projects.update_datasource_default_permissions(project, rules) - self.assertEqual('b4488bce-80f0-11ea-af1c-976d0c1dab39', new_rules[0].grantee.id) + self.assertEqual("b4488bce-80f0-11ea-af1c-976d0c1dab39", new_rules[0].grantee.id) updated_capabilities = new_rules[0].capabilities self.assertEqual(4, len(updated_capabilities)) - self.assertEqual('Deny', updated_capabilities['ExportXml']) - self.assertEqual('Allow', updated_capabilities['Read']) - self.assertEqual('Allow', updated_capabilities['Write']) - self.assertEqual('Allow', updated_capabilities['Connect']) + self.assertEqual("Deny", updated_capabilities["ExportXml"]) + self.assertEqual("Allow", updated_capabilities["Read"]) + self.assertEqual("Allow", updated_capabilities["Write"]) + self.assertEqual("Allow", updated_capabilities["Connect"]) def test_update_missing_id(self): - single_project = TSC.ProjectItem('test') + single_project = TSC.ProjectItem("test") self.assertRaises(TSC.MissingRequiredFieldError, self.server.projects.update, single_project) def test_create(self): - with open(CREATE_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(CREATE_XML, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: m.post(self.baseurl, text=response_xml) - new_project = TSC.ProjectItem(name='Test Project', description='Project created for testing') - new_project.content_permissions = 'ManagedByOwner' - new_project.parent_id = '9a8f2265-70f3-4494-96c5-e5949d7a1120' + new_project = TSC.ProjectItem(name="Test Project", description="Project created for testing") + new_project.content_permissions = "ManagedByOwner" + new_project.parent_id = "9a8f2265-70f3-4494-96c5-e5949d7a1120" new_project = self.server.projects.create(new_project) - self.assertEqual('ccbea03f-77c4-4209-8774-f67bc59c3cef', new_project.id) - self.assertEqual('Test Project', new_project.name) - self.assertEqual('Project created for testing', new_project.description) - self.assertEqual('ManagedByOwner', new_project.content_permissions) - self.assertEqual('9a8f2265-70f3-4494-96c5-e5949d7a1120', new_project.parent_id) + self.assertEqual("ccbea03f-77c4-4209-8774-f67bc59c3cef", new_project.id) + self.assertEqual("Test Project", new_project.name) + self.assertEqual("Project created for testing", new_project.description) + self.assertEqual("ManagedByOwner", new_project.content_permissions) + self.assertEqual("9a8f2265-70f3-4494-96c5-e5949d7a1120", new_project.parent_id) def test_create_missing_name(self): - self.assertRaises(ValueError, TSC.ProjectItem, '') + self.assertRaises(ValueError, TSC.ProjectItem, "") def test_populate_permissions(self): - with open(asset(POPULATE_PERMISSIONS_XML), 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(asset(POPULATE_PERMISSIONS_XML), "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: - m.get(self.baseurl + '/0448d2ed-590d-4fa0-b272-a2a8a24555b5/permissions', text=response_xml) - single_project = TSC.ProjectItem('Project3') - single_project._id = '0448d2ed-590d-4fa0-b272-a2a8a24555b5' + m.get(self.baseurl + "/0448d2ed-590d-4fa0-b272-a2a8a24555b5/permissions", text=response_xml) + single_project = TSC.ProjectItem("Project3") + single_project._id = "0448d2ed-590d-4fa0-b272-a2a8a24555b5" self.server.projects.populate_permissions(single_project) permissions = single_project.permissions - self.assertEqual(permissions[0].grantee.tag_name, 'group') - self.assertEqual(permissions[0].grantee.id, 'c8f2773a-c83a-11e8-8c8f-33e6d787b506') - self.assertDictEqual(permissions[0].capabilities, { - TSC.Permission.Capability.Write: TSC.Permission.Mode.Allow, - TSC.Permission.Capability.Read: TSC.Permission.Mode.Allow, - }) + self.assertEqual(permissions[0].grantee.tag_name, "group") + self.assertEqual(permissions[0].grantee.id, "c8f2773a-c83a-11e8-8c8f-33e6d787b506") + self.assertDictEqual( + permissions[0].capabilities, + { + TSC.Permission.Capability.Write: TSC.Permission.Mode.Allow, + TSC.Permission.Capability.Read: TSC.Permission.Mode.Allow, + }, + ) def test_populate_workbooks(self): response_xml = read_xml_asset(POPULATE_WORKBOOK_DEFAULT_PERMISSIONS_XML) with requests_mock.mock() as m: - m.get(self.baseurl + '/9dbd2263-16b5-46e1-9c43-a76bb8ab65fb/default-permissions/workbooks', - text=response_xml) - single_project = TSC.ProjectItem('test', '1d0304cd-3796-429f-b815-7258370b9b74') - single_project._owner_id = 'dd2239f6-ddf1-4107-981a-4cf94e415794' - single_project._id = '9dbd2263-16b5-46e1-9c43-a76bb8ab65fb' + m.get( + self.baseurl + "/9dbd2263-16b5-46e1-9c43-a76bb8ab65fb/default-permissions/workbooks", text=response_xml + ) + single_project = TSC.ProjectItem("test", "1d0304cd-3796-429f-b815-7258370b9b74") + single_project._owner_id = "dd2239f6-ddf1-4107-981a-4cf94e415794" + single_project._id = "9dbd2263-16b5-46e1-9c43-a76bb8ab65fb" self.server.projects.populate_workbook_default_permissions(single_project) permissions = single_project.default_workbook_permissions rule1 = permissions.pop() - self.assertEqual('c8f2773a-c83a-11e8-8c8f-33e6d787b506', rule1.grantee.id) - self.assertEqual('group', rule1.grantee.tag_name) - self.assertDictEqual(rule1.capabilities, { - TSC.Permission.Capability.Write: TSC.Permission.Mode.Allow, - TSC.Permission.Capability.Read: TSC.Permission.Mode.Allow, - TSC.Permission.Capability.Filter: TSC.Permission.Mode.Allow, - TSC.Permission.Capability.ChangePermissions: TSC.Permission.Mode.Allow, - TSC.Permission.Capability.WebAuthoring: TSC.Permission.Mode.Allow, - TSC.Permission.Capability.ExportData: TSC.Permission.Mode.Allow, - TSC.Permission.Capability.ExportXml: TSC.Permission.Mode.Allow, - TSC.Permission.Capability.ExportImage: TSC.Permission.Mode.Allow, - TSC.Permission.Capability.Delete: TSC.Permission.Mode.Deny, - TSC.Permission.Capability.ShareView: TSC.Permission.Mode.Allow, - TSC.Permission.Capability.ViewUnderlyingData: TSC.Permission.Mode.Deny, - TSC.Permission.Capability.ViewComments: TSC.Permission.Mode.Allow, - TSC.Permission.Capability.AddComment: TSC.Permission.Mode.Allow, - TSC.Permission.Capability.ChangeHierarchy: TSC.Permission.Mode.Allow, - }) + self.assertEqual("c8f2773a-c83a-11e8-8c8f-33e6d787b506", rule1.grantee.id) + self.assertEqual("group", rule1.grantee.tag_name) + self.assertDictEqual( + rule1.capabilities, + { + TSC.Permission.Capability.Write: TSC.Permission.Mode.Allow, + TSC.Permission.Capability.Read: TSC.Permission.Mode.Allow, + TSC.Permission.Capability.Filter: TSC.Permission.Mode.Allow, + TSC.Permission.Capability.ChangePermissions: TSC.Permission.Mode.Allow, + TSC.Permission.Capability.WebAuthoring: TSC.Permission.Mode.Allow, + TSC.Permission.Capability.ExportData: TSC.Permission.Mode.Allow, + TSC.Permission.Capability.ExportXml: TSC.Permission.Mode.Allow, + TSC.Permission.Capability.ExportImage: TSC.Permission.Mode.Allow, + TSC.Permission.Capability.Delete: TSC.Permission.Mode.Deny, + TSC.Permission.Capability.ShareView: TSC.Permission.Mode.Allow, + TSC.Permission.Capability.ViewUnderlyingData: TSC.Permission.Mode.Deny, + TSC.Permission.Capability.ViewComments: TSC.Permission.Mode.Allow, + TSC.Permission.Capability.AddComment: TSC.Permission.Mode.Allow, + TSC.Permission.Capability.ChangeHierarchy: TSC.Permission.Mode.Allow, + }, + ) def test_delete_permission(self): - with open(asset(POPULATE_PERMISSIONS_XML), 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(asset(POPULATE_PERMISSIONS_XML), "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: - m.get(self.baseurl + '/0448d2ed-590d-4fa0-b272-a2a8a24555b5/permissions', text=response_xml) + m.get(self.baseurl + "/0448d2ed-590d-4fa0-b272-a2a8a24555b5/permissions", text=response_xml) - single_group = TSC.GroupItem('Group1') - single_group._id = 'c8f2773a-c83a-11e8-8c8f-33e6d787b506' + single_group = TSC.GroupItem("Group1") + single_group._id = "c8f2773a-c83a-11e8-8c8f-33e6d787b506" - single_project = TSC.ProjectItem('Project3') - single_project._id = '0448d2ed-590d-4fa0-b272-a2a8a24555b5' + single_project = TSC.ProjectItem("Project3") + single_project._id = "0448d2ed-590d-4fa0-b272-a2a8a24555b5" self.server.projects.populate_permissions(single_project) permissions = single_project.permissions @@ -226,30 +235,28 @@ def test_delete_permission(self): if permission.grantee.id == single_group._id: capabilities = permission.capabilities - rules = TSC.PermissionsRule( - grantee=single_group, - capabilities=capabilities - ) + rules = TSC.PermissionsRule(grantee=single_group, capabilities=capabilities) - endpoint = '{}/permissions/groups/{}'.format(single_project._id, single_group._id) - m.delete('{}/{}/Read/Allow'.format(self.baseurl, endpoint), status_code=204) - m.delete('{}/{}/Write/Allow'.format(self.baseurl, endpoint), status_code=204) + endpoint = "{}/permissions/groups/{}".format(single_project._id, single_group._id) + m.delete("{}/{}/Read/Allow".format(self.baseurl, endpoint), status_code=204) + m.delete("{}/{}/Write/Allow".format(self.baseurl, endpoint), status_code=204) self.server.projects.delete_permission(item=single_project, rules=rules) def test_delete_workbook_default_permission(self): - with open(asset(POPULATE_WORKBOOK_DEFAULT_PERMISSIONS_XML), 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(asset(POPULATE_WORKBOOK_DEFAULT_PERMISSIONS_XML), "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: - m.get(self.baseurl + '/9dbd2263-16b5-46e1-9c43-a76bb8ab65fb/default-permissions/workbooks', - text=response_xml) + m.get( + self.baseurl + "/9dbd2263-16b5-46e1-9c43-a76bb8ab65fb/default-permissions/workbooks", text=response_xml + ) - single_group = TSC.GroupItem('Group1') - single_group._id = 'c8f2773a-c83a-11e8-8c8f-33e6d787b506' + single_group = TSC.GroupItem("Group1") + single_group._id = "c8f2773a-c83a-11e8-8c8f-33e6d787b506" - single_project = TSC.ProjectItem('test', '1d0304cd-3796-429f-b815-7258370b9b74') - single_project._owner_id = 'dd2239f6-ddf1-4107-981a-4cf94e415794' - single_project._id = '9dbd2263-16b5-46e1-9c43-a76bb8ab65fb' + single_project = TSC.ProjectItem("test", "1d0304cd-3796-429f-b815-7258370b9b74") + single_project._owner_id = "dd2239f6-ddf1-4107-981a-4cf94e415794" + single_project._id = "9dbd2263-16b5-46e1-9c43-a76bb8ab65fb" self.server.projects.populate_workbook_default_permissions(single_project) permissions = single_project.default_workbook_permissions @@ -261,39 +268,34 @@ def test_delete_workbook_default_permission(self): TSC.Permission.Capability.ExportData: TSC.Permission.Mode.Allow, TSC.Permission.Capability.ViewComments: TSC.Permission.Mode.Allow, TSC.Permission.Capability.AddComment: TSC.Permission.Mode.Allow, - # Interact/Edit TSC.Permission.Capability.Filter: TSC.Permission.Mode.Allow, TSC.Permission.Capability.ViewUnderlyingData: TSC.Permission.Mode.Deny, TSC.Permission.Capability.ShareView: TSC.Permission.Mode.Allow, TSC.Permission.Capability.WebAuthoring: TSC.Permission.Mode.Allow, - # Edit TSC.Permission.Capability.Write: TSC.Permission.Mode.Allow, TSC.Permission.Capability.ExportXml: TSC.Permission.Mode.Allow, TSC.Permission.Capability.ChangeHierarchy: TSC.Permission.Mode.Allow, TSC.Permission.Capability.Delete: TSC.Permission.Mode.Deny, - TSC.Permission.Capability.ChangePermissions: TSC.Permission.Mode.Allow + TSC.Permission.Capability.ChangePermissions: TSC.Permission.Mode.Allow, } - rules = TSC.PermissionsRule( - grantee=single_group, - capabilities=capabilities - ) - - endpoint = '{}/default-permissions/workbooks/groups/{}'.format(single_project._id, single_group._id) - m.delete('{}/{}/Read/Allow'.format(self.baseurl, endpoint), status_code=204) - m.delete('{}/{}/ExportImage/Allow'.format(self.baseurl, endpoint), status_code=204) - m.delete('{}/{}/ExportData/Allow'.format(self.baseurl, endpoint), status_code=204) - m.delete('{}/{}/ViewComments/Allow'.format(self.baseurl, endpoint), status_code=204) - m.delete('{}/{}/AddComment/Allow'.format(self.baseurl, endpoint), status_code=204) - m.delete('{}/{}/Filter/Allow'.format(self.baseurl, endpoint), status_code=204) - m.delete('{}/{}/ViewUnderlyingData/Deny'.format(self.baseurl, endpoint), status_code=204) - m.delete('{}/{}/ShareView/Allow'.format(self.baseurl, endpoint), status_code=204) - m.delete('{}/{}/WebAuthoring/Allow'.format(self.baseurl, endpoint), status_code=204) - m.delete('{}/{}/Write/Allow'.format(self.baseurl, endpoint), status_code=204) - m.delete('{}/{}/ExportXml/Allow'.format(self.baseurl, endpoint), status_code=204) - m.delete('{}/{}/ChangeHierarchy/Allow'.format(self.baseurl, endpoint), status_code=204) - m.delete('{}/{}/Delete/Deny'.format(self.baseurl, endpoint), status_code=204) - m.delete('{}/{}/ChangePermissions/Allow'.format(self.baseurl, endpoint), status_code=204) + rules = TSC.PermissionsRule(grantee=single_group, capabilities=capabilities) + + endpoint = "{}/default-permissions/workbooks/groups/{}".format(single_project._id, single_group._id) + m.delete("{}/{}/Read/Allow".format(self.baseurl, endpoint), status_code=204) + m.delete("{}/{}/ExportImage/Allow".format(self.baseurl, endpoint), status_code=204) + m.delete("{}/{}/ExportData/Allow".format(self.baseurl, endpoint), status_code=204) + m.delete("{}/{}/ViewComments/Allow".format(self.baseurl, endpoint), status_code=204) + m.delete("{}/{}/AddComment/Allow".format(self.baseurl, endpoint), status_code=204) + m.delete("{}/{}/Filter/Allow".format(self.baseurl, endpoint), status_code=204) + m.delete("{}/{}/ViewUnderlyingData/Deny".format(self.baseurl, endpoint), status_code=204) + m.delete("{}/{}/ShareView/Allow".format(self.baseurl, endpoint), status_code=204) + m.delete("{}/{}/WebAuthoring/Allow".format(self.baseurl, endpoint), status_code=204) + m.delete("{}/{}/Write/Allow".format(self.baseurl, endpoint), status_code=204) + m.delete("{}/{}/ExportXml/Allow".format(self.baseurl, endpoint), status_code=204) + m.delete("{}/{}/ChangeHierarchy/Allow".format(self.baseurl, endpoint), status_code=204) + m.delete("{}/{}/Delete/Deny".format(self.baseurl, endpoint), status_code=204) + m.delete("{}/{}/ChangePermissions/Allow".format(self.baseurl, endpoint), status_code=204) self.server.projects.delete_workbook_default_permissions(item=single_project, rule=rules) diff --git a/test/test_regression_tests.py b/test/test_regression_tests.py index 52ea03b92..76803c843 100644 --- a/test/test_regression_tests.py +++ b/test/test_regression_tests.py @@ -13,51 +13,50 @@ class BugFix257(unittest.TestCase): def test_empty_request_works(self): result = factory.EmptyRequest().empty_req() - self.assertEqual(b'', result) + self.assertEqual(b"", result) class BugFix273(unittest.TestCase): def test_binary_log_truncated(self): - class FakeResponse(object): - headers = {'Content-Type': 'application/octet-stream'} - content = b'\x1337' * 1000 + headers = {"Content-Type": "application/octet-stream"} + content = b"\x1337" * 1000 status_code = 200 server_response = FakeResponse() - self.assertEqual(Endpoint._safe_to_log(server_response), '[Truncated File Contents]') + self.assertEqual(Endpoint._safe_to_log(server_response), "[Truncated File Contents]") class FileSysHelpers(unittest.TestCase): def test_to_filename(self): invalid = [ "23brhafbjrjhkbbea.txt", - 'a_b_C.txt', - 'windows space.txt', - 'abc#def.txt', - 't@bL3A()', + "a_b_C.txt", + "windows space.txt", + "abc#def.txt", + "t@bL3A()", ] valid = [ "23brhafbjrjhkbbea.txt", - 'a_b_C.txt', - 'windows space.txt', - 'abcdef.txt', - 'tbL3A', + "a_b_C.txt", + "windows space.txt", + "abcdef.txt", + "tbL3A", ] self.assertTrue(all([(to_filename(i) == v) for i, v in zip(invalid, valid)])) def test_make_download_path(self): - no_file_path = (None, 'file.ext') - has_file_path_folder = ('/root/folder/', 'file.ext') - has_file_path_file = ('out', 'file.ext') + no_file_path = (None, "file.ext") + has_file_path_folder = ("/root/folder/", "file.ext") + has_file_path_file = ("out", "file.ext") - self.assertEqual('file.ext', make_download_path(*no_file_path)) - self.assertEqual('out.ext', make_download_path(*has_file_path_file)) + self.assertEqual("file.ext", make_download_path(*no_file_path)) + self.assertEqual("out.ext", make_download_path(*has_file_path_file)) - with mock.patch('os.path.isdir') as mocked_isdir: + with mock.patch("os.path.isdir") as mocked_isdir: mocked_isdir.return_value = True - self.assertEqual('/root/folder/file.ext', make_download_path(*has_file_path_folder)) + self.assertEqual("/root/folder/file.ext", make_download_path(*has_file_path_folder)) diff --git a/test/test_request_option.py b/test/test_request_option.py index 37b4fc945..fba1e0f68 100644 --- a/test/test_request_option.py +++ b/test/test_request_option.py @@ -5,32 +5,32 @@ import requests_mock import tableauserverclient as TSC -TEST_ASSET_DIR = os.path.join(os.path.dirname(__file__), 'assets') +TEST_ASSET_DIR = os.path.join(os.path.dirname(__file__), "assets") -PAGINATION_XML = os.path.join(TEST_ASSET_DIR, 'request_option_pagination.xml') -PAGE_NUMBER_XML = os.path.join(TEST_ASSET_DIR, 'request_option_page_number.xml') -PAGE_SIZE_XML = os.path.join(TEST_ASSET_DIR, 'request_option_page_size.xml') -FILTER_EQUALS = os.path.join(TEST_ASSET_DIR, 'request_option_filter_equals.xml') -FILTER_TAGS_IN = os.path.join(TEST_ASSET_DIR, 'request_option_filter_tags_in.xml') -FILTER_MULTIPLE = os.path.join(TEST_ASSET_DIR, 'request_option_filter_tags_in.xml') +PAGINATION_XML = os.path.join(TEST_ASSET_DIR, "request_option_pagination.xml") +PAGE_NUMBER_XML = os.path.join(TEST_ASSET_DIR, "request_option_page_number.xml") +PAGE_SIZE_XML = os.path.join(TEST_ASSET_DIR, "request_option_page_size.xml") +FILTER_EQUALS = os.path.join(TEST_ASSET_DIR, "request_option_filter_equals.xml") +FILTER_TAGS_IN = os.path.join(TEST_ASSET_DIR, "request_option_filter_tags_in.xml") +FILTER_MULTIPLE = os.path.join(TEST_ASSET_DIR, "request_option_filter_tags_in.xml") class RequestOptionTests(unittest.TestCase): def setUp(self): - self.server = TSC.Server('http://test') + self.server = TSC.Server("http://test") # Fake signin self.server.version = "3.10" - self.server._site_id = 'dad65087-b08b-4603-af4e-2887b8aafc67' - self.server._auth_token = 'j80k54ll2lfMZ0tv97mlPvvSCRyD0DOM' + self.server._site_id = "dad65087-b08b-4603-af4e-2887b8aafc67" + self.server._auth_token = "j80k54ll2lfMZ0tv97mlPvvSCRyD0DOM" - self.baseurl = '{0}/{1}'.format(self.server.sites.baseurl, self.server._site_id) + self.baseurl = "{0}/{1}".format(self.server.sites.baseurl, self.server._site_id) def test_pagination(self): - with open(PAGINATION_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(PAGINATION_XML, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: - m.get(self.baseurl + '/views?pageNumber=1&pageSize=10', text=response_xml) + m.get(self.baseurl + "/views?pageNumber=1&pageSize=10", text=response_xml) req_option = TSC.RequestOptions().page_size(10) all_views, pagination_item = self.server.views.get(req_option) @@ -40,10 +40,10 @@ def test_pagination(self): self.assertEqual(10, len(all_views)) def test_page_number(self): - with open(PAGE_NUMBER_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(PAGE_NUMBER_XML, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: - m.get(self.baseurl + '/views?pageNumber=3', text=response_xml) + m.get(self.baseurl + "/views?pageNumber=3", text=response_xml) req_option = TSC.RequestOptions().page_number(3) all_views, pagination_item = self.server.views.get(req_option) @@ -53,10 +53,10 @@ def test_page_number(self): self.assertEqual(10, len(all_views)) def test_page_size(self): - with open(PAGE_SIZE_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(PAGE_SIZE_XML, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: - m.get(self.baseurl + '/views?pageSize=5', text=response_xml) + m.get(self.baseurl + "/views?pageSize=5", text=response_xml) req_option = TSC.RequestOptions().page_size(5) all_views, pagination_item = self.server.views.get(req_option) @@ -66,74 +66,86 @@ def test_page_size(self): self.assertEqual(5, len(all_views)) def test_filter_equals(self): - with open(FILTER_EQUALS, 'rb') as f: - response_xml = f.read().decode('utf-8') + 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) + 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')) + 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) + self.assertEqual("RESTAPISample", matching_workbooks[0].name) + self.assertEqual("RESTAPISample", matching_workbooks[1].name) def test_filter_equals_shorthand(self): - with open(FILTER_EQUALS, 'rb') as f: - response_xml = f.read().decode('utf-8') + 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) - matching_workbooks = self.server.workbooks.filter(name='RESTAPISample').order_by("name") + m.get(self.baseurl + "/workbooks?filter=name:eq:RESTAPISample", text=response_xml) + matching_workbooks = self.server.workbooks.filter(name="RESTAPISample").order_by("name") self.assertEqual(2, matching_workbooks.total_available) - self.assertEqual('RESTAPISample', matching_workbooks[0].name) - self.assertEqual('RESTAPISample', matching_workbooks[1].name) + self.assertEqual("RESTAPISample", matching_workbooks[0].name) + self.assertEqual("RESTAPISample", matching_workbooks[1].name) def test_filter_tags_in(self): - with open(FILTER_TAGS_IN, 'rb') as f: - response_xml = f.read().decode('utf-8') + 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) + 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'])) + 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) + 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_shorthand(self): - with open(FILTER_TAGS_IN, 'rb') as f: - response_xml = f.read().decode('utf-8') + 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) - matching_workbooks = self.server.workbooks.filter(tags__in=['sample', 'safari', 'weather']) + m.get(self.baseurl + "/workbooks?filter=tags:in:[sample,safari,weather]", text=response_xml) + matching_workbooks = self.server.workbooks.filter(tags__in=["sample", "safari", "weather"]) self.assertEqual(3, matching_workbooks.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) + 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_invalid_shorthand_option(self): with self.assertRaises(ValueError): - self.server.workbooks.filter(nonexistant__in=['sample', 'safari']) + self.server.workbooks.filter(nonexistant__in=["sample", "safari"]) def test_multiple_filter_options(self): - with open(FILTER_MULTIPLE, 'rb') as f: - response_xml = f.read().decode('utf-8') + 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]')) + 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')) + 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) @@ -145,16 +157,15 @@ def test_double_query_params(self): 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)) + 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)) + 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)) # Test req_options for versions below 3.7 def test_filter_sort_legacy(self): @@ -164,16 +175,15 @@ def test_filter_sort_legacy(self): 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)) + 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:in:%5bstocks,market%5d', resp.request.query)) - self.assertTrue(re.search('sort=name:asc', resp.request.query)) + self.assertTrue(re.search("queryparamexists=true", resp.request.query)) + self.assertTrue(re.search("filter=tags:in:%5bstocks,market%5d", resp.request.query)) + self.assertTrue(re.search("sort=name:asc", resp.request.query)) def test_vf(self): with requests_mock.mock() as m: @@ -185,9 +195,9 @@ def test_vf(self): opts.page_type = TSC.PDFRequestOptions.PageType.Tabloid resp = self.server.workbooks.get_request(url, request_object=opts) - self.assertTrue(re.search('vf_name1%23=value1', resp.request.query)) - self.assertTrue(re.search('vf_name2%24=value2', resp.request.query)) - self.assertTrue(re.search('type=tabloid', resp.request.query)) + self.assertTrue(re.search("vf_name1%23=value1", resp.request.query)) + self.assertTrue(re.search("vf_name2%24=value2", resp.request.query)) + self.assertTrue(re.search("type=tabloid", resp.request.query)) # Test req_options for versions beloe 3.7 def test_vf_legacy(self): @@ -201,9 +211,9 @@ def test_vf_legacy(self): opts.page_type = TSC.PDFRequestOptions.PageType.Tabloid resp = self.server.workbooks.get_request(url, request_object=opts) - self.assertTrue(re.search('vf_name1@=value1', resp.request.query)) - self.assertTrue(re.search('vf_name2\\$=value2', resp.request.query)) - self.assertTrue(re.search('type=tabloid', resp.request.query)) + self.assertTrue(re.search("vf_name1@=value1", resp.request.query)) + self.assertTrue(re.search("vf_name2\\$=value2", resp.request.query)) + self.assertTrue(re.search("type=tabloid", resp.request.query)) def test_all_fields(self): with requests_mock.mock() as m: @@ -213,20 +223,23 @@ def test_all_fields(self): opts._all_fields = True resp = self.server.users.get_request(url, request_object=opts) - self.assertTrue(re.search('fields=_all_', resp.request.query)) + self.assertTrue(re.search("fields=_all_", resp.request.query)) def test_multiple_filter_options_shorthand(self): - with open(FILTER_MULTIPLE, 'rb') as f: - response_xml = f.read().decode('utf-8') + 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]')) + url = "".join( + ( + self.baseurl, + "/workbooks?pageNumber=1&pageSize=100&", + "filter=name:eq:foo,tags:in:[sample,safari,weather]", + ) + ) m.get(url, text=response_xml) for _ in range(100): - matching_workbooks = self.server.workbooks.filter( - tags__in=['sample', 'safari', 'weather'], name='foo' - ) + matching_workbooks = self.server.workbooks.filter(tags__in=["sample", "safari", "weather"], name="foo") self.assertEqual(3, matching_workbooks.total_available) diff --git a/test/test_requests.py b/test/test_requests.py index 2976e8f3e..d9dfc3ea2 100644 --- a/test/test_requests.py +++ b/test/test_requests.py @@ -10,11 +10,11 @@ class RequestTests(unittest.TestCase): def setUp(self): - self.server = TSC.Server('http://test') + self.server = TSC.Server("http://test") # Fake sign in - self.server._site_id = 'dad65087-b08b-4603-af4e-2887b8aafc67' - self.server._auth_token = 'j80k54ll2lfMZ0tv97mlPvvSCRyD0DOM' + self.server._site_id = "dad65087-b08b-4603-af4e-2887b8aafc67" + self.server._auth_token = "j80k54ll2lfMZ0tv97mlPvvSCRyD0DOM" self.baseurl = self.server.workbooks.baseurl @@ -25,26 +25,30 @@ def test_make_get_request(self): opts = TSC.RequestOptions(pagesize=13, pagenumber=15) resp = self.server.workbooks.get_request(url, request_object=opts) - self.assertTrue(re.search('pagesize=13', resp.request.query)) - self.assertTrue(re.search('pagenumber=15', resp.request.query)) + self.assertTrue(re.search("pagesize=13", resp.request.query)) + self.assertTrue(re.search("pagenumber=15", resp.request.query)) def test_make_post_request(self): with requests_mock.mock() as m: m.post(requests_mock.ANY) url = "http://test/api/2.3/sites/dad65087-b08b-4603-af4e-2887b8aafc67/workbooks" - resp = self.server.workbooks._make_request(requests.post, url, content=b'1337', - auth_token='j80k54ll2lfMZ0tv97mlPvvSCRyD0DOM', - content_type='multipart/mixed') - self.assertEqual(resp.request.headers['x-tableau-auth'], 'j80k54ll2lfMZ0tv97mlPvvSCRyD0DOM') - self.assertEqual(resp.request.headers['content-type'], 'multipart/mixed') - self.assertEqual(resp.request.body, b'1337') + resp = self.server.workbooks._make_request( + requests.post, + url, + content=b"1337", + auth_token="j80k54ll2lfMZ0tv97mlPvvSCRyD0DOM", + content_type="multipart/mixed", + ) + self.assertEqual(resp.request.headers["x-tableau-auth"], "j80k54ll2lfMZ0tv97mlPvvSCRyD0DOM") + self.assertEqual(resp.request.headers["content-type"], "multipart/mixed") + self.assertEqual(resp.request.body, b"1337") # Test that 500 server errors are handled properly def test_internal_server_error(self): self.server.version = "3.2" server_response = "500: Internal Server Error" with requests_mock.mock() as m: - m.register_uri('GET', self.server.server_info.baseurl, status_code=500, text=server_response) + m.register_uri("GET", self.server.server_info.baseurl, status_code=500, text=server_response) self.assertRaisesRegex(InternalServerError, server_response, self.server.server_info.get) # Test that non-xml server errors are handled properly @@ -52,5 +56,5 @@ def test_non_xml_error(self): self.server.version = "3.2" server_response = "this is not xml" with requests_mock.mock() as m: - m.register_uri('GET', self.server.server_info.baseurl, status_code=499, text=server_response) + m.register_uri("GET", self.server.server_info.baseurl, status_code=499, text=server_response) self.assertRaisesRegex(NonXMLResponseError, server_response, self.server.server_info.get) diff --git a/test/test_schedule.py b/test/test_schedule.py index 2302f6139..078097941 100644 --- a/test/test_schedule.py +++ b/test/test_schedule.py @@ -18,8 +18,8 @@ ADD_WORKBOOK_TO_SCHEDULE_WITH_WARNINGS = os.path.join(TEST_ASSET_DIR, "schedule_add_workbook_with_warnings.xml") ADD_DATASOURCE_TO_SCHEDULE = os.path.join(TEST_ASSET_DIR, "schedule_add_datasource.xml") -WORKBOOK_GET_BY_ID_XML = os.path.join(TEST_ASSET_DIR, 'workbook_get_by_id.xml') -DATASOURCE_GET_BY_ID_XML = os.path.join(TEST_ASSET_DIR, 'datasource_get_by_id.xml') +WORKBOOK_GET_BY_ID_XML = os.path.join(TEST_ASSET_DIR, "workbook_get_by_id.xml") +DATASOURCE_GET_BY_ID_XML = os.path.join(TEST_ASSET_DIR, "datasource_get_by_id.xml") class ScheduleTests(unittest.TestCase): @@ -91,11 +91,14 @@ def test_create_hourly(self) -> None: response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: m.post(self.baseurl, text=response_xml) - hourly_interval = TSC.HourlyInterval(start_time=time(2, 30), - end_time=time(23, 0), - interval_value=2) - new_schedule = TSC.ScheduleItem("hourly-schedule-1", 50, TSC.ScheduleItem.Type.Extract, - TSC.ScheduleItem.ExecutionOrder.Parallel, hourly_interval) + hourly_interval = TSC.HourlyInterval(start_time=time(2, 30), end_time=time(23, 0), interval_value=2) + new_schedule = TSC.ScheduleItem( + "hourly-schedule-1", + 50, + TSC.ScheduleItem.Type.Extract, + TSC.ScheduleItem.ExecutionOrder.Parallel, + hourly_interval, + ) new_schedule = self.server.schedules.create(new_schedule) self.assertEqual("5f42be25-8a43-47ba-971a-63f2d4e7029c", new_schedule.id) @@ -117,8 +120,13 @@ def test_create_daily(self) -> None: with requests_mock.mock() as m: m.post(self.baseurl, text=response_xml) daily_interval = TSC.DailyInterval(time(4, 50)) - new_schedule = TSC.ScheduleItem("daily-schedule-1", 90, TSC.ScheduleItem.Type.Subscription, - TSC.ScheduleItem.ExecutionOrder.Serial, daily_interval) + new_schedule = TSC.ScheduleItem( + "daily-schedule-1", + 90, + TSC.ScheduleItem.Type.Subscription, + TSC.ScheduleItem.ExecutionOrder.Serial, + daily_interval, + ) new_schedule = self.server.schedules.create(new_schedule) self.assertEqual("907cae38-72fd-417c-892a-95540c4664cd", new_schedule.id) @@ -137,11 +145,16 @@ def test_create_weekly(self) -> None: response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: m.post(self.baseurl, text=response_xml) - weekly_interval = TSC.WeeklyInterval(time(9, 15), TSC.IntervalItem.Day.Monday, - TSC.IntervalItem.Day.Wednesday, - TSC.IntervalItem.Day.Friday) - new_schedule = TSC.ScheduleItem("weekly-schedule-1", 80, TSC.ScheduleItem.Type.Extract, - TSC.ScheduleItem.ExecutionOrder.Parallel, weekly_interval) + weekly_interval = TSC.WeeklyInterval( + time(9, 15), TSC.IntervalItem.Day.Monday, TSC.IntervalItem.Day.Wednesday, TSC.IntervalItem.Day.Friday + ) + new_schedule = TSC.ScheduleItem( + "weekly-schedule-1", + 80, + TSC.ScheduleItem.Type.Extract, + TSC.ScheduleItem.ExecutionOrder.Parallel, + weekly_interval, + ) new_schedule = self.server.schedules.create(new_schedule) self.assertEqual("1adff386-6be0-4958-9f81-a35e676932bf", new_schedule.id) @@ -166,8 +179,13 @@ def test_create_monthly(self) -> None: with requests_mock.mock() as m: m.post(self.baseurl, text=response_xml) monthly_interval = TSC.MonthlyInterval(time(7), 12) - new_schedule = TSC.ScheduleItem("monthly-schedule-1", 20, TSC.ScheduleItem.Type.Extract, - TSC.ScheduleItem.ExecutionOrder.Serial, monthly_interval) + new_schedule = TSC.ScheduleItem( + "monthly-schedule-1", + 20, + TSC.ScheduleItem.Type.Extract, + TSC.ScheduleItem.ExecutionOrder.Serial, + monthly_interval, + ) new_schedule = self.server.schedules.create(new_schedule) self.assertEqual("e06a7c75-5576-4f68-882d-8909d0219326", new_schedule.id) @@ -186,11 +204,15 @@ def test_update(self) -> None: with open(UPDATE_XML, "rb") as f: response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: - m.put(self.baseurl + '/7bea1766-1543-4052-9753-9d224bc069b5', text=response_xml) - new_interval = TSC.WeeklyInterval(time(7), TSC.IntervalItem.Day.Monday, - TSC.IntervalItem.Day.Friday) - single_schedule = TSC.ScheduleItem("weekly-schedule-1", 90, TSC.ScheduleItem.Type.Extract, - TSC.ScheduleItem.ExecutionOrder.Parallel, new_interval) + m.put(self.baseurl + "/7bea1766-1543-4052-9753-9d224bc069b5", text=response_xml) + new_interval = TSC.WeeklyInterval(time(7), TSC.IntervalItem.Day.Monday, TSC.IntervalItem.Day.Friday) + single_schedule = TSC.ScheduleItem( + "weekly-schedule-1", + 90, + TSC.ScheduleItem.Type.Extract, + TSC.ScheduleItem.ExecutionOrder.Parallel, + new_interval, + ) single_schedule._id = "7bea1766-1543-4052-9753-9d224bc069b5" single_schedule.state = TSC.ScheduleItem.State.Suspended single_schedule = self.server.schedules.update(single_schedule) @@ -220,17 +242,17 @@ def test_update_after_get(self) -> None: all_schedules, pagination_item = self.server.schedules.get() schedule_item = all_schedules[0] self.assertEqual(TSC.ScheduleItem.State.Active, schedule_item.state) - self.assertEqual('Weekday early mornings', schedule_item.name) + self.assertEqual("Weekday early mornings", schedule_item.name) # Update the schedule with requests_mock.mock() as m: - m.put(self.baseurl + '/c9cff7f9-309c-4361-99ff-d4ba8c9f5467', text=update_response_xml) + m.put(self.baseurl + "/c9cff7f9-309c-4361-99ff-d4ba8c9f5467", text=update_response_xml) schedule_item.state = TSC.ScheduleItem.State.Suspended - schedule_item.name = 'newName' + schedule_item.name = "newName" schedule_item = self.server.schedules.update(schedule_item) self.assertEqual(TSC.ScheduleItem.State.Suspended, schedule_item.state) - self.assertEqual('weekly-schedule-1', schedule_item.name) + self.assertEqual("weekly-schedule-1", schedule_item.name) def test_add_workbook(self) -> None: self.server.version = "2.8" @@ -241,10 +263,10 @@ def test_add_workbook(self) -> None: with open(ADD_WORKBOOK_TO_SCHEDULE, "rb") as f: add_workbook_response = f.read().decode("utf-8") with requests_mock.mock() as m: - m.get(self.server.workbooks.baseurl + '/bar', text=workbook_response) - m.put(baseurl + '/foo/workbooks', text=add_workbook_response) + m.get(self.server.workbooks.baseurl + "/bar", text=workbook_response) + m.put(baseurl + "/foo/workbooks", text=add_workbook_response) workbook = self.server.workbooks.get_by_id("bar") - result = self.server.schedules.add_to_schedule('foo', workbook=workbook) + result = self.server.schedules.add_to_schedule("foo", workbook=workbook) self.assertEqual(0, len(result), "Added properly") def test_add_workbook_with_warnings(self) -> None: @@ -256,10 +278,10 @@ def test_add_workbook_with_warnings(self) -> None: with open(ADD_WORKBOOK_TO_SCHEDULE_WITH_WARNINGS, "rb") as f: add_workbook_response = f.read().decode("utf-8") with requests_mock.mock() as m: - m.get(self.server.workbooks.baseurl + '/bar', text=workbook_response) - m.put(baseurl + '/foo/workbooks', text=add_workbook_response) + m.get(self.server.workbooks.baseurl + "/bar", text=workbook_response) + m.put(baseurl + "/foo/workbooks", text=add_workbook_response) workbook = self.server.workbooks.get_by_id("bar") - result = self.server.schedules.add_to_schedule('foo', workbook=workbook) + result = self.server.schedules.add_to_schedule("foo", workbook=workbook) self.assertEqual(1, len(result), "Not added properly") self.assertEqual(2, len(result[0].warnings)) @@ -272,8 +294,8 @@ def test_add_datasource(self) -> None: with open(ADD_DATASOURCE_TO_SCHEDULE, "rb") as f: add_datasource_response = f.read().decode("utf-8") with requests_mock.mock() as m: - m.get(self.server.datasources.baseurl + '/bar', text=datasource_response) - m.put(baseurl + '/foo/datasources', text=add_datasource_response) + m.get(self.server.datasources.baseurl + "/bar", text=datasource_response) + m.put(baseurl + "/foo/datasources", text=add_datasource_response) datasource = self.server.datasources.get_by_id("bar") - result = self.server.schedules.add_to_schedule('foo', datasource=datasource) + result = self.server.schedules.add_to_schedule("foo", datasource=datasource) self.assertEqual(0, len(result), "Added properly") diff --git a/test/test_server_info.py b/test/test_server_info.py index 3dadff7c1..08565f6d5 100644 --- a/test/test_server_info.py +++ b/test/test_server_info.py @@ -3,60 +3,60 @@ import requests_mock import tableauserverclient as TSC -TEST_ASSET_DIR = os.path.join(os.path.dirname(__file__), 'assets') +TEST_ASSET_DIR = os.path.join(os.path.dirname(__file__), "assets") -SERVER_INFO_GET_XML = os.path.join(TEST_ASSET_DIR, 'server_info_get.xml') -SERVER_INFO_25_XML = os.path.join(TEST_ASSET_DIR, 'server_info_25.xml') -SERVER_INFO_404 = os.path.join(TEST_ASSET_DIR, 'server_info_404.xml') -SERVER_INFO_AUTH_INFO_XML = os.path.join(TEST_ASSET_DIR, 'server_info_auth_info.xml') +SERVER_INFO_GET_XML = os.path.join(TEST_ASSET_DIR, "server_info_get.xml") +SERVER_INFO_25_XML = os.path.join(TEST_ASSET_DIR, "server_info_25.xml") +SERVER_INFO_404 = os.path.join(TEST_ASSET_DIR, "server_info_404.xml") +SERVER_INFO_AUTH_INFO_XML = os.path.join(TEST_ASSET_DIR, "server_info_auth_info.xml") class ServerInfoTests(unittest.TestCase): def setUp(self): - self.server = TSC.Server('http://test') + self.server = TSC.Server("http://test") self.baseurl = self.server.server_info.baseurl self.server.version = "2.4" def test_server_info_get(self): - with open(SERVER_INFO_GET_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(SERVER_INFO_GET_XML, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: m.get(self.server.server_info.baseurl, text=response_xml) actual = self.server.server_info.get() - self.assertEqual('10.1.0', actual.product_version) - self.assertEqual('10100.16.1024.2100', actual.build_number) - self.assertEqual('2.4', actual.rest_api_version) + self.assertEqual("10.1.0", actual.product_version) + self.assertEqual("10100.16.1024.2100", actual.build_number) + self.assertEqual("2.4", actual.rest_api_version) def test_server_info_use_highest_version_downgrades(self): - with open(SERVER_INFO_AUTH_INFO_XML, 'rb') as f: + with open(SERVER_INFO_AUTH_INFO_XML, "rb") as f: # This is the auth.xml endpoint present back to 9.0 Servers - auth_response_xml = f.read().decode('utf-8') - with open(SERVER_INFO_404, 'rb') as f: + auth_response_xml = f.read().decode("utf-8") + with open(SERVER_INFO_404, "rb") as f: # 10.1 serverInfo response - si_response_xml = f.read().decode('utf-8') + si_response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: # Return a 404 for serverInfo so we can pretend this is an old Server m.get(self.server.server_address + "/api/2.4/serverInfo", text=si_response_xml, status_code=404) m.get(self.server.server_address + "/auth?format=xml", text=auth_response_xml) self.server.use_server_version() - self.assertEqual(self.server.version, '2.2') + self.assertEqual(self.server.version, "2.2") def test_server_info_use_highest_version_upgrades(self): - with open(SERVER_INFO_GET_XML, 'rb') as f: - si_response_xml = f.read().decode('utf-8') + with open(SERVER_INFO_GET_XML, "rb") as f: + si_response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: m.get(self.server.server_address + "/api/2.4/serverInfo", text=si_response_xml) # Pretend we're old - self.server.version = '2.0' + self.server.version = "2.0" self.server.use_server_version() # Did we upgrade to 2.4? - self.assertEqual(self.server.version, '2.4') + self.assertEqual(self.server.version, "2.4") def test_server_use_server_version_flag(self): - with open(SERVER_INFO_25_XML, 'rb') as f: - si_response_xml = f.read().decode('utf-8') + with open(SERVER_INFO_25_XML, "rb") as f: + si_response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: - m.get('http://test/api/2.4/serverInfo', text=si_response_xml) - server = TSC.Server('http://test', use_server_version=True) - self.assertEqual(server.version, '2.5') + m.get("http://test/api/2.4/serverInfo", text=si_response_xml) + server = TSC.Server("http://test", use_server_version=True) + self.assertEqual(server.version, "2.5") diff --git a/test/test_site.py b/test/test_site.py index 8fbb4eda3..b8cb5bbfd 100644 --- a/test/test_site.py +++ b/test/test_site.py @@ -3,37 +3,37 @@ import requests_mock import tableauserverclient as TSC -TEST_ASSET_DIR = os.path.join(os.path.dirname(__file__), 'assets') +TEST_ASSET_DIR = os.path.join(os.path.dirname(__file__), "assets") -GET_XML = os.path.join(TEST_ASSET_DIR, 'site_get.xml') -GET_BY_ID_XML = os.path.join(TEST_ASSET_DIR, 'site_get_by_id.xml') -GET_BY_NAME_XML = os.path.join(TEST_ASSET_DIR, 'site_get_by_name.xml') -UPDATE_XML = os.path.join(TEST_ASSET_DIR, 'site_update.xml') -CREATE_XML = os.path.join(TEST_ASSET_DIR, 'site_create.xml') +GET_XML = os.path.join(TEST_ASSET_DIR, "site_get.xml") +GET_BY_ID_XML = os.path.join(TEST_ASSET_DIR, "site_get_by_id.xml") +GET_BY_NAME_XML = os.path.join(TEST_ASSET_DIR, "site_get_by_name.xml") +UPDATE_XML = os.path.join(TEST_ASSET_DIR, "site_update.xml") +CREATE_XML = os.path.join(TEST_ASSET_DIR, "site_create.xml") class SiteTests(unittest.TestCase): def setUp(self): - self.server = TSC.Server('http://test') + self.server = TSC.Server("http://test") self.server.version = "3.10" # Fake signin - self.server._auth_token = 'j80k54ll2lfMZ0tv97mlPvvSCRyD0DOM' - self.server._site_id = '0626857c-1def-4503-a7d8-7907c3ff9d9f' + self.server._auth_token = "j80k54ll2lfMZ0tv97mlPvvSCRyD0DOM" + self.server._site_id = "0626857c-1def-4503-a7d8-7907c3ff9d9f" self.baseurl = self.server.sites.baseurl def test_get(self): - with open(GET_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(GET_XML, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: m.get(self.baseurl, text=response_xml) all_sites, pagination_item = self.server.sites.get() self.assertEqual(2, pagination_item.total_available) - self.assertEqual('dad65087-b08b-4603-af4e-2887b8aafc67', all_sites[0].id) - self.assertEqual('Active', all_sites[0].state) - self.assertEqual('Default', all_sites[0].name) - self.assertEqual('ContentOnly', all_sites[0].admin_mode) + self.assertEqual("dad65087-b08b-4603-af4e-2887b8aafc67", all_sites[0].id) + self.assertEqual("Active", all_sites[0].state) + self.assertEqual("Default", all_sites[0].name) + self.assertEqual("ContentOnly", all_sites[0].admin_mode) self.assertEqual(False, all_sites[0].revision_history_enabled) self.assertEqual(True, all_sites[0].subscribe_others_enabled) self.assertEqual(25, all_sites[0].revision_limit) @@ -43,10 +43,10 @@ def test_get(self): self.assertEqual(False, all_sites[0].editing_flows_enabled) self.assertEqual(False, all_sites[0].scheduling_flows_enabled) self.assertEqual(True, all_sites[0].allow_subscription_attachments) - self.assertEqual('6b7179ba-b82b-4f0f-91ed-812074ac5da6', all_sites[1].id) - self.assertEqual('Active', all_sites[1].state) - self.assertEqual('Samples', all_sites[1].name) - self.assertEqual('ContentOnly', all_sites[1].admin_mode) + self.assertEqual("6b7179ba-b82b-4f0f-91ed-812074ac5da6", all_sites[1].id) + self.assertEqual("Active", all_sites[1].state) + self.assertEqual("Samples", all_sites[1].name) + self.assertEqual("ContentOnly", all_sites[1].admin_mode) self.assertEqual(False, all_sites[1].revision_history_enabled) self.assertEqual(True, all_sites[1].subscribe_others_enabled) self.assertEqual(False, all_sites[1].guest_access_enabled) @@ -66,16 +66,16 @@ def test_get_before_signin(self): self.assertRaises(TSC.NotSignedInError, self.server.sites.get) def test_get_by_id(self): - with open(GET_BY_ID_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(GET_BY_ID_XML, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: - m.get(self.baseurl + '/dad65087-b08b-4603-af4e-2887b8aafc67', text=response_xml) - single_site = self.server.sites.get_by_id('dad65087-b08b-4603-af4e-2887b8aafc67') + m.get(self.baseurl + "/dad65087-b08b-4603-af4e-2887b8aafc67", text=response_xml) + single_site = self.server.sites.get_by_id("dad65087-b08b-4603-af4e-2887b8aafc67") - self.assertEqual('dad65087-b08b-4603-af4e-2887b8aafc67', single_site.id) - self.assertEqual('Active', single_site.state) - self.assertEqual('Default', single_site.name) - self.assertEqual('ContentOnly', single_site.admin_mode) + self.assertEqual("dad65087-b08b-4603-af4e-2887b8aafc67", single_site.id) + self.assertEqual("Active", single_site.state) + self.assertEqual("Default", single_site.name) + self.assertEqual("ContentOnly", single_site.admin_mode) self.assertEqual(False, single_site.revision_history_enabled) self.assertEqual(True, single_site.subscribe_others_enabled) self.assertEqual(False, single_site.disable_subscriptions) @@ -84,60 +84,73 @@ def test_get_by_id(self): self.assertEqual(True, single_site.catalog_obfuscation_enabled) def test_get_by_id_missing_id(self): - self.assertRaises(ValueError, self.server.sites.get_by_id, '') + self.assertRaises(ValueError, self.server.sites.get_by_id, "") def test_get_by_name(self): - with open(GET_BY_NAME_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(GET_BY_NAME_XML, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: - m.get(self.baseurl + '/testsite?key=name', text=response_xml) - single_site = self.server.sites.get_by_name('testsite') + m.get(self.baseurl + "/testsite?key=name", text=response_xml) + single_site = self.server.sites.get_by_name("testsite") - self.assertEqual('dad65087-b08b-4603-af4e-2887b8aafc67', single_site.id) - self.assertEqual('Active', single_site.state) - self.assertEqual('testsite', single_site.name) - self.assertEqual('ContentOnly', single_site.admin_mode) + self.assertEqual("dad65087-b08b-4603-af4e-2887b8aafc67", single_site.id) + self.assertEqual("Active", single_site.state) + self.assertEqual("testsite", single_site.name) + self.assertEqual("ContentOnly", single_site.admin_mode) self.assertEqual(False, single_site.revision_history_enabled) self.assertEqual(True, single_site.subscribe_others_enabled) self.assertEqual(False, single_site.disable_subscriptions) def test_get_by_name_missing_name(self): - self.assertRaises(ValueError, self.server.sites.get_by_name, '') + self.assertRaises(ValueError, self.server.sites.get_by_name, "") def test_update(self): - with open(UPDATE_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(UPDATE_XML, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: - m.put(self.baseurl + '/6b7179ba-b82b-4f0f-91ed-812074ac5da6', text=response_xml) - single_site = TSC.SiteItem(name='Tableau', content_url='tableau', - admin_mode=TSC.SiteItem.AdminMode.ContentAndUsers, - user_quota=15, storage_quota=1000, - disable_subscriptions=True, revision_history_enabled=False, - data_acceleration_mode='disable', flow_auto_save_enabled=True, - web_extraction_enabled=False, metrics_content_type_enabled=True, - notify_site_admins_on_throttle=False, authoring_enabled=True, - custom_subscription_email_enabled=True, - custom_subscription_email='test@test.com', - custom_subscription_footer_enabled=True, - custom_subscription_footer='example_footer', ask_data_mode='EnabledByDefault', - named_sharing_enabled=False, mobile_biometrics_enabled=True, - sheet_image_enabled=False, derived_permissions_enabled=True, - user_visibility_mode='FULL', use_default_time_zone=False, - time_zone='America/Los_Angeles', auto_suspend_refresh_enabled=True, - auto_suspend_refresh_inactivity_window=55) - single_site._id = '6b7179ba-b82b-4f0f-91ed-812074ac5da6' + m.put(self.baseurl + "/6b7179ba-b82b-4f0f-91ed-812074ac5da6", text=response_xml) + single_site = TSC.SiteItem( + name="Tableau", + content_url="tableau", + admin_mode=TSC.SiteItem.AdminMode.ContentAndUsers, + user_quota=15, + storage_quota=1000, + disable_subscriptions=True, + revision_history_enabled=False, + data_acceleration_mode="disable", + flow_auto_save_enabled=True, + web_extraction_enabled=False, + metrics_content_type_enabled=True, + notify_site_admins_on_throttle=False, + authoring_enabled=True, + custom_subscription_email_enabled=True, + custom_subscription_email="test@test.com", + custom_subscription_footer_enabled=True, + custom_subscription_footer="example_footer", + ask_data_mode="EnabledByDefault", + named_sharing_enabled=False, + mobile_biometrics_enabled=True, + sheet_image_enabled=False, + derived_permissions_enabled=True, + user_visibility_mode="FULL", + use_default_time_zone=False, + time_zone="America/Los_Angeles", + auto_suspend_refresh_enabled=True, + auto_suspend_refresh_inactivity_window=55, + ) + single_site._id = "6b7179ba-b82b-4f0f-91ed-812074ac5da6" single_site = self.server.sites.update(single_site) - self.assertEqual('6b7179ba-b82b-4f0f-91ed-812074ac5da6', single_site.id) - self.assertEqual('tableau', single_site.content_url) - self.assertEqual('Suspended', single_site.state) - self.assertEqual('Tableau', single_site.name) - self.assertEqual('ContentAndUsers', single_site.admin_mode) + self.assertEqual("6b7179ba-b82b-4f0f-91ed-812074ac5da6", single_site.id) + self.assertEqual("tableau", single_site.content_url) + self.assertEqual("Suspended", single_site.state) + self.assertEqual("Tableau", single_site.name) + self.assertEqual("ContentAndUsers", single_site.admin_mode) self.assertEqual(True, single_site.revision_history_enabled) self.assertEqual(13, single_site.revision_limit) self.assertEqual(True, single_site.disable_subscriptions) self.assertEqual(15, single_site.user_quota) - self.assertEqual('disable', single_site.data_acceleration_mode) + self.assertEqual("disable", single_site.data_acceleration_mode) self.assertEqual(True, single_site.flows_enabled) self.assertEqual(True, single_site.cataloging_enabled) self.assertEqual(True, single_site.flow_auto_save_enabled) @@ -146,39 +159,44 @@ def test_update(self): self.assertEqual(False, single_site.notify_site_admins_on_throttle) self.assertEqual(True, single_site.authoring_enabled) self.assertEqual(True, single_site.custom_subscription_email_enabled) - self.assertEqual('test@test.com', single_site.custom_subscription_email) + self.assertEqual("test@test.com", single_site.custom_subscription_email) self.assertEqual(True, single_site.custom_subscription_footer_enabled) - self.assertEqual('example_footer', single_site.custom_subscription_footer) - self.assertEqual('EnabledByDefault', single_site.ask_data_mode) + self.assertEqual("example_footer", single_site.custom_subscription_footer) + self.assertEqual("EnabledByDefault", single_site.ask_data_mode) self.assertEqual(False, single_site.named_sharing_enabled) self.assertEqual(True, single_site.mobile_biometrics_enabled) self.assertEqual(False, single_site.sheet_image_enabled) self.assertEqual(True, single_site.derived_permissions_enabled) - self.assertEqual('FULL', single_site.user_visibility_mode) + self.assertEqual("FULL", single_site.user_visibility_mode) self.assertEqual(False, single_site.use_default_time_zone) - self.assertEqual('America/Los_Angeles', single_site.time_zone) + self.assertEqual("America/Los_Angeles", single_site.time_zone) self.assertEqual(True, single_site.auto_suspend_refresh_enabled) self.assertEqual(55, single_site.auto_suspend_refresh_inactivity_window) def test_update_missing_id(self): - single_site = TSC.SiteItem('test', 'test') + single_site = TSC.SiteItem("test", "test") self.assertRaises(TSC.MissingRequiredFieldError, self.server.sites.update, single_site) def test_create(self): - with open(CREATE_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(CREATE_XML, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: m.post(self.baseurl, text=response_xml) - new_site = TSC.SiteItem(name='Tableau', content_url='tableau', - admin_mode=TSC.SiteItem.AdminMode.ContentAndUsers, user_quota=15, - storage_quota=1000, disable_subscriptions=True) + new_site = TSC.SiteItem( + name="Tableau", + content_url="tableau", + admin_mode=TSC.SiteItem.AdminMode.ContentAndUsers, + user_quota=15, + storage_quota=1000, + disable_subscriptions=True, + ) new_site = self.server.sites.create(new_site) - self.assertEqual('0626857c-1def-4503-a7d8-7907c3ff9d9f', new_site.id) - self.assertEqual('tableau', new_site.content_url) - self.assertEqual('Tableau', new_site.name) - self.assertEqual('Active', new_site.state) - self.assertEqual('ContentAndUsers', new_site.admin_mode) + self.assertEqual("0626857c-1def-4503-a7d8-7907c3ff9d9f", new_site.id) + self.assertEqual("tableau", new_site.content_url) + self.assertEqual("Tableau", new_site.name) + self.assertEqual("Active", new_site.state) + self.assertEqual("ContentAndUsers", new_site.admin_mode) self.assertEqual(False, new_site.revision_history_enabled) self.assertEqual(True, new_site.subscribe_others_enabled) self.assertEqual(True, new_site.disable_subscriptions) @@ -186,23 +204,23 @@ def test_create(self): def test_delete(self): with requests_mock.mock() as m: - m.delete(self.baseurl + '/0626857c-1def-4503-a7d8-7907c3ff9d9f', status_code=204) - self.server.sites.delete('0626857c-1def-4503-a7d8-7907c3ff9d9f') + m.delete(self.baseurl + "/0626857c-1def-4503-a7d8-7907c3ff9d9f", status_code=204) + self.server.sites.delete("0626857c-1def-4503-a7d8-7907c3ff9d9f") def test_delete_missing_id(self): - self.assertRaises(ValueError, self.server.sites.delete, '') + self.assertRaises(ValueError, self.server.sites.delete, "") def test_encrypt(self): with requests_mock.mock() as m: - m.post(self.baseurl + '/0626857c-1def-4503-a7d8-7907c3ff9d9f/encrypt-extracts', status_code=200) - self.server.sites.encrypt_extracts('0626857c-1def-4503-a7d8-7907c3ff9d9f') + m.post(self.baseurl + "/0626857c-1def-4503-a7d8-7907c3ff9d9f/encrypt-extracts", status_code=200) + self.server.sites.encrypt_extracts("0626857c-1def-4503-a7d8-7907c3ff9d9f") def test_recrypt(self): with requests_mock.mock() as m: - m.post(self.baseurl + '/0626857c-1def-4503-a7d8-7907c3ff9d9f/reencrypt-extracts', status_code=200) - self.server.sites.re_encrypt_extracts('0626857c-1def-4503-a7d8-7907c3ff9d9f') + m.post(self.baseurl + "/0626857c-1def-4503-a7d8-7907c3ff9d9f/reencrypt-extracts", status_code=200) + self.server.sites.re_encrypt_extracts("0626857c-1def-4503-a7d8-7907c3ff9d9f") def test_decrypt(self): with requests_mock.mock() as m: - m.post(self.baseurl + '/0626857c-1def-4503-a7d8-7907c3ff9d9f/decrypt-extracts', status_code=200) - self.server.sites.decrypt_extracts('0626857c-1def-4503-a7d8-7907c3ff9d9f') + m.post(self.baseurl + "/0626857c-1def-4503-a7d8-7907c3ff9d9f/decrypt-extracts", status_code=200) + self.server.sites.decrypt_extracts("0626857c-1def-4503-a7d8-7907c3ff9d9f") diff --git a/test/test_sort.py b/test/test_sort.py index 0572a1e10..105240fba 100644 --- a/test/test_sort.py +++ b/test/test_sort.py @@ -7,10 +7,10 @@ class SortTests(unittest.TestCase): def setUp(self): - self.server = TSC.Server('http://test') + self.server = TSC.Server("http://test") self.server.version = "3.10" - self.server._site_id = 'dad65087-b08b-4603-af4e-2887b8aafc67' - self.server._auth_token = 'j80k54ll2lfMZ0tv97mlPvvSCRyD0DOM' + self.server._site_id = "dad65087-b08b-4603-af4e-2887b8aafc67" + self.server._auth_token = "j80k54ll2lfMZ0tv97mlPvvSCRyD0DOM" self.baseurl = self.server.workbooks.baseurl def test_empty_filter(self): @@ -21,21 +21,17 @@ def test_filter_equals(self): 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')) + 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)) + 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_equals_list(self): with self.assertRaises(ValueError) as cm: - TSC.Filter(TSC.RequestOptions.Field.Tags, - TSC.RequestOptions.Operator.Equals, - ['foo', 'bar']) + 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)), @@ -45,28 +41,27 @@ def test_filter_in(self): 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'])) + 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)) + 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 test_sort_asc(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.sort.add(TSC.Sort(TSC.RequestOptions.Field.Name, - TSC.RequestOptions.Direction.Asc)) + 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('pagenumber=13', resp.request.query)) - self.assertTrue(re.search('pagesize=13', resp.request.query)) - self.assertTrue(re.search('sort=name%3aasc', resp.request.query)) + self.assertTrue(re.search("pagenumber=13", resp.request.query)) + self.assertTrue(re.search("pagesize=13", resp.request.query)) + self.assertTrue(re.search("sort=name%3aasc", resp.request.query)) def test_filter_combo(self): with requests_mock.mock() as m: @@ -74,25 +69,34 @@ def test_filter_combo(self): 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.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')) + opts.filter.add( + TSC.Filter(TSC.RequestOptions.Field.SiteRole, TSC.RequestOptions.Operator.Equals, "Publisher") + ) resp = self.server.workbooks.get_request(url, request_object=opts) - expected = 'pagenumber=13&pagesize=13&filter=lastlogin%3agte%3a' \ - '2017-01-15t00%3a00%3a00%3a00z%2csiterole%3aeq%3apublisher' + expected = ( + "pagenumber=13&pagesize=13&filter=lastlogin%3agte%3a" + "2017-01-15t00%3a00%3a00%3a00z%2csiterole%3aeq%3apublisher" + ) - self.assertTrue(re.search('pagenumber=13', resp.request.query)) - self.assertTrue(re.search('pagesize=13', resp.request.query)) - self.assertTrue(re.search( - 'filter=lastlogin%3agte%3a2017-01-15t00%3a00%3a00%3a00z%2csiterole%3aeq%3apublisher', - resp.request.query)) + self.assertTrue(re.search("pagenumber=13", resp.request.query)) + self.assertTrue(re.search("pagesize=13", resp.request.query)) + self.assertTrue( + re.search( + "filter=lastlogin%3agte%3a2017-01-15t00%3a00%3a00%3a00z%2csiterole%3aeq%3apublisher", + resp.request.query, + ) + ) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/test/test_subscription.py b/test/test_subscription.py index 15b845e56..951157575 100644 --- a/test/test_subscription.py +++ b/test/test_subscription.py @@ -13,7 +13,7 @@ class SubscriptionTests(unittest.TestCase): def setUp(self): self.server = TSC.Server("http://test") - self.server.version = '2.6' + self.server.version = "2.6" # Fake Signin self.server._site_id = "dad65087-b08b-4603-af4e-2887b8aafc67" @@ -30,58 +30,59 @@ def test_get_subscriptions(self): self.assertEqual(2, pagination_item.total_available) subscription = all_subscriptions[0] - self.assertEqual('382e9a6e-0c08-4a95-b6c1-c14df7bac3e4', subscription.id) - self.assertEqual('NOT FOUND!', subscription.message) + self.assertEqual("382e9a6e-0c08-4a95-b6c1-c14df7bac3e4", subscription.id) + self.assertEqual("NOT FOUND!", subscription.message) self.assertTrue(subscription.attach_image) self.assertFalse(subscription.attach_pdf) self.assertFalse(subscription.suspended) self.assertFalse(subscription.send_if_view_empty) self.assertIsNone(subscription.page_orientation) self.assertIsNone(subscription.page_size_option) - self.assertEqual('Not Found Alert', subscription.subject) - self.assertEqual('cdd716ca-5818-470e-8bec-086885dbadee', subscription.target.id) - self.assertEqual('View', subscription.target.type) - self.assertEqual('c0d5fc44-ad8c-4957-bec0-b70ed0f8df1e', subscription.user_id) - self.assertEqual('7617c389-cdca-4940-a66e-69956fcebf3e', subscription.schedule_id) + self.assertEqual("Not Found Alert", subscription.subject) + self.assertEqual("cdd716ca-5818-470e-8bec-086885dbadee", subscription.target.id) + self.assertEqual("View", subscription.target.type) + self.assertEqual("c0d5fc44-ad8c-4957-bec0-b70ed0f8df1e", subscription.user_id) + self.assertEqual("7617c389-cdca-4940-a66e-69956fcebf3e", subscription.schedule_id) subscription = all_subscriptions[1] - self.assertEqual('23cb7630-afc8-4c8e-b6cd-83ae0322ec66', subscription.id) - self.assertEqual('overview', subscription.message) + self.assertEqual("23cb7630-afc8-4c8e-b6cd-83ae0322ec66", subscription.id) + self.assertEqual("overview", subscription.message) self.assertFalse(subscription.attach_image) self.assertTrue(subscription.attach_pdf) self.assertTrue(subscription.suspended) self.assertTrue(subscription.send_if_view_empty) - self.assertEqual('PORTRAIT', subscription.page_orientation) - self.assertEqual('A5', subscription.page_size_option) - self.assertEqual('Last 7 Days', subscription.subject) - self.assertEqual('2e6b4e8f-22dd-4061-8f75-bf33703da7e5', subscription.target.id) - self.assertEqual('Workbook', subscription.target.type) - self.assertEqual('c0d5fc44-ad8c-4957-bec0-b70ed0f8df1e', subscription.user_id) - self.assertEqual('3407cd38-7b39-4983-86a6-67a1506a5e3f', subscription.schedule_id) + self.assertEqual("PORTRAIT", subscription.page_orientation) + self.assertEqual("A5", subscription.page_size_option) + self.assertEqual("Last 7 Days", subscription.subject) + self.assertEqual("2e6b4e8f-22dd-4061-8f75-bf33703da7e5", subscription.target.id) + self.assertEqual("Workbook", subscription.target.type) + self.assertEqual("c0d5fc44-ad8c-4957-bec0-b70ed0f8df1e", subscription.user_id) + self.assertEqual("3407cd38-7b39-4983-86a6-67a1506a5e3f", subscription.schedule_id) def test_get_subscription_by_id(self): with open(GET_XML_BY_ID, "rb") as f: response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: - m.get(self.baseurl + '/382e9a6e-0c08-4a95-b6c1-c14df7bac3e4', text=response_xml) - subscription = self.server.subscriptions.get_by_id('382e9a6e-0c08-4a95-b6c1-c14df7bac3e4') + m.get(self.baseurl + "/382e9a6e-0c08-4a95-b6c1-c14df7bac3e4", text=response_xml) + subscription = self.server.subscriptions.get_by_id("382e9a6e-0c08-4a95-b6c1-c14df7bac3e4") - self.assertEqual('382e9a6e-0c08-4a95-b6c1-c14df7bac3e4', subscription.id) - self.assertEqual('View', subscription.target.type) - self.assertEqual('cdd716ca-5818-470e-8bec-086885dbadee', subscription.target.id) - self.assertEqual('c0d5fc44-ad8c-4957-bec0-b70ed0f8df1e', subscription.user_id) - self.assertEqual('Not Found Alert', subscription.subject) - self.assertEqual('7617c389-cdca-4940-a66e-69956fcebf3e', subscription.schedule_id) + self.assertEqual("382e9a6e-0c08-4a95-b6c1-c14df7bac3e4", subscription.id) + self.assertEqual("View", subscription.target.type) + self.assertEqual("cdd716ca-5818-470e-8bec-086885dbadee", subscription.target.id) + self.assertEqual("c0d5fc44-ad8c-4957-bec0-b70ed0f8df1e", subscription.user_id) + self.assertEqual("Not Found Alert", subscription.subject) + self.assertEqual("7617c389-cdca-4940-a66e-69956fcebf3e", subscription.schedule_id) def test_create_subscription(self): - with open(CREATE_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(CREATE_XML, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: m.post(self.baseurl, text=response_xml) target_item = TSC.Target("960e61f2-1838-40b2-bba2-340c9492f943", "workbook") - new_subscription = TSC.SubscriptionItem("subject", "4906c453-d5ec-4972-9ff4-789b629bdfa2", - "8d30c8de-0a5f-4bee-b266-c621b4f3eed0", target_item) + new_subscription = TSC.SubscriptionItem( + "subject", "4906c453-d5ec-4972-9ff4-789b629bdfa2", "8d30c8de-0a5f-4bee-b266-c621b4f3eed0", target_item + ) new_subscription = self.server.subscriptions.create(new_subscription) self.assertEqual("78e9318d-2d29-4d67-b60f-3f2f5fd89ecc", new_subscription.id) @@ -93,5 +94,5 @@ def test_create_subscription(self): def test_delete_subscription(self): with requests_mock.mock() as m: - m.delete(self.baseurl + '/78e9318d-2d29-4d67-b60f-3f2f5fd89ecc', status_code=204) - self.server.subscriptions.delete('78e9318d-2d29-4d67-b60f-3f2f5fd89ecc') + m.delete(self.baseurl + "/78e9318d-2d29-4d67-b60f-3f2f5fd89ecc", status_code=204) + self.server.subscriptions.delete("78e9318d-2d29-4d67-b60f-3f2f5fd89ecc") diff --git a/test/test_table.py b/test/test_table.py index 45af43c9a..f03b9a522 100644 --- a/test/test_table.py +++ b/test/test_table.py @@ -8,17 +8,17 @@ from tableauserverclient.server.request_factory import RequestFactory from ._utils import read_xml_asset, read_xml_assets, asset -GET_XML = 'table_get.xml' -UPDATE_XML = 'table_update.xml' +GET_XML = "table_get.xml" +UPDATE_XML = "table_update.xml" class TableTests(unittest.TestCase): def setUp(self): - self.server = TSC.Server('http://test') + self.server = TSC.Server("http://test") # Fake signin - self.server._site_id = 'dad65087-b08b-4603-af4e-2887b8aafc67' - self.server._auth_token = 'j80k54ll2lfMZ0tv97mlPvvSCRyD0DOM' + self.server._site_id = "dad65087-b08b-4603-af4e-2887b8aafc67" + self.server._auth_token = "j80k54ll2lfMZ0tv97mlPvvSCRyD0DOM" self.server.version = "3.5" self.baseurl = self.server.tables.baseurl @@ -30,33 +30,33 @@ def test_get(self): all_tables, pagination_item = self.server.tables.get() self.assertEqual(4, pagination_item.total_available) - self.assertEqual('10224773-ecee-42ac-b822-d786b0b8e4d9', all_tables[0].id) - self.assertEqual('dim_Product', all_tables[0].name) + self.assertEqual("10224773-ecee-42ac-b822-d786b0b8e4d9", all_tables[0].id) + self.assertEqual("dim_Product", all_tables[0].name) - self.assertEqual('53c77bc1-fb41-4342-a75a-f68ac0656d0d', all_tables[1].id) - self.assertEqual('customer', all_tables[1].name) - self.assertEqual('dbo', all_tables[1].schema) - self.assertEqual('9324cf6b-ba72-4b8e-b895-ac3f28d2f0e0', all_tables[1].contact_id) + self.assertEqual("53c77bc1-fb41-4342-a75a-f68ac0656d0d", all_tables[1].id) + self.assertEqual("customer", all_tables[1].name) + self.assertEqual("dbo", all_tables[1].schema) + self.assertEqual("9324cf6b-ba72-4b8e-b895-ac3f28d2f0e0", all_tables[1].contact_id) self.assertEqual(False, all_tables[1].certified) def test_update(self): response_xml = read_xml_asset(UPDATE_XML) with requests_mock.mock() as m: - m.put(self.baseurl + '/10224773-ecee-42ac-b822-d786b0b8e4d9', text=response_xml) - single_table = TSC.TableItem('test') - single_table._id = '10224773-ecee-42ac-b822-d786b0b8e4d9' + m.put(self.baseurl + "/10224773-ecee-42ac-b822-d786b0b8e4d9", text=response_xml) + single_table = TSC.TableItem("test") + single_table._id = "10224773-ecee-42ac-b822-d786b0b8e4d9" - single_table.contact_id = '8e1a8235-c9ee-4d61-ae82-2ffacceed8e0' + single_table.contact_id = "8e1a8235-c9ee-4d61-ae82-2ffacceed8e0" single_table.certified = True single_table.certification_note = "Test" single_table = self.server.tables.update(single_table) - self.assertEqual('10224773-ecee-42ac-b822-d786b0b8e4d9', single_table.id) - self.assertEqual('8e1a8235-c9ee-4d61-ae82-2ffacceed8e0', single_table.contact_id) + self.assertEqual("10224773-ecee-42ac-b822-d786b0b8e4d9", single_table.id) + self.assertEqual("8e1a8235-c9ee-4d61-ae82-2ffacceed8e0", single_table.contact_id) self.assertEqual(True, single_table.certified) self.assertEqual("Test", single_table.certification_note) def test_delete(self): with requests_mock.mock() as m: - m.delete(self.baseurl + '/0448d2ed-590d-4fa0-b272-a2a8a24555b5', status_code=204) - self.server.tables.delete('0448d2ed-590d-4fa0-b272-a2a8a24555b5') + m.delete(self.baseurl + "/0448d2ed-590d-4fa0-b272-a2a8a24555b5", status_code=204) + self.server.tables.delete("0448d2ed-590d-4fa0-b272-a2a8a24555b5") diff --git a/test/test_tableauauth_model.py b/test/test_tableauauth_model.py index 94a44706a..3314aee26 100644 --- a/test/test_tableauauth_model.py +++ b/test/test_tableauauth_model.py @@ -5,10 +5,7 @@ class TableauAuthModelTests(unittest.TestCase): def setUp(self): - self.auth = TSC.TableauAuth('user', - 'password', - site_id='site1', - user_id_to_impersonate='admin') + self.auth = TSC.TableauAuth("user", "password", site_id="site1", user_id_to_impersonate="admin") def test_username_password_required(self): with self.assertRaises(TypeError): @@ -18,8 +15,6 @@ def test_site_arg_raises_warning(self): with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") - tableau_auth = TSC.TableauAuth('user', - 'password', - site='Default') + tableau_auth = TSC.TableauAuth("user", "password", site="Default") self.assertTrue(any(item.category == DeprecationWarning for item in w)) diff --git a/test/test_task.py b/test/test_task.py index 566167d4a..329caf2e7 100644 --- a/test/test_task.py +++ b/test/test_task.py @@ -18,7 +18,7 @@ class TaskTests(unittest.TestCase): def setUp(self): self.server = TSC.Server("http://test") - self.server.version = '3.8' + self.server.version = "3.8" # Fake Signin self.server._site_id = "dad65087-b08b-4603-af4e-2887b8aafc67" @@ -45,8 +45,8 @@ def test_get_tasks_with_workbook(self): all_tasks, pagination_item = self.server.tasks.get() task = all_tasks[0] - self.assertEqual('c7a9327e-1cda-4504-b026-ddb43b976d1d', task.target.id) - self.assertEqual('workbook', task.target.type) + self.assertEqual("c7a9327e-1cda-4504-b026-ddb43b976d1d", task.target.id) + self.assertEqual("workbook", task.target.type) def test_get_tasks_with_datasource(self): with open(GET_XML_WITH_DATASOURCE, "rb") as f: @@ -56,8 +56,8 @@ def test_get_tasks_with_datasource(self): all_tasks, pagination_item = self.server.tasks.get() task = all_tasks[0] - self.assertEqual('c7a9327e-1cda-4504-b026-ddb43b976d1d', task.target.id) - self.assertEqual('datasource', task.target.type) + self.assertEqual("c7a9327e-1cda-4504-b026-ddb43b976d1d", task.target.id) + self.assertEqual("datasource", task.target.type) def test_get_tasks_with_workbook_and_datasource(self): with open(GET_XML_WITH_WORKBOOK_AND_DATASOURCE, "rb") as f: @@ -66,9 +66,9 @@ def test_get_tasks_with_workbook_and_datasource(self): m.get(self.baseurl, text=response_xml) all_tasks, pagination_item = self.server.tasks.get() - self.assertEqual('workbook', all_tasks[0].target.type) - self.assertEqual('datasource', all_tasks[1].target.type) - self.assertEqual('workbook', all_tasks[2].target.type) + self.assertEqual("workbook", all_tasks[0].target.type) + self.assertEqual("datasource", all_tasks[1].target.type) + self.assertEqual("workbook", all_tasks[2].target.type) def test_get_task_with_schedule(self): with open(GET_XML_WITH_WORKBOOK, "rb") as f: @@ -78,63 +78,64 @@ def test_get_task_with_schedule(self): all_tasks, pagination_item = self.server.tasks.get() task = all_tasks[0] - self.assertEqual('c7a9327e-1cda-4504-b026-ddb43b976d1d', task.target.id) - self.assertEqual('workbook', task.target.type) - self.assertEqual('b60b4efd-a6f7-4599-beb3-cb677e7abac1', task.schedule_id) + self.assertEqual("c7a9327e-1cda-4504-b026-ddb43b976d1d", task.target.id) + self.assertEqual("workbook", task.target.type) + self.assertEqual("b60b4efd-a6f7-4599-beb3-cb677e7abac1", task.schedule_id) def test_delete(self): with requests_mock.mock() as m: - m.delete(self.baseurl + '/c7a9327e-1cda-4504-b026-ddb43b976d1d', status_code=204) - self.server.tasks.delete('c7a9327e-1cda-4504-b026-ddb43b976d1d') + m.delete(self.baseurl + "/c7a9327e-1cda-4504-b026-ddb43b976d1d", status_code=204) + self.server.tasks.delete("c7a9327e-1cda-4504-b026-ddb43b976d1d") def test_delete_missing_id(self): - self.assertRaises(ValueError, self.server.tasks.delete, '') + self.assertRaises(ValueError, self.server.tasks.delete, "") def test_get_materializeviews_tasks(self): with open(GET_XML_DATAACCELERATION_TASK, "rb") as f: response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: - m.get('{}/{}'.format( - self.server.tasks.baseurl, TaskItem.Type.DataAcceleration), text=response_xml) + m.get("{}/{}".format(self.server.tasks.baseurl, TaskItem.Type.DataAcceleration), text=response_xml) all_tasks, pagination_item = self.server.tasks.get(task_type=TaskItem.Type.DataAcceleration) task = all_tasks[0] - self.assertEqual('a462c148-fc40-4670-a8e4-39b7f0c58c7f', task.target.id) - self.assertEqual('workbook', task.target.type) - self.assertEqual('b22190b4-6ac2-4eed-9563-4afc03444413', task.schedule_id) - self.assertEqual(parse_datetime('2019-12-09T22:30:00Z'), task.schedule_item.next_run_at) - self.assertEqual(parse_datetime('2019-12-09T20:45:04Z'), task.last_run_at) + self.assertEqual("a462c148-fc40-4670-a8e4-39b7f0c58c7f", task.target.id) + self.assertEqual("workbook", task.target.type) + self.assertEqual("b22190b4-6ac2-4eed-9563-4afc03444413", task.schedule_id) + self.assertEqual(parse_datetime("2019-12-09T22:30:00Z"), task.schedule_item.next_run_at) + self.assertEqual(parse_datetime("2019-12-09T20:45:04Z"), task.last_run_at) self.assertEqual(TSC.TaskItem.Type.DataAcceleration, task.task_type) def test_delete_data_acceleration(self): with requests_mock.mock() as m: - m.delete('{}/{}/{}'.format( - self.server.tasks.baseurl, TaskItem.Type.DataAcceleration, - 'c9cff7f9-309c-4361-99ff-d4ba8c9f5467'), status_code=204) - self.server.tasks.delete('c9cff7f9-309c-4361-99ff-d4ba8c9f5467', - TaskItem.Type.DataAcceleration) + m.delete( + "{}/{}/{}".format( + self.server.tasks.baseurl, TaskItem.Type.DataAcceleration, "c9cff7f9-309c-4361-99ff-d4ba8c9f5467" + ), + status_code=204, + ) + self.server.tasks.delete("c9cff7f9-309c-4361-99ff-d4ba8c9f5467", TaskItem.Type.DataAcceleration) def test_get_by_id(self): with open(GET_XML_WITH_WORKBOOK, "rb") as f: response_xml = f.read().decode("utf-8") - task_id = 'f84901ac-72ad-4f9b-a87e-7a3500402ad6' + task_id = "f84901ac-72ad-4f9b-a87e-7a3500402ad6" with requests_mock.mock() as m: - m.get('{}/{}'.format(self.baseurl, task_id), text=response_xml) + m.get("{}/{}".format(self.baseurl, task_id), text=response_xml) task = self.server.tasks.get_by_id(task_id) - self.assertEqual('c7a9327e-1cda-4504-b026-ddb43b976d1d', task.target.id) - self.assertEqual('workbook', task.target.type) - self.assertEqual('b60b4efd-a6f7-4599-beb3-cb677e7abac1', task.schedule_id) + self.assertEqual("c7a9327e-1cda-4504-b026-ddb43b976d1d", task.target.id) + self.assertEqual("workbook", task.target.type) + self.assertEqual("b60b4efd-a6f7-4599-beb3-cb677e7abac1", task.schedule_id) self.assertEqual(TSC.TaskItem.Type.ExtractRefresh, task.task_type) def test_run_now(self): - task_id = 'f84901ac-72ad-4f9b-a87e-7a3500402ad6' + task_id = "f84901ac-72ad-4f9b-a87e-7a3500402ad6" task = TaskItem(task_id, TaskItem.Type.ExtractRefresh, 100) with open(GET_XML_RUN_NOW_RESPONSE, "rb") as f: response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: - m.post('{}/{}/runNow'.format(self.baseurl, task_id), text=response_xml) + m.post("{}/{}/runNow".format(self.baseurl, task_id), text=response_xml) job_response_content = self.server.tasks.run(task).decode("utf-8") - self.assertTrue('7b6b59a8-ac3c-4d1d-2e9e-0b5b4ba8a7b6' in job_response_content) - self.assertTrue('RefreshExtract' in job_response_content) + self.assertTrue("7b6b59a8-ac3c-4d1d-2e9e-0b5b4ba8a7b6" in job_response_content) + self.assertTrue("RefreshExtract" in job_response_content) diff --git a/test/test_user.py b/test/test_user.py index e4d1d6717..90299c317 100644 --- a/test/test_user.py +++ b/test/test_user.py @@ -4,31 +4,31 @@ import tableauserverclient as TSC from tableauserverclient.datetime_helpers import format_datetime -TEST_ASSET_DIR = os.path.join(os.path.dirname(__file__), 'assets') +TEST_ASSET_DIR = os.path.join(os.path.dirname(__file__), "assets") -GET_XML = os.path.join(TEST_ASSET_DIR, 'user_get.xml') -GET_EMPTY_XML = os.path.join(TEST_ASSET_DIR, 'user_get_empty.xml') -GET_BY_ID_XML = os.path.join(TEST_ASSET_DIR, 'user_get_by_id.xml') -UPDATE_XML = os.path.join(TEST_ASSET_DIR, 'user_update.xml') -ADD_XML = os.path.join(TEST_ASSET_DIR, 'user_add.xml') -POPULATE_WORKBOOKS_XML = os.path.join(TEST_ASSET_DIR, 'user_populate_workbooks.xml') -GET_FAVORITES_XML = os.path.join(TEST_ASSET_DIR, 'favorites_get.xml') -POPULATE_GROUPS_XML = os.path.join(TEST_ASSET_DIR, 'user_populate_groups.xml') +GET_XML = os.path.join(TEST_ASSET_DIR, "user_get.xml") +GET_EMPTY_XML = os.path.join(TEST_ASSET_DIR, "user_get_empty.xml") +GET_BY_ID_XML = os.path.join(TEST_ASSET_DIR, "user_get_by_id.xml") +UPDATE_XML = os.path.join(TEST_ASSET_DIR, "user_update.xml") +ADD_XML = os.path.join(TEST_ASSET_DIR, "user_add.xml") +POPULATE_WORKBOOKS_XML = os.path.join(TEST_ASSET_DIR, "user_populate_workbooks.xml") +GET_FAVORITES_XML = os.path.join(TEST_ASSET_DIR, "favorites_get.xml") +POPULATE_GROUPS_XML = os.path.join(TEST_ASSET_DIR, "user_populate_groups.xml") class UserTests(unittest.TestCase): def setUp(self): - self.server = TSC.Server('http://test') + self.server = TSC.Server("http://test") # Fake signin - self.server._site_id = 'dad65087-b08b-4603-af4e-2887b8aafc67' - self.server._auth_token = 'j80k54ll2lfMZ0tv97mlPvvSCRyD0DOM' + self.server._site_id = "dad65087-b08b-4603-af4e-2887b8aafc67" + self.server._auth_token = "j80k54ll2lfMZ0tv97mlPvvSCRyD0DOM" self.baseurl = self.server.users.baseurl def test_get(self): - with open(GET_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(GET_XML, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: m.get(self.baseurl + "?fields=_all_", text=response_xml) all_users, pagination_item = self.server.users.get() @@ -36,24 +36,24 @@ def test_get(self): self.assertEqual(2, pagination_item.total_available) self.assertEqual(2, len(all_users)) - self.assertTrue(any(user.id == 'dd2239f6-ddf1-4107-981a-4cf94e415794' for user in all_users)) - single_user = next(user for user in all_users if user.id == 'dd2239f6-ddf1-4107-981a-4cf94e415794') - self.assertEqual('alice', single_user.name) - self.assertEqual('Publisher', single_user.site_role) - self.assertEqual('2016-08-16T23:17:06Z', format_datetime(single_user.last_login)) - self.assertEqual('alice cook', single_user.fullname) - self.assertEqual('alicecook@test.com', single_user.email) - - self.assertTrue(any(user.id == '2a47bbf8-8900-4ebb-b0a4-2723bd7c46c3' for user in all_users)) - single_user = next(user for user in all_users if user.id == '2a47bbf8-8900-4ebb-b0a4-2723bd7c46c3') - self.assertEqual('Bob', single_user.name) - self.assertEqual('Interactor', single_user.site_role) - self.assertEqual('Bob Smith', single_user.fullname) - self.assertEqual('bob@test.com', single_user.email) + self.assertTrue(any(user.id == "dd2239f6-ddf1-4107-981a-4cf94e415794" for user in all_users)) + single_user = next(user for user in all_users if user.id == "dd2239f6-ddf1-4107-981a-4cf94e415794") + self.assertEqual("alice", single_user.name) + self.assertEqual("Publisher", single_user.site_role) + self.assertEqual("2016-08-16T23:17:06Z", format_datetime(single_user.last_login)) + self.assertEqual("alice cook", single_user.fullname) + self.assertEqual("alicecook@test.com", single_user.email) + + self.assertTrue(any(user.id == "2a47bbf8-8900-4ebb-b0a4-2723bd7c46c3" for user in all_users)) + single_user = next(user for user in all_users if user.id == "2a47bbf8-8900-4ebb-b0a4-2723bd7c46c3") + self.assertEqual("Bob", single_user.name) + self.assertEqual("Interactor", single_user.site_role) + self.assertEqual("Bob Smith", single_user.fullname) + self.assertEqual("bob@test.com", single_user.email) def test_get_empty(self): - with open(GET_EMPTY_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(GET_EMPTY_XML, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: m.get(self.baseurl, text=response_xml) all_users, pagination_item = self.server.users.get() @@ -66,139 +66,137 @@ def test_get_before_signin(self): self.assertRaises(TSC.NotSignedInError, self.server.users.get) def test_get_by_id(self): - with open(GET_BY_ID_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(GET_BY_ID_XML, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: - m.get(self.baseurl + '/dd2239f6-ddf1-4107-981a-4cf94e415794', text=response_xml) - single_user = self.server.users.get_by_id('dd2239f6-ddf1-4107-981a-4cf94e415794') + m.get(self.baseurl + "/dd2239f6-ddf1-4107-981a-4cf94e415794", text=response_xml) + single_user = self.server.users.get_by_id("dd2239f6-ddf1-4107-981a-4cf94e415794") - self.assertEqual('dd2239f6-ddf1-4107-981a-4cf94e415794', single_user.id) - self.assertEqual('alice', single_user.name) - self.assertEqual('Alice', single_user.fullname) - self.assertEqual('Publisher', single_user.site_role) - self.assertEqual('ServerDefault', single_user.auth_setting) - self.assertEqual('2016-08-16T23:17:06Z', format_datetime(single_user.last_login)) - self.assertEqual('local', single_user.domain_name) + self.assertEqual("dd2239f6-ddf1-4107-981a-4cf94e415794", single_user.id) + self.assertEqual("alice", single_user.name) + self.assertEqual("Alice", single_user.fullname) + self.assertEqual("Publisher", single_user.site_role) + self.assertEqual("ServerDefault", single_user.auth_setting) + self.assertEqual("2016-08-16T23:17:06Z", format_datetime(single_user.last_login)) + self.assertEqual("local", single_user.domain_name) def test_get_by_id_missing_id(self): - self.assertRaises(ValueError, self.server.users.get_by_id, '') + self.assertRaises(ValueError, self.server.users.get_by_id, "") def test_update(self): - with open(UPDATE_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(UPDATE_XML, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: - m.put(self.baseurl + '/dd2239f6-ddf1-4107-981a-4cf94e415794', text=response_xml) - single_user = TSC.UserItem('test', 'Viewer') - single_user._id = 'dd2239f6-ddf1-4107-981a-4cf94e415794' - single_user.name = 'Cassie' - single_user.fullname = 'Cassie' - single_user.email = 'cassie@email.com' + m.put(self.baseurl + "/dd2239f6-ddf1-4107-981a-4cf94e415794", text=response_xml) + single_user = TSC.UserItem("test", "Viewer") + single_user._id = "dd2239f6-ddf1-4107-981a-4cf94e415794" + single_user.name = "Cassie" + single_user.fullname = "Cassie" + single_user.email = "cassie@email.com" single_user = self.server.users.update(single_user) - self.assertEqual('Cassie', single_user.name) - self.assertEqual('Cassie', single_user.fullname) - self.assertEqual('cassie@email.com', single_user.email) - self.assertEqual('Viewer', single_user.site_role) + self.assertEqual("Cassie", single_user.name) + self.assertEqual("Cassie", single_user.fullname) + self.assertEqual("cassie@email.com", single_user.email) + self.assertEqual("Viewer", single_user.site_role) def test_update_missing_id(self): - single_user = TSC.UserItem('test', 'Interactor') + single_user = TSC.UserItem("test", "Interactor") self.assertRaises(TSC.MissingRequiredFieldError, self.server.users.update, single_user) def test_remove(self): with requests_mock.mock() as m: - m.delete(self.baseurl + '/dd2239f6-ddf1-4107-981a-4cf94e415794', status_code=204) - self.server.users.remove('dd2239f6-ddf1-4107-981a-4cf94e415794') + m.delete(self.baseurl + "/dd2239f6-ddf1-4107-981a-4cf94e415794", status_code=204) + self.server.users.remove("dd2239f6-ddf1-4107-981a-4cf94e415794") def test_remove_missing_id(self): - self.assertRaises(ValueError, self.server.users.remove, '') + self.assertRaises(ValueError, self.server.users.remove, "") def test_add(self): - with open(ADD_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(ADD_XML, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: - m.post(self.baseurl + '', text=response_xml) - new_user = TSC.UserItem(name='Cassie', site_role='Viewer', auth_setting='ServerDefault') + m.post(self.baseurl + "", text=response_xml) + new_user = TSC.UserItem(name="Cassie", site_role="Viewer", auth_setting="ServerDefault") new_user = self.server.users.add(new_user) - self.assertEqual('4cc4c17f-898a-4de4-abed-a1681c673ced', new_user.id) - self.assertEqual('Cassie', new_user.name) - self.assertEqual('Viewer', new_user.site_role) - self.assertEqual('ServerDefault', new_user.auth_setting) + self.assertEqual("4cc4c17f-898a-4de4-abed-a1681c673ced", new_user.id) + self.assertEqual("Cassie", new_user.name) + self.assertEqual("Viewer", new_user.site_role) + self.assertEqual("ServerDefault", new_user.auth_setting) def test_populate_workbooks(self): - with open(POPULATE_WORKBOOKS_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(POPULATE_WORKBOOKS_XML, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: - m.get(self.baseurl + '/dd2239f6-ddf1-4107-981a-4cf94e415794/workbooks', - text=response_xml) - single_user = TSC.UserItem('test', 'Interactor') - single_user._id = 'dd2239f6-ddf1-4107-981a-4cf94e415794' + m.get(self.baseurl + "/dd2239f6-ddf1-4107-981a-4cf94e415794/workbooks", text=response_xml) + single_user = TSC.UserItem("test", "Interactor") + single_user._id = "dd2239f6-ddf1-4107-981a-4cf94e415794" self.server.users.populate_workbooks(single_user) workbook_list = list(single_user.workbooks) - self.assertEqual('3cc6cd06-89ce-4fdc-b935-5294135d6d42', workbook_list[0].id) - self.assertEqual('SafariSample', workbook_list[0].name) - self.assertEqual('SafariSample', workbook_list[0].content_url) + self.assertEqual("3cc6cd06-89ce-4fdc-b935-5294135d6d42", workbook_list[0].id) + self.assertEqual("SafariSample", workbook_list[0].name) + self.assertEqual("SafariSample", workbook_list[0].content_url) self.assertEqual(False, workbook_list[0].show_tabs) self.assertEqual(26, workbook_list[0].size) - self.assertEqual('2016-07-26T20:34:56Z', format_datetime(workbook_list[0].created_at)) - self.assertEqual('2016-07-26T20:35:05Z', format_datetime(workbook_list[0].updated_at)) - self.assertEqual('ee8c6e70-43b6-11e6-af4f-f7b0d8e20760', workbook_list[0].project_id) - self.assertEqual('default', workbook_list[0].project_name) - self.assertEqual('5de011f8-5aa9-4d5b-b991-f462c8dd6bb7', workbook_list[0].owner_id) - self.assertEqual(set(['Safari', 'Sample']), workbook_list[0].tags) + self.assertEqual("2016-07-26T20:34:56Z", format_datetime(workbook_list[0].created_at)) + self.assertEqual("2016-07-26T20:35:05Z", format_datetime(workbook_list[0].updated_at)) + self.assertEqual("ee8c6e70-43b6-11e6-af4f-f7b0d8e20760", workbook_list[0].project_id) + self.assertEqual("default", workbook_list[0].project_name) + self.assertEqual("5de011f8-5aa9-4d5b-b991-f462c8dd6bb7", workbook_list[0].owner_id) + self.assertEqual(set(["Safari", "Sample"]), workbook_list[0].tags) def test_populate_workbooks_missing_id(self): - single_user = TSC.UserItem('test', 'Interactor') + single_user = TSC.UserItem("test", "Interactor") self.assertRaises(TSC.MissingRequiredFieldError, self.server.users.populate_workbooks, single_user) def test_populate_favorites(self): - self.server.version = '2.5' + self.server.version = "2.5" baseurl = self.server.favorites.baseurl - single_user = TSC.UserItem('test', 'Interactor') - with open(GET_FAVORITES_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') + single_user = TSC.UserItem("test", "Interactor") + with open(GET_FAVORITES_XML, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: - m.get('{0}/{1}'.format(baseurl, single_user.id), text=response_xml) + m.get("{0}/{1}".format(baseurl, single_user.id), text=response_xml) self.server.users.populate_favorites(single_user) self.assertIsNotNone(single_user._favorites) - self.assertEqual(len(single_user.favorites['workbooks']), 1) - self.assertEqual(len(single_user.favorites['views']), 1) - self.assertEqual(len(single_user.favorites['projects']), 1) - self.assertEqual(len(single_user.favorites['datasources']), 1) + self.assertEqual(len(single_user.favorites["workbooks"]), 1) + self.assertEqual(len(single_user.favorites["views"]), 1) + self.assertEqual(len(single_user.favorites["projects"]), 1) + self.assertEqual(len(single_user.favorites["datasources"]), 1) - workbook = single_user.favorites['workbooks'][0] - view = single_user.favorites['views'][0] - datasource = single_user.favorites['datasources'][0] - project = single_user.favorites['projects'][0] + workbook = single_user.favorites["workbooks"][0] + view = single_user.favorites["views"][0] + datasource = single_user.favorites["datasources"][0] + project = single_user.favorites["projects"][0] - self.assertEqual(workbook.id, '6d13b0ca-043d-4d42-8c9d-3f3313ea3a00') - self.assertEqual(view.id, 'd79634e1-6063-4ec9-95ff-50acbf609ff5') - self.assertEqual(datasource.id, 'e76a1461-3b1d-4588-bf1b-17551a879ad9') - self.assertEqual(project.id, '1d0304cd-3796-429f-b815-7258370b9b74') + self.assertEqual(workbook.id, "6d13b0ca-043d-4d42-8c9d-3f3313ea3a00") + self.assertEqual(view.id, "d79634e1-6063-4ec9-95ff-50acbf609ff5") + self.assertEqual(datasource.id, "e76a1461-3b1d-4588-bf1b-17551a879ad9") + self.assertEqual(project.id, "1d0304cd-3796-429f-b815-7258370b9b74") def test_populate_groups(self): - self.server.version = '3.7' - with open(POPULATE_GROUPS_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') + self.server.version = "3.7" + with open(POPULATE_GROUPS_XML, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: - m.get(self.server.users.baseurl + '/dd2239f6-ddf1-4107-981a-4cf94e415794/groups', - text=response_xml) - single_user = TSC.UserItem('test', 'Interactor') - single_user._id = 'dd2239f6-ddf1-4107-981a-4cf94e415794' + m.get(self.server.users.baseurl + "/dd2239f6-ddf1-4107-981a-4cf94e415794/groups", text=response_xml) + single_user = TSC.UserItem("test", "Interactor") + single_user._id = "dd2239f6-ddf1-4107-981a-4cf94e415794" self.server.users.populate_groups(single_user) group_list = list(single_user.groups) self.assertEqual(3, len(group_list)) - self.assertEqual('ef8b19c0-43b6-11e6-af50-63f5805dbe3c', group_list[0].id) - self.assertEqual('All Users', group_list[0].name) - self.assertEqual('local', group_list[0].domain_name) + self.assertEqual("ef8b19c0-43b6-11e6-af50-63f5805dbe3c", group_list[0].id) + self.assertEqual("All Users", group_list[0].name) + self.assertEqual("local", group_list[0].domain_name) - self.assertEqual('e7833b48-c6f7-47b5-a2a7-36e7dd232758', group_list[1].id) - self.assertEqual('Another group', group_list[1].name) - self.assertEqual('local', group_list[1].domain_name) + self.assertEqual("e7833b48-c6f7-47b5-a2a7-36e7dd232758", group_list[1].id) + self.assertEqual("Another group", group_list[1].name) + self.assertEqual("local", group_list[1].domain_name) - self.assertEqual('86a66d40-f289-472a-83d0-927b0f954dc8', group_list[2].id) - self.assertEqual('TableauExample', group_list[2].name) - self.assertEqual('local', group_list[2].domain_name) + self.assertEqual("86a66d40-f289-472a-83d0-927b0f954dc8", group_list[2].id) + self.assertEqual("TableauExample", group_list[2].name) + self.assertEqual("local", group_list[2].domain_name) diff --git a/test/test_view.py b/test/test_view.py index e32971ea2..ddb3871c4 100644 --- a/test/test_view.py +++ b/test/test_view.py @@ -6,109 +6,110 @@ from tableauserverclient.datetime_helpers import format_datetime from tableauserverclient import UserItem, GroupItem, PermissionsRule -TEST_ASSET_DIR = os.path.join(os.path.dirname(__file__), 'assets') +TEST_ASSET_DIR = os.path.join(os.path.dirname(__file__), "assets") -ADD_TAGS_XML = os.path.join(TEST_ASSET_DIR, 'view_add_tags.xml') -GET_XML = os.path.join(TEST_ASSET_DIR, 'view_get.xml') -GET_XML_ID = os.path.join(TEST_ASSET_DIR, 'view_get_id.xml') -GET_XML_USAGE = os.path.join(TEST_ASSET_DIR, 'view_get_usage.xml') -POPULATE_PREVIEW_IMAGE = os.path.join(TEST_ASSET_DIR, 'Sample View Image.png') -POPULATE_PDF = os.path.join(TEST_ASSET_DIR, 'populate_pdf.pdf') -POPULATE_CSV = os.path.join(TEST_ASSET_DIR, 'populate_csv.csv') -POPULATE_PERMISSIONS_XML = os.path.join(TEST_ASSET_DIR, 'view_populate_permissions.xml') -UPDATE_PERMISSIONS = os.path.join(TEST_ASSET_DIR, 'view_update_permissions.xml') -UPDATE_XML = os.path.join(TEST_ASSET_DIR, 'workbook_update.xml') +ADD_TAGS_XML = os.path.join(TEST_ASSET_DIR, "view_add_tags.xml") +GET_XML = os.path.join(TEST_ASSET_DIR, "view_get.xml") +GET_XML_ID = os.path.join(TEST_ASSET_DIR, "view_get_id.xml") +GET_XML_USAGE = os.path.join(TEST_ASSET_DIR, "view_get_usage.xml") +POPULATE_PREVIEW_IMAGE = os.path.join(TEST_ASSET_DIR, "Sample View Image.png") +POPULATE_PDF = os.path.join(TEST_ASSET_DIR, "populate_pdf.pdf") +POPULATE_CSV = os.path.join(TEST_ASSET_DIR, "populate_csv.csv") +POPULATE_PERMISSIONS_XML = os.path.join(TEST_ASSET_DIR, "view_populate_permissions.xml") +UPDATE_PERMISSIONS = os.path.join(TEST_ASSET_DIR, "view_update_permissions.xml") +UPDATE_XML = os.path.join(TEST_ASSET_DIR, "workbook_update.xml") class ViewTests(unittest.TestCase): def setUp(self): - self.server = TSC.Server('http://test') - self.server.version = '3.2' + self.server = TSC.Server("http://test") + self.server.version = "3.2" # Fake sign in - self.server._site_id = 'dad65087-b08b-4603-af4e-2887b8aafc67' - self.server._auth_token = 'j80k54ll2lfMZ0tv97mlPvvSCRyD0DOM' + self.server._site_id = "dad65087-b08b-4603-af4e-2887b8aafc67" + self.server._auth_token = "j80k54ll2lfMZ0tv97mlPvvSCRyD0DOM" self.baseurl = self.server.views.baseurl self.siteurl = self.server.views.siteurl def test_get(self): - with open(GET_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(GET_XML, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: m.get(self.baseurl, text=response_xml) all_views, pagination_item = self.server.views.get() self.assertEqual(2, pagination_item.total_available) - self.assertEqual('d79634e1-6063-4ec9-95ff-50acbf609ff5', all_views[0].id) - self.assertEqual('ENDANGERED SAFARI', all_views[0].name) - self.assertEqual('SafariSample/sheets/ENDANGEREDSAFARI', all_views[0].content_url) - self.assertEqual('3cc6cd06-89ce-4fdc-b935-5294135d6d42', all_views[0].workbook_id) - self.assertEqual('5de011f8-5aa9-4d5b-b991-f462c8dd6bb7', all_views[0].owner_id) - self.assertEqual('5241e88d-d384-4fd7-9c2f-648b5247efc5', all_views[0].project_id) - self.assertEqual(set(['tag1', 'tag2']), all_views[0].tags) + self.assertEqual("d79634e1-6063-4ec9-95ff-50acbf609ff5", all_views[0].id) + self.assertEqual("ENDANGERED SAFARI", all_views[0].name) + self.assertEqual("SafariSample/sheets/ENDANGEREDSAFARI", all_views[0].content_url) + self.assertEqual("3cc6cd06-89ce-4fdc-b935-5294135d6d42", all_views[0].workbook_id) + self.assertEqual("5de011f8-5aa9-4d5b-b991-f462c8dd6bb7", all_views[0].owner_id) + self.assertEqual("5241e88d-d384-4fd7-9c2f-648b5247efc5", all_views[0].project_id) + self.assertEqual(set(["tag1", "tag2"]), all_views[0].tags) self.assertIsNone(all_views[0].created_at) self.assertIsNone(all_views[0].updated_at) self.assertIsNone(all_views[0].sheet_type) - self.assertEqual('fd252f73-593c-4c4e-8584-c032b8022adc', all_views[1].id) - self.assertEqual('Overview', all_views[1].name) - self.assertEqual('Superstore/sheets/Overview', all_views[1].content_url) - self.assertEqual('6d13b0ca-043d-4d42-8c9d-3f3313ea3a00', all_views[1].workbook_id) - self.assertEqual('5de011f8-5aa9-4d5b-b991-f462c8dd6bb7', all_views[1].owner_id) - self.assertEqual('5b534f74-3226-11e8-b47a-cb2e00f738a3', all_views[1].project_id) - self.assertEqual('2002-05-30T09:00:00Z', format_datetime(all_views[1].created_at)) - self.assertEqual('2002-06-05T08:00:59Z', format_datetime(all_views[1].updated_at)) - self.assertEqual('story', all_views[1].sheet_type) + self.assertEqual("fd252f73-593c-4c4e-8584-c032b8022adc", all_views[1].id) + self.assertEqual("Overview", all_views[1].name) + self.assertEqual("Superstore/sheets/Overview", all_views[1].content_url) + self.assertEqual("6d13b0ca-043d-4d42-8c9d-3f3313ea3a00", all_views[1].workbook_id) + self.assertEqual("5de011f8-5aa9-4d5b-b991-f462c8dd6bb7", all_views[1].owner_id) + self.assertEqual("5b534f74-3226-11e8-b47a-cb2e00f738a3", all_views[1].project_id) + self.assertEqual("2002-05-30T09:00:00Z", format_datetime(all_views[1].created_at)) + self.assertEqual("2002-06-05T08:00:59Z", format_datetime(all_views[1].updated_at)) + self.assertEqual("story", all_views[1].sheet_type) def test_get_by_id(self): - with open(GET_XML_ID, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(GET_XML_ID, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: - m.get(self.baseurl + '/d79634e1-6063-4ec9-95ff-50acbf609ff5', text=response_xml) - view = self.server.views.get_by_id('d79634e1-6063-4ec9-95ff-50acbf609ff5') - - self.assertEqual('d79634e1-6063-4ec9-95ff-50acbf609ff5', view.id) - self.assertEqual('ENDANGERED SAFARI', view.name) - self.assertEqual('SafariSample/sheets/ENDANGEREDSAFARI', view.content_url) - self.assertEqual('3cc6cd06-89ce-4fdc-b935-5294135d6d42', view.workbook_id) - self.assertEqual('5de011f8-5aa9-4d5b-b991-f462c8dd6bb7', view.owner_id) - self.assertEqual('5241e88d-d384-4fd7-9c2f-648b5247efc5', view.project_id) - self.assertEqual(set(['tag1', 'tag2']), view.tags) - self.assertEqual('2002-05-30T09:00:00Z', format_datetime(view.created_at)) - self.assertEqual('2002-06-05T08:00:59Z', format_datetime(view.updated_at)) - self.assertEqual('story', view.sheet_type) + m.get(self.baseurl + "/d79634e1-6063-4ec9-95ff-50acbf609ff5", text=response_xml) + view = self.server.views.get_by_id("d79634e1-6063-4ec9-95ff-50acbf609ff5") + + self.assertEqual("d79634e1-6063-4ec9-95ff-50acbf609ff5", view.id) + self.assertEqual("ENDANGERED SAFARI", view.name) + self.assertEqual("SafariSample/sheets/ENDANGEREDSAFARI", view.content_url) + self.assertEqual("3cc6cd06-89ce-4fdc-b935-5294135d6d42", view.workbook_id) + self.assertEqual("5de011f8-5aa9-4d5b-b991-f462c8dd6bb7", view.owner_id) + self.assertEqual("5241e88d-d384-4fd7-9c2f-648b5247efc5", view.project_id) + self.assertEqual(set(["tag1", "tag2"]), view.tags) + self.assertEqual("2002-05-30T09:00:00Z", format_datetime(view.created_at)) + self.assertEqual("2002-06-05T08:00:59Z", format_datetime(view.updated_at)) + self.assertEqual("story", view.sheet_type) def test_get_by_id_missing_id(self): self.assertRaises(TSC.MissingRequiredFieldError, self.server.views.get_by_id, None) def test_get_with_usage(self): - with open(GET_XML_USAGE, 'rb') as f: - response_xml = f.read().decode('utf-8') + 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", text=response_xml) all_views, pagination_item = self.server.views.get(usage=True) - self.assertEqual('d79634e1-6063-4ec9-95ff-50acbf609ff5', all_views[0].id) + self.assertEqual("d79634e1-6063-4ec9-95ff-50acbf609ff5", all_views[0].id) self.assertEqual(7, all_views[0].total_views) self.assertIsNone(all_views[0].created_at) self.assertIsNone(all_views[0].updated_at) self.assertIsNone(all_views[0].sheet_type) - self.assertEqual('fd252f73-593c-4c4e-8584-c032b8022adc', all_views[1].id) + self.assertEqual("fd252f73-593c-4c4e-8584-c032b8022adc", all_views[1].id) self.assertEqual(13, all_views[1].total_views) - self.assertEqual('2002-05-30T09:00:00Z', format_datetime(all_views[1].created_at)) - self.assertEqual('2002-06-05T08:00:59Z', format_datetime(all_views[1].updated_at)) - self.assertEqual('story', all_views[1].sheet_type) + self.assertEqual("2002-05-30T09:00:00Z", format_datetime(all_views[1].created_at)) + self.assertEqual("2002-06-05T08:00:59Z", format_datetime(all_views[1].updated_at)) + self.assertEqual("story", all_views[1].sheet_type) def test_get_with_usage_and_filter(self): - with open(GET_XML_USAGE, 'rb') as f: - response_xml = f.read().decode('utf-8') + 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"])) + 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) @@ -121,56 +122,62 @@ def test_get_before_signin(self): self.assertRaises(TSC.NotSignedInError, self.server.views.get) def test_populate_preview_image(self): - with open(POPULATE_PREVIEW_IMAGE, 'rb') as f: + with open(POPULATE_PREVIEW_IMAGE, "rb") as f: response = f.read() with requests_mock.mock() as m: - m.get(self.siteurl + '/workbooks/3cc6cd06-89ce-4fdc-b935-5294135d6d42/' - 'views/d79634e1-6063-4ec9-95ff-50acbf609ff5/previewImage', content=response) + m.get( + self.siteurl + "/workbooks/3cc6cd06-89ce-4fdc-b935-5294135d6d42/" + "views/d79634e1-6063-4ec9-95ff-50acbf609ff5/previewImage", + content=response, + ) single_view = TSC.ViewItem() - single_view._id = 'd79634e1-6063-4ec9-95ff-50acbf609ff5' - single_view._workbook_id = '3cc6cd06-89ce-4fdc-b935-5294135d6d42' + single_view._id = "d79634e1-6063-4ec9-95ff-50acbf609ff5" + single_view._workbook_id = "3cc6cd06-89ce-4fdc-b935-5294135d6d42" self.server.views.populate_preview_image(single_view) self.assertEqual(response, single_view.preview_image) def test_populate_preview_image_missing_id(self): single_view = TSC.ViewItem() - single_view._id = 'd79634e1-6063-4ec9-95ff-50acbf609ff5' + single_view._id = "d79634e1-6063-4ec9-95ff-50acbf609ff5" self.assertRaises(TSC.MissingRequiredFieldError, self.server.views.populate_preview_image, single_view) single_view._id = None - single_view._workbook_id = '3cc6cd06-89ce-4fdc-b935-5294135d6d42' + single_view._workbook_id = "3cc6cd06-89ce-4fdc-b935-5294135d6d42" self.assertRaises(TSC.MissingRequiredFieldError, self.server.views.populate_preview_image, single_view) def test_populate_image(self): - with open(POPULATE_PREVIEW_IMAGE, 'rb') as f: + with open(POPULATE_PREVIEW_IMAGE, "rb") as f: response = f.read() with requests_mock.mock() as m: - m.get(self.baseurl + '/d79634e1-6063-4ec9-95ff-50acbf609ff5/image', content=response) + m.get(self.baseurl + "/d79634e1-6063-4ec9-95ff-50acbf609ff5/image", content=response) single_view = TSC.ViewItem() - single_view._id = 'd79634e1-6063-4ec9-95ff-50acbf609ff5' + single_view._id = "d79634e1-6063-4ec9-95ff-50acbf609ff5" self.server.views.populate_image(single_view) self.assertEqual(response, single_view.image) def test_populate_image_with_options(self): - with open(POPULATE_PREVIEW_IMAGE, 'rb') as f: + with open(POPULATE_PREVIEW_IMAGE, "rb") as f: response = f.read() with requests_mock.mock() as m: - m.get(self.baseurl + '/d79634e1-6063-4ec9-95ff-50acbf609ff5/image?resolution=high&maxAge=10', - content=response) + m.get( + self.baseurl + "/d79634e1-6063-4ec9-95ff-50acbf609ff5/image?resolution=high&maxAge=10", content=response + ) single_view = TSC.ViewItem() - single_view._id = 'd79634e1-6063-4ec9-95ff-50acbf609ff5' + single_view._id = "d79634e1-6063-4ec9-95ff-50acbf609ff5" req_option = TSC.ImageRequestOptions(imageresolution=TSC.ImageRequestOptions.Resolution.High, maxage=10) self.server.views.populate_image(single_view, req_option) self.assertEqual(response, single_view.image) def test_populate_pdf(self): - with open(POPULATE_PDF, 'rb') as f: + with open(POPULATE_PDF, "rb") as f: response = f.read() with requests_mock.mock() as m: - m.get(self.baseurl + '/d79634e1-6063-4ec9-95ff-50acbf609ff5/pdf?type=letter&orientation=portrait&maxAge=5', - content=response) + m.get( + self.baseurl + "/d79634e1-6063-4ec9-95ff-50acbf609ff5/pdf?type=letter&orientation=portrait&maxAge=5", + content=response, + ) single_view = TSC.ViewItem() - single_view._id = 'd79634e1-6063-4ec9-95ff-50acbf609ff5' + single_view._id = "d79634e1-6063-4ec9-95ff-50acbf609ff5" size = TSC.PDFRequestOptions.PageType.Letter orientation = TSC.PDFRequestOptions.Orientation.Portrait @@ -180,12 +187,12 @@ def test_populate_pdf(self): self.assertEqual(response, single_view.pdf) def test_populate_csv(self): - with open(POPULATE_CSV, 'rb') as f: + with open(POPULATE_CSV, "rb") as f: response = f.read() with requests_mock.mock() as m: - m.get(self.baseurl + '/d79634e1-6063-4ec9-95ff-50acbf609ff5/data?maxAge=1', content=response) + m.get(self.baseurl + "/d79634e1-6063-4ec9-95ff-50acbf609ff5/data?maxAge=1", content=response) single_view = TSC.ViewItem() - single_view._id = 'd79634e1-6063-4ec9-95ff-50acbf609ff5' + single_view._id = "d79634e1-6063-4ec9-95ff-50acbf609ff5" request_option = TSC.CSVRequestOptions(maxage=1) self.server.views.populate_csv(single_view, request_option) @@ -193,12 +200,12 @@ def test_populate_csv(self): self.assertEqual(response, csv_file) def test_populate_csv_default_maxage(self): - with open(POPULATE_CSV, 'rb') as f: + with open(POPULATE_CSV, "rb") as f: response = f.read() with requests_mock.mock() as m: - m.get(self.baseurl + '/d79634e1-6063-4ec9-95ff-50acbf609ff5/data', content=response) + m.get(self.baseurl + "/d79634e1-6063-4ec9-95ff-50acbf609ff5/data", content=response) single_view = TSC.ViewItem() - single_view._id = 'd79634e1-6063-4ec9-95ff-50acbf609ff5' + single_view._id = "d79634e1-6063-4ec9-95ff-50acbf609ff5" self.server.views.populate_csv(single_view) csv_file = b"".join(single_view.csv) @@ -210,8 +217,8 @@ def test_populate_image_missing_id(self): self.assertRaises(TSC.MissingRequiredFieldError, self.server.views.populate_image, single_view) def test_populate_permissions(self): - with open(POPULATE_PERMISSIONS_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(POPULATE_PERMISSIONS_XML, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: m.get(self.baseurl + "/e490bec4-2652-4fda-8c4e-f087db6fa328/permissions", text=response_xml) single_view = TSC.ViewItem() @@ -220,62 +227,57 @@ def test_populate_permissions(self): self.server.views.populate_permissions(single_view) permissions = single_view.permissions - self.assertEqual(permissions[0].grantee.tag_name, 'group') - self.assertEqual(permissions[0].grantee.id, 'c8f2773a-c83a-11e8-8c8f-33e6d787b506') - self.assertDictEqual(permissions[0].capabilities, { - TSC.Permission.Capability.ViewComments: TSC.Permission.Mode.Allow, - TSC.Permission.Capability.Read: TSC.Permission.Mode.Allow, - TSC.Permission.Capability.AddComment: TSC.Permission.Mode.Allow, - TSC.Permission.Capability.ExportData: TSC.Permission.Mode.Allow, - TSC.Permission.Capability.ExportImage: TSC.Permission.Mode.Allow, - - }) + self.assertEqual(permissions[0].grantee.tag_name, "group") + self.assertEqual(permissions[0].grantee.id, "c8f2773a-c83a-11e8-8c8f-33e6d787b506") + self.assertDictEqual( + permissions[0].capabilities, + { + TSC.Permission.Capability.ViewComments: TSC.Permission.Mode.Allow, + TSC.Permission.Capability.Read: TSC.Permission.Mode.Allow, + TSC.Permission.Capability.AddComment: TSC.Permission.Mode.Allow, + TSC.Permission.Capability.ExportData: TSC.Permission.Mode.Allow, + TSC.Permission.Capability.ExportImage: TSC.Permission.Mode.Allow, + }, + ) def test_add_permissions(self): - with open(UPDATE_PERMISSIONS, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(UPDATE_PERMISSIONS, "rb") as f: + response_xml = f.read().decode("utf-8") single_view = TSC.ViewItem() - single_view._id = '21778de4-b7b9-44bc-a599-1506a2639ace' + single_view._id = "21778de4-b7b9-44bc-a599-1506a2639ace" bob = UserItem.as_reference("7c37ee24-c4b1-42b6-a154-eaeab7ee330a") group_of_people = GroupItem.as_reference("5e5e1978-71fa-11e4-87dd-7382f5c437af") - new_permissions = [ - PermissionsRule(bob, {'Write': 'Allow'}), - PermissionsRule(group_of_people, {'Read': 'Deny'}) - ] + new_permissions = [PermissionsRule(bob, {"Write": "Allow"}), PermissionsRule(group_of_people, {"Read": "Deny"})] with requests_mock.mock() as m: m.put(self.baseurl + "/21778de4-b7b9-44bc-a599-1506a2639ace/permissions", text=response_xml) permissions = self.server.views.update_permissions(single_view, new_permissions) - self.assertEqual(permissions[0].grantee.tag_name, 'group') - self.assertEqual(permissions[0].grantee.id, '5e5e1978-71fa-11e4-87dd-7382f5c437af') - self.assertDictEqual(permissions[0].capabilities, { - TSC.Permission.Capability.Read: TSC.Permission.Mode.Deny - }) + self.assertEqual(permissions[0].grantee.tag_name, "group") + self.assertEqual(permissions[0].grantee.id, "5e5e1978-71fa-11e4-87dd-7382f5c437af") + self.assertDictEqual(permissions[0].capabilities, {TSC.Permission.Capability.Read: TSC.Permission.Mode.Deny}) - self.assertEqual(permissions[1].grantee.tag_name, 'user') - self.assertEqual(permissions[1].grantee.id, '7c37ee24-c4b1-42b6-a154-eaeab7ee330a') - self.assertDictEqual(permissions[1].capabilities, { - TSC.Permission.Capability.Write: TSC.Permission.Mode.Allow - }) + self.assertEqual(permissions[1].grantee.tag_name, "user") + self.assertEqual(permissions[1].grantee.id, "7c37ee24-c4b1-42b6-a154-eaeab7ee330a") + self.assertDictEqual(permissions[1].capabilities, {TSC.Permission.Capability.Write: TSC.Permission.Mode.Allow}) def test_update_tags(self): - with open(ADD_TAGS_XML, 'rb') as f: - add_tags_xml = f.read().decode('utf-8') - with open(UPDATE_XML, 'rb') as f: - update_xml = f.read().decode('utf-8') + with open(ADD_TAGS_XML, "rb") as f: + add_tags_xml = f.read().decode("utf-8") + with open(UPDATE_XML, "rb") as f: + update_xml = f.read().decode("utf-8") with requests_mock.mock() as m: - m.put(self.baseurl + '/d79634e1-6063-4ec9-95ff-50acbf609ff5/tags', text=add_tags_xml) - m.delete(self.baseurl + '/d79634e1-6063-4ec9-95ff-50acbf609ff5/tags/b', status_code=204) - m.delete(self.baseurl + '/d79634e1-6063-4ec9-95ff-50acbf609ff5/tags/d', status_code=204) - m.put(self.baseurl + '/d79634e1-6063-4ec9-95ff-50acbf609ff5', text=update_xml) + m.put(self.baseurl + "/d79634e1-6063-4ec9-95ff-50acbf609ff5/tags", text=add_tags_xml) + m.delete(self.baseurl + "/d79634e1-6063-4ec9-95ff-50acbf609ff5/tags/b", status_code=204) + m.delete(self.baseurl + "/d79634e1-6063-4ec9-95ff-50acbf609ff5/tags/d", status_code=204) + m.put(self.baseurl + "/d79634e1-6063-4ec9-95ff-50acbf609ff5", text=update_xml) single_view = TSC.ViewItem() - single_view._id = 'd79634e1-6063-4ec9-95ff-50acbf609ff5' - single_view._initial_tags.update(['a', 'b', 'c', 'd']) - single_view.tags.update(['a', 'c', 'e']) + single_view._id = "d79634e1-6063-4ec9-95ff-50acbf609ff5" + single_view._initial_tags.update(["a", "b", "c", "d"]) + single_view.tags.update(["a", "c", "e"]) updated_view = self.server.views.update(single_view) self.assertEqual(single_view.tags, updated_view.tags) diff --git a/test/test_webhook.py b/test/test_webhook.py index 819de18ae..64c201af5 100644 --- a/test/test_webhook.py +++ b/test/test_webhook.py @@ -6,27 +6,27 @@ from ._utils import read_xml_asset, read_xml_assets, asset -TEST_ASSET_DIR = os.path.join(os.path.dirname(__file__), 'assets') +TEST_ASSET_DIR = os.path.join(os.path.dirname(__file__), "assets") -GET_XML = asset('webhook_get.xml') -CREATE_XML = asset('webhook_create.xml') -CREATE_REQUEST_XML = asset('webhook_create_request.xml') +GET_XML = asset("webhook_get.xml") +CREATE_XML = asset("webhook_create.xml") +CREATE_REQUEST_XML = asset("webhook_create_request.xml") class WebhookTests(unittest.TestCase): def setUp(self): - self.server = TSC.Server('http://test') + self.server = TSC.Server("http://test") self.server.version = "3.6" # Fake signin - self.server._site_id = 'dad65087-b08b-4603-af4e-2887b8aafc67' - self.server._auth_token = 'j80k54ll2lfMZ0tv97mlPvvSCRyD0DOM' + self.server._site_id = "dad65087-b08b-4603-af4e-2887b8aafc67" + self.server._auth_token = "j80k54ll2lfMZ0tv97mlPvvSCRyD0DOM" self.baseurl = self.server.webhooks.baseurl def test_get(self): - with open(GET_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(GET_XML, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: m.get(self.baseurl, text=response_xml) webhooks, _ = self.server.webhooks.get() @@ -45,20 +45,20 @@ def test_get_before_signin(self): def test_delete(self): with requests_mock.mock() as m: - m.delete(self.baseurl + '/ee8c6e70-43b6-11e6-af4f-f7b0d8e20760', status_code=204) - self.server.webhooks.delete('ee8c6e70-43b6-11e6-af4f-f7b0d8e20760') + m.delete(self.baseurl + "/ee8c6e70-43b6-11e6-af4f-f7b0d8e20760", status_code=204) + self.server.webhooks.delete("ee8c6e70-43b6-11e6-af4f-f7b0d8e20760") def test_delete_missing_id(self): - self.assertRaises(ValueError, self.server.webhooks.delete, '') + self.assertRaises(ValueError, self.server.webhooks.delete, "") def test_test(self): with requests_mock.mock() as m: - m.get(self.baseurl + '/ee8c6e70-43b6-11e6-af4f-f7b0d8e20760/test', status_code=200) - self.server.webhooks.test('ee8c6e70-43b6-11e6-af4f-f7b0d8e20760') + m.get(self.baseurl + "/ee8c6e70-43b6-11e6-af4f-f7b0d8e20760/test", status_code=200) + self.server.webhooks.test("ee8c6e70-43b6-11e6-af4f-f7b0d8e20760") def test_create(self): - with open(CREATE_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(CREATE_XML, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: m.post(self.baseurl, text=response_xml) webhook_model = TSC.WebhookItem() @@ -71,13 +71,12 @@ def test_create(self): self.assertNotEqual(new_webhook.id, None) def test_request_factory(self): - with open(CREATE_REQUEST_XML, 'rb') as f: - webhook_request_expected = f.read().decode('utf-8') + with open(CREATE_REQUEST_XML, "rb") as f: + webhook_request_expected = f.read().decode("utf-8") webhook_item = WebhookItem() - webhook_item._set_values("webhook-id", "webhook-name", "url", "api-event-name", - None) - webhook_request_actual = '{}\n'.format(RequestFactory.Webhook.create_req(webhook_item).decode('utf-8')) + webhook_item._set_values("webhook-id", "webhook-name", "url", "api-event-name", None) + webhook_request_actual = "{}\n".format(RequestFactory.Webhook.create_req(webhook_item).decode("utf-8")) self.maxDiff = None # windows does /r/n for linebreaks, remove the extra char if it is there - self.assertEqual(webhook_request_expected.replace('\r', ''), webhook_request_actual) + self.assertEqual(webhook_request_expected.replace("\r", ""), webhook_request_actual) diff --git a/test/test_workbook.py b/test/test_workbook.py index b73c000f5..cf6bce1f3 100644 --- a/test/test_workbook.py +++ b/test/test_workbook.py @@ -17,89 +17,90 @@ from ._utils import asset -TEST_ASSET_DIR = os.path.join(os.path.dirname(__file__), 'assets') - -ADD_TAGS_XML = os.path.join(TEST_ASSET_DIR, 'workbook_add_tags.xml') -GET_BY_ID_XML = os.path.join(TEST_ASSET_DIR, 'workbook_get_by_id.xml') -GET_BY_ID_XML_PERSONAL = os.path.join(TEST_ASSET_DIR, 'workbook_get_by_id_personal.xml') -GET_EMPTY_XML = os.path.join(TEST_ASSET_DIR, 'workbook_get_empty.xml') -GET_INVALID_DATE_XML = os.path.join(TEST_ASSET_DIR, 'workbook_get_invalid_date.xml') -GET_XML = os.path.join(TEST_ASSET_DIR, 'workbook_get.xml') -POPULATE_CONNECTIONS_XML = os.path.join(TEST_ASSET_DIR, 'workbook_populate_connections.xml') -POPULATE_PDF = os.path.join(TEST_ASSET_DIR, 'populate_pdf.pdf') -POPULATE_PERMISSIONS_XML = os.path.join(TEST_ASSET_DIR, 'workbook_populate_permissions.xml') -POPULATE_PREVIEW_IMAGE = os.path.join(TEST_ASSET_DIR, 'RESTAPISample Image.png') -POPULATE_VIEWS_XML = os.path.join(TEST_ASSET_DIR, 'workbook_populate_views.xml') -POPULATE_VIEWS_USAGE_XML = os.path.join(TEST_ASSET_DIR, 'workbook_populate_views_usage.xml') -PUBLISH_XML = os.path.join(TEST_ASSET_DIR, 'workbook_publish.xml') -PUBLISH_ASYNC_XML = os.path.join(TEST_ASSET_DIR, 'workbook_publish_async.xml') -REFRESH_XML = os.path.join(TEST_ASSET_DIR, 'workbook_refresh.xml') -REVISION_XML = os.path.join(TEST_ASSET_DIR, 'workbook_revision.xml') -UPDATE_XML = os.path.join(TEST_ASSET_DIR, 'workbook_update.xml') -UPDATE_PERMISSIONS = os.path.join(TEST_ASSET_DIR, 'workbook_update_permissions.xml') + +TEST_ASSET_DIR = os.path.join(os.path.dirname(__file__), "assets") + +ADD_TAGS_XML = os.path.join(TEST_ASSET_DIR, "workbook_add_tags.xml") +GET_BY_ID_XML = os.path.join(TEST_ASSET_DIR, "workbook_get_by_id.xml") +GET_BY_ID_XML_PERSONAL = os.path.join(TEST_ASSET_DIR, "workbook_get_by_id_personal.xml") +GET_EMPTY_XML = os.path.join(TEST_ASSET_DIR, "workbook_get_empty.xml") +GET_INVALID_DATE_XML = os.path.join(TEST_ASSET_DIR, "workbook_get_invalid_date.xml") +GET_XML = os.path.join(TEST_ASSET_DIR, "workbook_get.xml") +POPULATE_CONNECTIONS_XML = os.path.join(TEST_ASSET_DIR, "workbook_populate_connections.xml") +POPULATE_PDF = os.path.join(TEST_ASSET_DIR, "populate_pdf.pdf") +POPULATE_PERMISSIONS_XML = os.path.join(TEST_ASSET_DIR, "workbook_populate_permissions.xml") +POPULATE_PREVIEW_IMAGE = os.path.join(TEST_ASSET_DIR, "RESTAPISample Image.png") +POPULATE_VIEWS_XML = os.path.join(TEST_ASSET_DIR, "workbook_populate_views.xml") +POPULATE_VIEWS_USAGE_XML = os.path.join(TEST_ASSET_DIR, "workbook_populate_views_usage.xml") +PUBLISH_XML = os.path.join(TEST_ASSET_DIR, "workbook_publish.xml") +PUBLISH_ASYNC_XML = os.path.join(TEST_ASSET_DIR, "workbook_publish_async.xml") +REFRESH_XML = os.path.join(TEST_ASSET_DIR, "workbook_refresh.xml") +REVISION_XML = os.path.join(TEST_ASSET_DIR, "workbook_revision.xml") +UPDATE_XML = os.path.join(TEST_ASSET_DIR, "workbook_update.xml") +UPDATE_PERMISSIONS = os.path.join(TEST_ASSET_DIR, "workbook_update_permissions.xml") class WorkbookTests(unittest.TestCase): def setUp(self) -> None: - self.server = TSC.Server('http://test') + self.server = TSC.Server("http://test") # Fake sign in - self.server._site_id = 'dad65087-b08b-4603-af4e-2887b8aafc67' - self.server._auth_token = 'j80k54ll2lfMZ0tv97mlPvvSCRyD0DOM' + self.server._site_id = "dad65087-b08b-4603-af4e-2887b8aafc67" + self.server._auth_token = "j80k54ll2lfMZ0tv97mlPvvSCRyD0DOM" self.baseurl = self.server.workbooks.baseurl def test_get(self) -> None: - with open(GET_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(GET_XML, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: m.get(self.baseurl, text=response_xml) all_workbooks, pagination_item = self.server.workbooks.get() self.assertEqual(2, pagination_item.total_available) - self.assertEqual('6d13b0ca-043d-4d42-8c9d-3f3313ea3a00', all_workbooks[0].id) - self.assertEqual('Superstore', all_workbooks[0].name) - self.assertEqual('Superstore', all_workbooks[0].content_url) + self.assertEqual("6d13b0ca-043d-4d42-8c9d-3f3313ea3a00", all_workbooks[0].id) + self.assertEqual("Superstore", all_workbooks[0].name) + self.assertEqual("Superstore", all_workbooks[0].content_url) self.assertEqual(False, all_workbooks[0].show_tabs) - self.assertEqual('http://tableauserver/#/workbooks/1/views', all_workbooks[0].webpage_url) + self.assertEqual("http://tableauserver/#/workbooks/1/views", all_workbooks[0].webpage_url) self.assertEqual(1, all_workbooks[0].size) - self.assertEqual('2016-08-03T20:34:04Z', format_datetime(all_workbooks[0].created_at)) - self.assertEqual('description for Superstore', all_workbooks[0].description) - self.assertEqual('2016-08-04T17:56:41Z', format_datetime(all_workbooks[0].updated_at)) - self.assertEqual('ee8c6e70-43b6-11e6-af4f-f7b0d8e20760', all_workbooks[0].project_id) - self.assertEqual('default', all_workbooks[0].project_name) - self.assertEqual('5de011f8-5aa9-4d5b-b991-f462c8dd6bb7', all_workbooks[0].owner_id) - - self.assertEqual('3cc6cd06-89ce-4fdc-b935-5294135d6d42', all_workbooks[1].id) - self.assertEqual('SafariSample', all_workbooks[1].name) - self.assertEqual('SafariSample', all_workbooks[1].content_url) - self.assertEqual('http://tableauserver/#/workbooks/2/views', all_workbooks[1].webpage_url) + self.assertEqual("2016-08-03T20:34:04Z", format_datetime(all_workbooks[0].created_at)) + self.assertEqual("description for Superstore", all_workbooks[0].description) + self.assertEqual("2016-08-04T17:56:41Z", format_datetime(all_workbooks[0].updated_at)) + self.assertEqual("ee8c6e70-43b6-11e6-af4f-f7b0d8e20760", all_workbooks[0].project_id) + self.assertEqual("default", all_workbooks[0].project_name) + self.assertEqual("5de011f8-5aa9-4d5b-b991-f462c8dd6bb7", all_workbooks[0].owner_id) + + self.assertEqual("3cc6cd06-89ce-4fdc-b935-5294135d6d42", all_workbooks[1].id) + self.assertEqual("SafariSample", all_workbooks[1].name) + self.assertEqual("SafariSample", all_workbooks[1].content_url) + self.assertEqual("http://tableauserver/#/workbooks/2/views", all_workbooks[1].webpage_url) self.assertEqual(False, all_workbooks[1].show_tabs) self.assertEqual(26, all_workbooks[1].size) - self.assertEqual('2016-07-26T20:34:56Z', format_datetime(all_workbooks[1].created_at)) - self.assertEqual('description for SafariSample', all_workbooks[1].description) - self.assertEqual('2016-07-26T20:35:05Z', format_datetime(all_workbooks[1].updated_at)) - self.assertEqual('ee8c6e70-43b6-11e6-af4f-f7b0d8e20760', all_workbooks[1].project_id) - self.assertEqual('default', all_workbooks[1].project_name) - self.assertEqual('5de011f8-5aa9-4d5b-b991-f462c8dd6bb7', all_workbooks[1].owner_id) - self.assertEqual(set(['Safari', 'Sample']), all_workbooks[1].tags) + self.assertEqual("2016-07-26T20:34:56Z", format_datetime(all_workbooks[1].created_at)) + self.assertEqual("description for SafariSample", all_workbooks[1].description) + self.assertEqual("2016-07-26T20:35:05Z", format_datetime(all_workbooks[1].updated_at)) + self.assertEqual("ee8c6e70-43b6-11e6-af4f-f7b0d8e20760", all_workbooks[1].project_id) + self.assertEqual("default", all_workbooks[1].project_name) + self.assertEqual("5de011f8-5aa9-4d5b-b991-f462c8dd6bb7", all_workbooks[1].owner_id) + self.assertEqual(set(["Safari", "Sample"]), all_workbooks[1].tags) def test_get_ignore_invalid_date(self) -> None: - with open(GET_INVALID_DATE_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(GET_INVALID_DATE_XML, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: m.get(self.baseurl, text=response_xml) all_workbooks, pagination_item = self.server.workbooks.get() self.assertEqual(None, format_datetime(all_workbooks[0].created_at)) - self.assertEqual('2016-08-04T17:56:41Z', format_datetime(all_workbooks[0].updated_at)) + self.assertEqual("2016-08-04T17:56:41Z", format_datetime(all_workbooks[0].updated_at)) def test_get_before_signin(self) -> None: self.server._auth_token = None self.assertRaises(TSC.NotSignedInError, self.server.workbooks.get) def test_get_empty(self) -> None: - with open(GET_EMPTY_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(GET_EMPTY_XML, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: m.get(self.baseurl, text=response_xml) all_workbooks, pagination_item = self.server.workbooks.get() @@ -108,124 +109,124 @@ def test_get_empty(self) -> None: self.assertEqual([], all_workbooks) def test_get_by_id(self) -> None: - with open(GET_BY_ID_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(GET_BY_ID_XML, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: - m.get(self.baseurl + '/3cc6cd06-89ce-4fdc-b935-5294135d6d42', text=response_xml) - single_workbook = self.server.workbooks.get_by_id('3cc6cd06-89ce-4fdc-b935-5294135d6d42') + m.get(self.baseurl + "/3cc6cd06-89ce-4fdc-b935-5294135d6d42", text=response_xml) + single_workbook = self.server.workbooks.get_by_id("3cc6cd06-89ce-4fdc-b935-5294135d6d42") - self.assertEqual('3cc6cd06-89ce-4fdc-b935-5294135d6d42', single_workbook.id) - self.assertEqual('SafariSample', single_workbook.name) - self.assertEqual('SafariSample', single_workbook.content_url) - self.assertEqual('http://tableauserver/#/workbooks/2/views', single_workbook.webpage_url) + self.assertEqual("3cc6cd06-89ce-4fdc-b935-5294135d6d42", single_workbook.id) + self.assertEqual("SafariSample", single_workbook.name) + self.assertEqual("SafariSample", single_workbook.content_url) + self.assertEqual("http://tableauserver/#/workbooks/2/views", single_workbook.webpage_url) self.assertEqual(False, single_workbook.show_tabs) self.assertEqual(26, single_workbook.size) - self.assertEqual('2016-07-26T20:34:56Z', format_datetime(single_workbook.created_at)) - self.assertEqual('description for SafariSample', single_workbook.description) - self.assertEqual('2016-07-26T20:35:05Z', format_datetime(single_workbook.updated_at)) - self.assertEqual('ee8c6e70-43b6-11e6-af4f-f7b0d8e20760', single_workbook.project_id) - self.assertEqual('default', single_workbook.project_name) - self.assertEqual('5de011f8-5aa9-4d5b-b991-f462c8dd6bb7', single_workbook.owner_id) - self.assertEqual(set(['Safari', 'Sample']), single_workbook.tags) - self.assertEqual('d79634e1-6063-4ec9-95ff-50acbf609ff5', single_workbook.views[0].id) - self.assertEqual('ENDANGERED SAFARI', single_workbook.views[0].name) - self.assertEqual('SafariSample/sheets/ENDANGEREDSAFARI', single_workbook.views[0].content_url) + self.assertEqual("2016-07-26T20:34:56Z", format_datetime(single_workbook.created_at)) + self.assertEqual("description for SafariSample", single_workbook.description) + self.assertEqual("2016-07-26T20:35:05Z", format_datetime(single_workbook.updated_at)) + self.assertEqual("ee8c6e70-43b6-11e6-af4f-f7b0d8e20760", single_workbook.project_id) + self.assertEqual("default", single_workbook.project_name) + self.assertEqual("5de011f8-5aa9-4d5b-b991-f462c8dd6bb7", single_workbook.owner_id) + self.assertEqual(set(["Safari", "Sample"]), single_workbook.tags) + self.assertEqual("d79634e1-6063-4ec9-95ff-50acbf609ff5", single_workbook.views[0].id) + self.assertEqual("ENDANGERED SAFARI", single_workbook.views[0].name) + self.assertEqual("SafariSample/sheets/ENDANGEREDSAFARI", single_workbook.views[0].content_url) def test_get_by_id_personal(self) -> None: # workbooks in personal space don't have project_id or project_name - with open(GET_BY_ID_XML_PERSONAL, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(GET_BY_ID_XML_PERSONAL, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: - m.get(self.baseurl + '/3cc6cd06-89ce-4fdc-b935-5294135d6d43', text=response_xml) - single_workbook = self.server.workbooks.get_by_id('3cc6cd06-89ce-4fdc-b935-5294135d6d43') + m.get(self.baseurl + "/3cc6cd06-89ce-4fdc-b935-5294135d6d43", text=response_xml) + single_workbook = self.server.workbooks.get_by_id("3cc6cd06-89ce-4fdc-b935-5294135d6d43") - self.assertEqual('3cc6cd06-89ce-4fdc-b935-5294135d6d43', single_workbook.id) - self.assertEqual('SafariSample', single_workbook.name) - self.assertEqual('SafariSample', single_workbook.content_url) - self.assertEqual('http://tableauserver/#/workbooks/2/views', single_workbook.webpage_url) + self.assertEqual("3cc6cd06-89ce-4fdc-b935-5294135d6d43", single_workbook.id) + self.assertEqual("SafariSample", single_workbook.name) + self.assertEqual("SafariSample", single_workbook.content_url) + self.assertEqual("http://tableauserver/#/workbooks/2/views", single_workbook.webpage_url) self.assertEqual(False, single_workbook.show_tabs) self.assertEqual(26, single_workbook.size) - self.assertEqual('2016-07-26T20:34:56Z', format_datetime(single_workbook.created_at)) - self.assertEqual('description for SafariSample', single_workbook.description) - self.assertEqual('2016-07-26T20:35:05Z', format_datetime(single_workbook.updated_at)) + self.assertEqual("2016-07-26T20:34:56Z", format_datetime(single_workbook.created_at)) + self.assertEqual("description for SafariSample", single_workbook.description) + self.assertEqual("2016-07-26T20:35:05Z", format_datetime(single_workbook.updated_at)) self.assertTrue(single_workbook.project_id) self.assertIsNone(single_workbook.project_name) - self.assertEqual('5de011f8-5aa9-4d5b-b991-f462c8dd6bb7', single_workbook.owner_id) - self.assertEqual(set(['Safari', 'Sample']), single_workbook.tags) - self.assertEqual('d79634e1-6063-4ec9-95ff-50acbf609ff5', single_workbook.views[0].id) - self.assertEqual('ENDANGERED SAFARI', single_workbook.views[0].name) - self.assertEqual('SafariSample/sheets/ENDANGEREDSAFARI', single_workbook.views[0].content_url) + self.assertEqual("5de011f8-5aa9-4d5b-b991-f462c8dd6bb7", single_workbook.owner_id) + self.assertEqual(set(["Safari", "Sample"]), single_workbook.tags) + self.assertEqual("d79634e1-6063-4ec9-95ff-50acbf609ff5", single_workbook.views[0].id) + self.assertEqual("ENDANGERED SAFARI", single_workbook.views[0].name) + self.assertEqual("SafariSample/sheets/ENDANGEREDSAFARI", single_workbook.views[0].content_url) def test_get_by_id_missing_id(self) -> None: - self.assertRaises(ValueError, self.server.workbooks.get_by_id, '') + self.assertRaises(ValueError, self.server.workbooks.get_by_id, "") def test_refresh_id(self) -> None: - self.server.version = '2.8' + self.server.version = "2.8" self.baseurl = self.server.workbooks.baseurl - with open(REFRESH_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(REFRESH_XML, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: - m.post(self.baseurl + '/3cc6cd06-89ce-4fdc-b935-5294135d6d42/refresh', - status_code=202, text=response_xml) - self.server.workbooks.refresh('3cc6cd06-89ce-4fdc-b935-5294135d6d42') + m.post(self.baseurl + "/3cc6cd06-89ce-4fdc-b935-5294135d6d42/refresh", status_code=202, text=response_xml) + self.server.workbooks.refresh("3cc6cd06-89ce-4fdc-b935-5294135d6d42") def test_refresh_object(self) -> None: - self.server.version = '2.8' + self.server.version = "2.8" self.baseurl = self.server.workbooks.baseurl - workbook = TSC.WorkbookItem('') - workbook._id = '3cc6cd06-89ce-4fdc-b935-5294135d6d42' - with open(REFRESH_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') + workbook = TSC.WorkbookItem("") + workbook._id = "3cc6cd06-89ce-4fdc-b935-5294135d6d42" + with open(REFRESH_XML, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: - m.post(self.baseurl + '/3cc6cd06-89ce-4fdc-b935-5294135d6d42/refresh', - status_code=202, text=response_xml) + m.post(self.baseurl + "/3cc6cd06-89ce-4fdc-b935-5294135d6d42/refresh", status_code=202, text=response_xml) self.server.workbooks.refresh(workbook) def test_delete(self) -> None: with requests_mock.mock() as m: - m.delete(self.baseurl + '/3cc6cd06-89ce-4fdc-b935-5294135d6d42', status_code=204) - self.server.workbooks.delete('3cc6cd06-89ce-4fdc-b935-5294135d6d42') + m.delete(self.baseurl + "/3cc6cd06-89ce-4fdc-b935-5294135d6d42", status_code=204) + self.server.workbooks.delete("3cc6cd06-89ce-4fdc-b935-5294135d6d42") def test_delete_missing_id(self) -> None: - self.assertRaises(ValueError, self.server.workbooks.delete, '') + self.assertRaises(ValueError, self.server.workbooks.delete, "") def test_update(self) -> None: - with open(UPDATE_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') - with requests_mock.mock() as m: - m.put(self.baseurl + '/1f951daf-4061-451a-9df1-69a8062664f2', text=response_xml) - single_workbook = TSC.WorkbookItem('1d0304cd-3796-429f-b815-7258370b9b74', show_tabs=True) - single_workbook._id = '1f951daf-4061-451a-9df1-69a8062664f2' - single_workbook.owner_id = 'dd2239f6-ddf1-4107-981a-4cf94e415794' - single_workbook.name = 'renamedWorkbook' - single_workbook.data_acceleration_config = {'acceleration_enabled': True, - 'accelerate_now': False, - 'last_updated_at': None, - 'acceleration_status': None} + with open(UPDATE_XML, "rb") as f: + response_xml = f.read().decode("utf-8") + with requests_mock.mock() as m: + m.put(self.baseurl + "/1f951daf-4061-451a-9df1-69a8062664f2", text=response_xml) + single_workbook = TSC.WorkbookItem("1d0304cd-3796-429f-b815-7258370b9b74", show_tabs=True) + single_workbook._id = "1f951daf-4061-451a-9df1-69a8062664f2" + single_workbook.owner_id = "dd2239f6-ddf1-4107-981a-4cf94e415794" + single_workbook.name = "renamedWorkbook" + single_workbook.data_acceleration_config = { + "acceleration_enabled": True, + "accelerate_now": False, + "last_updated_at": None, + "acceleration_status": None, + } single_workbook = self.server.workbooks.update(single_workbook) - self.assertEqual('1f951daf-4061-451a-9df1-69a8062664f2', single_workbook.id) + self.assertEqual("1f951daf-4061-451a-9df1-69a8062664f2", single_workbook.id) self.assertEqual(True, single_workbook.show_tabs) - self.assertEqual('1d0304cd-3796-429f-b815-7258370b9b74', single_workbook.project_id) - self.assertEqual('dd2239f6-ddf1-4107-981a-4cf94e415794', single_workbook.owner_id) - self.assertEqual('renamedWorkbook', single_workbook.name) - self.assertEqual(True, single_workbook.data_acceleration_config['acceleration_enabled']) - self.assertEqual(False, single_workbook.data_acceleration_config['accelerate_now']) + self.assertEqual("1d0304cd-3796-429f-b815-7258370b9b74", single_workbook.project_id) + self.assertEqual("dd2239f6-ddf1-4107-981a-4cf94e415794", single_workbook.owner_id) + self.assertEqual("renamedWorkbook", single_workbook.name) + self.assertEqual(True, single_workbook.data_acceleration_config["acceleration_enabled"]) + self.assertEqual(False, single_workbook.data_acceleration_config["accelerate_now"]) def test_update_missing_id(self) -> None: - single_workbook = TSC.WorkbookItem('test') + single_workbook = TSC.WorkbookItem("test") self.assertRaises(TSC.MissingRequiredFieldError, self.server.workbooks.update, single_workbook) def test_update_copy_fields(self) -> None: - with open(POPULATE_CONNECTIONS_XML, 'rb') as f: - connection_xml = f.read().decode('utf-8') - with open(UPDATE_XML, 'rb') as f: - update_xml = f.read().decode('utf-8') - with requests_mock.mock() as m: - m.get(self.baseurl + '/1f951daf-4061-451a-9df1-69a8062664f2/connections', text=connection_xml) - m.put(self.baseurl + '/1f951daf-4061-451a-9df1-69a8062664f2', text=update_xml) - single_workbook = TSC.WorkbookItem('1d0304cd-3796-429f-b815-7258370b9b74') - single_workbook._id = '1f951daf-4061-451a-9df1-69a8062664f2' + with open(POPULATE_CONNECTIONS_XML, "rb") as f: + connection_xml = f.read().decode("utf-8") + with open(UPDATE_XML, "rb") as f: + update_xml = f.read().decode("utf-8") + with requests_mock.mock() as m: + m.get(self.baseurl + "/1f951daf-4061-451a-9df1-69a8062664f2/connections", text=connection_xml) + m.put(self.baseurl + "/1f951daf-4061-451a-9df1-69a8062664f2", text=update_xml) + single_workbook = TSC.WorkbookItem("1d0304cd-3796-429f-b815-7258370b9b74") + single_workbook._id = "1f951daf-4061-451a-9df1-69a8062664f2" self.server.workbooks.populate_connections(single_workbook) updated_workbook = self.server.workbooks.update(single_workbook) @@ -236,19 +237,19 @@ def test_update_copy_fields(self) -> None: self.assertEqual(single_workbook._preview_image, updated_workbook._preview_image) def test_update_tags(self) -> None: - with open(ADD_TAGS_XML, 'rb') as f: - add_tags_xml = f.read().decode('utf-8') - with open(UPDATE_XML, 'rb') as f: - update_xml = f.read().decode('utf-8') - with requests_mock.mock() as m: - m.put(self.baseurl + '/1f951daf-4061-451a-9df1-69a8062664f2/tags', text=add_tags_xml) - m.delete(self.baseurl + '/1f951daf-4061-451a-9df1-69a8062664f2/tags/b', status_code=204) - m.delete(self.baseurl + '/1f951daf-4061-451a-9df1-69a8062664f2/tags/d', status_code=204) - m.put(self.baseurl + '/1f951daf-4061-451a-9df1-69a8062664f2', text=update_xml) - single_workbook = TSC.WorkbookItem('1d0304cd-3796-429f-b815-7258370b9b74') - single_workbook._id = '1f951daf-4061-451a-9df1-69a8062664f2' - single_workbook._initial_tags.update(['a', 'b', 'c', 'd']) - single_workbook.tags.update(['a', 'c', 'e']) + with open(ADD_TAGS_XML, "rb") as f: + add_tags_xml = f.read().decode("utf-8") + with open(UPDATE_XML, "rb") as f: + update_xml = f.read().decode("utf-8") + with requests_mock.mock() as m: + m.put(self.baseurl + "/1f951daf-4061-451a-9df1-69a8062664f2/tags", text=add_tags_xml) + m.delete(self.baseurl + "/1f951daf-4061-451a-9df1-69a8062664f2/tags/b", status_code=204) + m.delete(self.baseurl + "/1f951daf-4061-451a-9df1-69a8062664f2/tags/d", status_code=204) + m.put(self.baseurl + "/1f951daf-4061-451a-9df1-69a8062664f2", text=update_xml) + single_workbook = TSC.WorkbookItem("1d0304cd-3796-429f-b815-7258370b9b74") + single_workbook._id = "1f951daf-4061-451a-9df1-69a8062664f2" + single_workbook._initial_tags.update(["a", "b", "c", "d"]) + single_workbook.tags.update(["a", "c", "e"]) updated_workbook = self.server.workbooks.update(single_workbook) self.assertEqual(single_workbook.tags, updated_workbook.tags) @@ -256,9 +257,11 @@ def test_update_tags(self) -> None: def test_download(self) -> None: with requests_mock.mock() as m: - m.get(self.baseurl + '/1f951daf-4061-451a-9df1-69a8062664f2/content', - headers={'Content-Disposition': 'name="tableau_workbook"; filename="RESTAPISample.twbx"'}) - file_path = self.server.workbooks.download('1f951daf-4061-451a-9df1-69a8062664f2') + m.get( + self.baseurl + "/1f951daf-4061-451a-9df1-69a8062664f2/content", + headers={"Content-Disposition": 'name="tableau_workbook"; filename="RESTAPISample.twbx"'}, + ) + file_path = self.server.workbooks.download("1f951daf-4061-451a-9df1-69a8062664f2") self.assertTrue(os.path.exists(file_path)) os.remove(file_path) @@ -266,9 +269,11 @@ def test_download_sanitizes_name(self) -> None: filename = "Name,With,Commas.twbx" disposition = 'name="tableau_workbook"; filename="{}"'.format(filename) with requests_mock.mock() as m: - m.get(self.baseurl + '/1f951daf-4061-451a-9df1-69a8062664f2/content', - headers={'Content-Disposition': disposition}) - file_path = self.server.workbooks.download('1f951daf-4061-451a-9df1-69a8062664f2') + m.get( + self.baseurl + "/1f951daf-4061-451a-9df1-69a8062664f2/content", + headers={"Content-Disposition": disposition}, + ) + file_path = self.server.workbooks.download("1f951daf-4061-451a-9df1-69a8062664f2") self.assertEqual(os.path.basename(file_path), "NameWithCommas.twbx") self.assertTrue(os.path.exists(file_path)) os.remove(file_path) @@ -279,140 +284,141 @@ def test_download_extract_only(self) -> None: self.baseurl = self.server.workbooks.baseurl with requests_mock.mock() as m: - m.get(self.baseurl + '/1f951daf-4061-451a-9df1-69a8062664f2/content?includeExtract=False', - headers={'Content-Disposition': 'name="tableau_workbook"; filename="RESTAPISample.twbx"'}, - complete_qs=True) + m.get( + self.baseurl + "/1f951daf-4061-451a-9df1-69a8062664f2/content?includeExtract=False", + headers={"Content-Disposition": 'name="tableau_workbook"; filename="RESTAPISample.twbx"'}, + complete_qs=True, + ) # Technically this shouldn't download a twbx, but we are interested in the qs, not the file - file_path = self.server.workbooks.download('1f951daf-4061-451a-9df1-69a8062664f2', include_extract=False) + file_path = self.server.workbooks.download("1f951daf-4061-451a-9df1-69a8062664f2", include_extract=False) self.assertTrue(os.path.exists(file_path)) os.remove(file_path) def test_download_missing_id(self) -> None: - self.assertRaises(ValueError, self.server.workbooks.download, '') + self.assertRaises(ValueError, self.server.workbooks.download, "") def test_populate_views(self) -> None: - with open(POPULATE_VIEWS_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(POPULATE_VIEWS_XML, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: - m.get(self.baseurl + '/1f951daf-4061-451a-9df1-69a8062664f2/views', text=response_xml) - single_workbook = TSC.WorkbookItem('test') - single_workbook._id = '1f951daf-4061-451a-9df1-69a8062664f2' + m.get(self.baseurl + "/1f951daf-4061-451a-9df1-69a8062664f2/views", text=response_xml) + single_workbook = TSC.WorkbookItem("test") + single_workbook._id = "1f951daf-4061-451a-9df1-69a8062664f2" self.server.workbooks.populate_views(single_workbook) views_list = single_workbook.views - self.assertEqual('097dbe13-de89-445f-b2c3-02f28bd010c1', views_list[0].id) - self.assertEqual('GDP per capita', views_list[0].name) - self.assertEqual('RESTAPISample/sheets/GDPpercapita', views_list[0].content_url) + self.assertEqual("097dbe13-de89-445f-b2c3-02f28bd010c1", views_list[0].id) + self.assertEqual("GDP per capita", views_list[0].name) + self.assertEqual("RESTAPISample/sheets/GDPpercapita", views_list[0].content_url) - self.assertEqual('2c1ab9d7-8d64-4cc6-b495-52e40c60c330', views_list[1].id) - self.assertEqual('Country ranks', views_list[1].name) - self.assertEqual('RESTAPISample/sheets/Countryranks', views_list[1].content_url) + self.assertEqual("2c1ab9d7-8d64-4cc6-b495-52e40c60c330", views_list[1].id) + self.assertEqual("Country ranks", views_list[1].name) + self.assertEqual("RESTAPISample/sheets/Countryranks", views_list[1].content_url) - self.assertEqual('0599c28c-6d82-457e-a453-e52c1bdb00f5', views_list[2].id) - self.assertEqual('Interest rates', views_list[2].name) - self.assertEqual('RESTAPISample/sheets/Interestrates', views_list[2].content_url) + self.assertEqual("0599c28c-6d82-457e-a453-e52c1bdb00f5", views_list[2].id) + self.assertEqual("Interest rates", views_list[2].name) + self.assertEqual("RESTAPISample/sheets/Interestrates", views_list[2].content_url) def test_populate_views_with_usage(self) -> None: - with open(POPULATE_VIEWS_USAGE_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(POPULATE_VIEWS_USAGE_XML, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: - m.get(self.baseurl + '/1f951daf-4061-451a-9df1-69a8062664f2/views?includeUsageStatistics=true', - text=response_xml) - single_workbook = TSC.WorkbookItem('test') - single_workbook._id = '1f951daf-4061-451a-9df1-69a8062664f2' + m.get( + self.baseurl + "/1f951daf-4061-451a-9df1-69a8062664f2/views?includeUsageStatistics=true", + text=response_xml, + ) + single_workbook = TSC.WorkbookItem("test") + single_workbook._id = "1f951daf-4061-451a-9df1-69a8062664f2" self.server.workbooks.populate_views(single_workbook, usage=True) views_list = single_workbook.views - self.assertEqual('097dbe13-de89-445f-b2c3-02f28bd010c1', views_list[0].id) + self.assertEqual("097dbe13-de89-445f-b2c3-02f28bd010c1", views_list[0].id) self.assertEqual(2, views_list[0].total_views) - self.assertEqual('2c1ab9d7-8d64-4cc6-b495-52e40c60c330', views_list[1].id) + self.assertEqual("2c1ab9d7-8d64-4cc6-b495-52e40c60c330", views_list[1].id) self.assertEqual(37, views_list[1].total_views) - self.assertEqual('0599c28c-6d82-457e-a453-e52c1bdb00f5', views_list[2].id) + self.assertEqual("0599c28c-6d82-457e-a453-e52c1bdb00f5", views_list[2].id) self.assertEqual(0, views_list[2].total_views) def test_populate_views_missing_id(self) -> None: - single_workbook = TSC.WorkbookItem('test') + single_workbook = TSC.WorkbookItem("test") self.assertRaises(TSC.MissingRequiredFieldError, self.server.workbooks.populate_views, single_workbook) def test_populate_connections(self) -> None: - with open(POPULATE_CONNECTIONS_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(POPULATE_CONNECTIONS_XML, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: - m.get(self.baseurl + '/1f951daf-4061-451a-9df1-69a8062664f2/connections', text=response_xml) - single_workbook = TSC.WorkbookItem('test') - single_workbook._id = '1f951daf-4061-451a-9df1-69a8062664f2' + m.get(self.baseurl + "/1f951daf-4061-451a-9df1-69a8062664f2/connections", text=response_xml) + single_workbook = TSC.WorkbookItem("test") + single_workbook._id = "1f951daf-4061-451a-9df1-69a8062664f2" self.server.workbooks.populate_connections(single_workbook) - self.assertEqual('37ca6ced-58d7-4dcf-99dc-f0a85223cbef', single_workbook.connections[0].id) - self.assertEqual('dataengine', single_workbook.connections[0].connection_type) - self.assertEqual('4506225a-0d32-4ab1-82d3-c24e85f7afba', single_workbook.connections[0].datasource_id) - self.assertEqual('World Indicators', single_workbook.connections[0].datasource_name) + self.assertEqual("37ca6ced-58d7-4dcf-99dc-f0a85223cbef", single_workbook.connections[0].id) + self.assertEqual("dataengine", single_workbook.connections[0].connection_type) + self.assertEqual("4506225a-0d32-4ab1-82d3-c24e85f7afba", single_workbook.connections[0].datasource_id) + self.assertEqual("World Indicators", single_workbook.connections[0].datasource_name) def test_populate_permissions(self) -> None: - with open(POPULATE_PERMISSIONS_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(POPULATE_PERMISSIONS_XML, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: - m.get(self.baseurl + '/21778de4-b7b9-44bc-a599-1506a2639ace/permissions', text=response_xml) - single_workbook = TSC.WorkbookItem('test') - single_workbook._id = '21778de4-b7b9-44bc-a599-1506a2639ace' + m.get(self.baseurl + "/21778de4-b7b9-44bc-a599-1506a2639ace/permissions", text=response_xml) + single_workbook = TSC.WorkbookItem("test") + single_workbook._id = "21778de4-b7b9-44bc-a599-1506a2639ace" self.server.workbooks.populate_permissions(single_workbook) permissions = single_workbook.permissions - self.assertEqual(permissions[0].grantee.tag_name, 'group') - self.assertEqual(permissions[0].grantee.id, '5e5e1978-71fa-11e4-87dd-7382f5c437af') - self.assertDictEqual(permissions[0].capabilities, { - TSC.Permission.Capability.WebAuthoring: TSC.Permission.Mode.Allow, - TSC.Permission.Capability.Read: TSC.Permission.Mode.Allow, - TSC.Permission.Capability.Filter: TSC.Permission.Mode.Allow, - TSC.Permission.Capability.AddComment: TSC.Permission.Mode.Allow - }) - - self.assertEqual(permissions[1].grantee.tag_name, 'user') - self.assertEqual(permissions[1].grantee.id, '7c37ee24-c4b1-42b6-a154-eaeab7ee330a') - self.assertDictEqual(permissions[1].capabilities, { - TSC.Permission.Capability.ExportImage: TSC.Permission.Mode.Allow, - TSC.Permission.Capability.ShareView: TSC.Permission.Mode.Allow, - TSC.Permission.Capability.ExportData: TSC.Permission.Mode.Deny, - TSC.Permission.Capability.ViewComments: TSC.Permission.Mode.Deny - }) + self.assertEqual(permissions[0].grantee.tag_name, "group") + self.assertEqual(permissions[0].grantee.id, "5e5e1978-71fa-11e4-87dd-7382f5c437af") + self.assertDictEqual( + permissions[0].capabilities, + { + TSC.Permission.Capability.WebAuthoring: TSC.Permission.Mode.Allow, + TSC.Permission.Capability.Read: TSC.Permission.Mode.Allow, + TSC.Permission.Capability.Filter: TSC.Permission.Mode.Allow, + TSC.Permission.Capability.AddComment: TSC.Permission.Mode.Allow, + }, + ) + + self.assertEqual(permissions[1].grantee.tag_name, "user") + self.assertEqual(permissions[1].grantee.id, "7c37ee24-c4b1-42b6-a154-eaeab7ee330a") + self.assertDictEqual( + permissions[1].capabilities, + { + TSC.Permission.Capability.ExportImage: TSC.Permission.Mode.Allow, + TSC.Permission.Capability.ShareView: TSC.Permission.Mode.Allow, + TSC.Permission.Capability.ExportData: TSC.Permission.Mode.Deny, + TSC.Permission.Capability.ViewComments: TSC.Permission.Mode.Deny, + }, + ) def test_add_permissions(self) -> None: - with open(UPDATE_PERMISSIONS, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(UPDATE_PERMISSIONS, "rb") as f: + response_xml = f.read().decode("utf-8") - single_workbook = TSC.WorkbookItem('test') - single_workbook._id = '21778de4-b7b9-44bc-a599-1506a2639ace' + single_workbook = TSC.WorkbookItem("test") + single_workbook._id = "21778de4-b7b9-44bc-a599-1506a2639ace" bob = UserItem.as_reference("7c37ee24-c4b1-42b6-a154-eaeab7ee330a") group_of_people = GroupItem.as_reference("5e5e1978-71fa-11e4-87dd-7382f5c437af") - new_permissions = [ - PermissionsRule(bob, {'Write': 'Allow'}), - PermissionsRule(group_of_people, {'Read': 'Deny'}) - ] + new_permissions = [PermissionsRule(bob, {"Write": "Allow"}), PermissionsRule(group_of_people, {"Read": "Deny"})] with requests_mock.mock() as m: m.put(self.baseurl + "/21778de4-b7b9-44bc-a599-1506a2639ace/permissions", text=response_xml) permissions = self.server.workbooks.update_permissions(single_workbook, new_permissions) - self.assertEqual(permissions[0].grantee.tag_name, 'group') - self.assertEqual(permissions[0].grantee.id, '5e5e1978-71fa-11e4-87dd-7382f5c437af') - self.assertDictEqual(permissions[0].capabilities, { - TSC.Permission.Capability.Read: TSC.Permission.Mode.Deny - }) + self.assertEqual(permissions[0].grantee.tag_name, "group") + self.assertEqual(permissions[0].grantee.id, "5e5e1978-71fa-11e4-87dd-7382f5c437af") + self.assertDictEqual(permissions[0].capabilities, {TSC.Permission.Capability.Read: TSC.Permission.Mode.Deny}) - self.assertEqual(permissions[1].grantee.tag_name, 'user') - self.assertEqual(permissions[1].grantee.id, '7c37ee24-c4b1-42b6-a154-eaeab7ee330a') - self.assertDictEqual(permissions[1].capabilities, { - TSC.Permission.Capability.Write: TSC.Permission.Mode.Allow - }) + self.assertEqual(permissions[1].grantee.tag_name, "user") + self.assertEqual(permissions[1].grantee.id, "7c37ee24-c4b1-42b6-a154-eaeab7ee330a") + self.assertDictEqual(permissions[1].capabilities, {TSC.Permission.Capability.Write: TSC.Permission.Mode.Allow}) def test_populate_connections_missing_id(self) -> None: - single_workbook = TSC.WorkbookItem('test') - self.assertRaises(TSC.MissingRequiredFieldError, - self.server.workbooks.populate_connections, - single_workbook) + single_workbook = TSC.WorkbookItem("test") + self.assertRaises(TSC.MissingRequiredFieldError, self.server.workbooks.populate_connections, single_workbook) def test_populate_pdf(self) -> None: self.server.version = "3.4" @@ -420,10 +426,12 @@ def test_populate_pdf(self) -> None: with open(POPULATE_PDF, "rb") as f: response = f.read() with requests_mock.mock() as m: - m.get(self.baseurl + "/1f951daf-4061-451a-9df1-69a8062664f2/pdf?type=a5&orientation=landscape", - content=response) - single_workbook = TSC.WorkbookItem('test') - single_workbook._id = '1f951daf-4061-451a-9df1-69a8062664f2' + m.get( + self.baseurl + "/1f951daf-4061-451a-9df1-69a8062664f2/pdf?type=a5&orientation=landscape", + content=response, + ) + single_workbook = TSC.WorkbookItem("test") + single_workbook._id = "1f951daf-4061-451a-9df1-69a8062664f2" type = TSC.PDFRequestOptions.PageType.A5 orientation = TSC.PDFRequestOptions.Orientation.Landscape @@ -433,356 +441,357 @@ def test_populate_pdf(self) -> None: self.assertEqual(response, single_workbook.pdf) def test_populate_preview_image(self) -> None: - with open(POPULATE_PREVIEW_IMAGE, 'rb') as f: + with open(POPULATE_PREVIEW_IMAGE, "rb") as f: response = f.read() with requests_mock.mock() as m: - m.get(self.baseurl + '/1f951daf-4061-451a-9df1-69a8062664f2/previewImage', content=response) - single_workbook = TSC.WorkbookItem('test') - single_workbook._id = '1f951daf-4061-451a-9df1-69a8062664f2' + m.get(self.baseurl + "/1f951daf-4061-451a-9df1-69a8062664f2/previewImage", content=response) + single_workbook = TSC.WorkbookItem("test") + single_workbook._id = "1f951daf-4061-451a-9df1-69a8062664f2" self.server.workbooks.populate_preview_image(single_workbook) self.assertEqual(response, single_workbook.preview_image) def test_populate_preview_image_missing_id(self) -> None: - single_workbook = TSC.WorkbookItem('test') - self.assertRaises(TSC.MissingRequiredFieldError, - self.server.workbooks.populate_preview_image, - single_workbook) + single_workbook = TSC.WorkbookItem("test") + self.assertRaises(TSC.MissingRequiredFieldError, self.server.workbooks.populate_preview_image, single_workbook) def test_publish(self) -> None: - with open(PUBLISH_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(PUBLISH_XML, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: m.post(self.baseurl, text=response_xml) - new_workbook = TSC.WorkbookItem(name='Sample', - show_tabs=False, - project_id='ee8c6e70-43b6-11e6-af4f-f7b0d8e20760') + new_workbook = TSC.WorkbookItem( + name="Sample", show_tabs=False, project_id="ee8c6e70-43b6-11e6-af4f-f7b0d8e20760" + ) - sample_workbook = os.path.join(TEST_ASSET_DIR, 'SampleWB.twbx') + sample_workbook = os.path.join(TEST_ASSET_DIR, "SampleWB.twbx") publish_mode = self.server.PublishMode.CreateNew - new_workbook = self.server.workbooks.publish(new_workbook, - sample_workbook, - publish_mode) + new_workbook = self.server.workbooks.publish(new_workbook, sample_workbook, publish_mode) - self.assertEqual('a8076ca1-e9d8-495e-bae6-c684dbb55836', new_workbook.id) - self.assertEqual('RESTAPISample', new_workbook.name) - self.assertEqual('RESTAPISample_0', new_workbook.content_url) + self.assertEqual("a8076ca1-e9d8-495e-bae6-c684dbb55836", new_workbook.id) + self.assertEqual("RESTAPISample", new_workbook.name) + self.assertEqual("RESTAPISample_0", new_workbook.content_url) self.assertEqual(False, new_workbook.show_tabs) self.assertEqual(1, new_workbook.size) - self.assertEqual('2016-08-18T18:33:24Z', format_datetime(new_workbook.created_at)) - self.assertEqual('2016-08-18T20:31:34Z', format_datetime(new_workbook.updated_at)) - self.assertEqual('ee8c6e70-43b6-11e6-af4f-f7b0d8e20760', new_workbook.project_id) - self.assertEqual('default', new_workbook.project_name) - self.assertEqual('5de011f8-5aa9-4d5b-b991-f462c8dd6bb7', new_workbook.owner_id) - self.assertEqual('fe0b4e89-73f4-435e-952d-3a263fbfa56c', new_workbook.views[0].id) - self.assertEqual('GDP per capita', new_workbook.views[0].name) - self.assertEqual('RESTAPISample_0/sheets/GDPpercapita', new_workbook.views[0].content_url) + self.assertEqual("2016-08-18T18:33:24Z", format_datetime(new_workbook.created_at)) + self.assertEqual("2016-08-18T20:31:34Z", format_datetime(new_workbook.updated_at)) + self.assertEqual("ee8c6e70-43b6-11e6-af4f-f7b0d8e20760", new_workbook.project_id) + self.assertEqual("default", new_workbook.project_name) + self.assertEqual("5de011f8-5aa9-4d5b-b991-f462c8dd6bb7", new_workbook.owner_id) + self.assertEqual("fe0b4e89-73f4-435e-952d-3a263fbfa56c", new_workbook.views[0].id) + self.assertEqual("GDP per capita", new_workbook.views[0].name) + self.assertEqual("RESTAPISample_0/sheets/GDPpercapita", new_workbook.views[0].content_url) def test_publish_a_packaged_file_object(self) -> None: - with open(PUBLISH_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(PUBLISH_XML, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: m.post(self.baseurl, text=response_xml) - new_workbook = TSC.WorkbookItem(name='Sample', - show_tabs=False, - project_id='ee8c6e70-43b6-11e6-af4f-f7b0d8e20760') + new_workbook = TSC.WorkbookItem( + name="Sample", show_tabs=False, project_id="ee8c6e70-43b6-11e6-af4f-f7b0d8e20760" + ) - sample_workbook = os.path.join(TEST_ASSET_DIR, 'SampleWB.twbx') + sample_workbook = os.path.join(TEST_ASSET_DIR, "SampleWB.twbx") - with open(sample_workbook, 'rb') as fp: + with open(sample_workbook, "rb") as fp: publish_mode = self.server.PublishMode.CreateNew - new_workbook = self.server.workbooks.publish(new_workbook, - fp, - publish_mode) + new_workbook = self.server.workbooks.publish(new_workbook, fp, publish_mode) - self.assertEqual('a8076ca1-e9d8-495e-bae6-c684dbb55836', new_workbook.id) - self.assertEqual('RESTAPISample', new_workbook.name) - self.assertEqual('RESTAPISample_0', new_workbook.content_url) + self.assertEqual("a8076ca1-e9d8-495e-bae6-c684dbb55836", new_workbook.id) + self.assertEqual("RESTAPISample", new_workbook.name) + self.assertEqual("RESTAPISample_0", new_workbook.content_url) self.assertEqual(False, new_workbook.show_tabs) self.assertEqual(1, new_workbook.size) - self.assertEqual('2016-08-18T18:33:24Z', format_datetime(new_workbook.created_at)) - self.assertEqual('2016-08-18T20:31:34Z', format_datetime(new_workbook.updated_at)) - self.assertEqual('ee8c6e70-43b6-11e6-af4f-f7b0d8e20760', new_workbook.project_id) - self.assertEqual('default', new_workbook.project_name) - self.assertEqual('5de011f8-5aa9-4d5b-b991-f462c8dd6bb7', new_workbook.owner_id) - self.assertEqual('fe0b4e89-73f4-435e-952d-3a263fbfa56c', new_workbook.views[0].id) - self.assertEqual('GDP per capita', new_workbook.views[0].name) - self.assertEqual('RESTAPISample_0/sheets/GDPpercapita', new_workbook.views[0].content_url) + self.assertEqual("2016-08-18T18:33:24Z", format_datetime(new_workbook.created_at)) + self.assertEqual("2016-08-18T20:31:34Z", format_datetime(new_workbook.updated_at)) + self.assertEqual("ee8c6e70-43b6-11e6-af4f-f7b0d8e20760", new_workbook.project_id) + self.assertEqual("default", new_workbook.project_name) + self.assertEqual("5de011f8-5aa9-4d5b-b991-f462c8dd6bb7", new_workbook.owner_id) + self.assertEqual("fe0b4e89-73f4-435e-952d-3a263fbfa56c", new_workbook.views[0].id) + self.assertEqual("GDP per capita", new_workbook.views[0].name) + self.assertEqual("RESTAPISample_0/sheets/GDPpercapita", new_workbook.views[0].content_url) def test_publish_non_packeged_file_object(self) -> None: - with open(PUBLISH_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(PUBLISH_XML, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: m.post(self.baseurl, text=response_xml) - new_workbook = TSC.WorkbookItem(name='Sample', - show_tabs=False, - project_id='ee8c6e70-43b6-11e6-af4f-f7b0d8e20760') + new_workbook = TSC.WorkbookItem( + name="Sample", show_tabs=False, project_id="ee8c6e70-43b6-11e6-af4f-f7b0d8e20760" + ) - sample_workbook = os.path.join(TEST_ASSET_DIR, 'RESTAPISample.twb') + sample_workbook = os.path.join(TEST_ASSET_DIR, "RESTAPISample.twb") - with open(sample_workbook, 'rb') as fp: + with open(sample_workbook, "rb") as fp: publish_mode = self.server.PublishMode.CreateNew - new_workbook = self.server.workbooks.publish(new_workbook, - fp, - publish_mode) + new_workbook = self.server.workbooks.publish(new_workbook, fp, publish_mode) - self.assertEqual('a8076ca1-e9d8-495e-bae6-c684dbb55836', new_workbook.id) - self.assertEqual('RESTAPISample', new_workbook.name) - self.assertEqual('RESTAPISample_0', new_workbook.content_url) + self.assertEqual("a8076ca1-e9d8-495e-bae6-c684dbb55836", new_workbook.id) + self.assertEqual("RESTAPISample", new_workbook.name) + self.assertEqual("RESTAPISample_0", new_workbook.content_url) self.assertEqual(False, new_workbook.show_tabs) self.assertEqual(1, new_workbook.size) - self.assertEqual('2016-08-18T18:33:24Z', format_datetime(new_workbook.created_at)) - self.assertEqual('2016-08-18T20:31:34Z', format_datetime(new_workbook.updated_at)) - self.assertEqual('ee8c6e70-43b6-11e6-af4f-f7b0d8e20760', new_workbook.project_id) - self.assertEqual('default', new_workbook.project_name) - self.assertEqual('5de011f8-5aa9-4d5b-b991-f462c8dd6bb7', new_workbook.owner_id) - self.assertEqual('fe0b4e89-73f4-435e-952d-3a263fbfa56c', new_workbook.views[0].id) - self.assertEqual('GDP per capita', new_workbook.views[0].name) - self.assertEqual('RESTAPISample_0/sheets/GDPpercapita', new_workbook.views[0].content_url) + self.assertEqual("2016-08-18T18:33:24Z", format_datetime(new_workbook.created_at)) + self.assertEqual("2016-08-18T20:31:34Z", format_datetime(new_workbook.updated_at)) + self.assertEqual("ee8c6e70-43b6-11e6-af4f-f7b0d8e20760", new_workbook.project_id) + self.assertEqual("default", new_workbook.project_name) + self.assertEqual("5de011f8-5aa9-4d5b-b991-f462c8dd6bb7", new_workbook.owner_id) + self.assertEqual("fe0b4e89-73f4-435e-952d-3a263fbfa56c", new_workbook.views[0].id) + self.assertEqual("GDP per capita", new_workbook.views[0].name) + self.assertEqual("RESTAPISample_0/sheets/GDPpercapita", new_workbook.views[0].content_url) def test_publish_path_object(self) -> None: - with open(PUBLISH_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(PUBLISH_XML, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: m.post(self.baseurl, text=response_xml) - new_workbook = TSC.WorkbookItem(name='Sample', - show_tabs=False, - project_id='ee8c6e70-43b6-11e6-af4f-f7b0d8e20760') + new_workbook = TSC.WorkbookItem( + name="Sample", show_tabs=False, project_id="ee8c6e70-43b6-11e6-af4f-f7b0d8e20760" + ) - sample_workbook = Path(TEST_ASSET_DIR) / 'SampleWB.twbx' + sample_workbook = Path(TEST_ASSET_DIR) / "SampleWB.twbx" publish_mode = self.server.PublishMode.CreateNew - new_workbook = self.server.workbooks.publish(new_workbook, - sample_workbook, - publish_mode) + new_workbook = self.server.workbooks.publish(new_workbook, sample_workbook, publish_mode) - self.assertEqual('a8076ca1-e9d8-495e-bae6-c684dbb55836', new_workbook.id) - self.assertEqual('RESTAPISample', new_workbook.name) - self.assertEqual('RESTAPISample_0', new_workbook.content_url) + self.assertEqual("a8076ca1-e9d8-495e-bae6-c684dbb55836", new_workbook.id) + self.assertEqual("RESTAPISample", new_workbook.name) + self.assertEqual("RESTAPISample_0", new_workbook.content_url) self.assertEqual(False, new_workbook.show_tabs) self.assertEqual(1, new_workbook.size) - self.assertEqual('2016-08-18T18:33:24Z', format_datetime(new_workbook.created_at)) - self.assertEqual('2016-08-18T20:31:34Z', format_datetime(new_workbook.updated_at)) - self.assertEqual('ee8c6e70-43b6-11e6-af4f-f7b0d8e20760', new_workbook.project_id) - self.assertEqual('default', new_workbook.project_name) - self.assertEqual('5de011f8-5aa9-4d5b-b991-f462c8dd6bb7', new_workbook.owner_id) - self.assertEqual('fe0b4e89-73f4-435e-952d-3a263fbfa56c', new_workbook.views[0].id) - self.assertEqual('GDP per capita', new_workbook.views[0].name) - self.assertEqual('RESTAPISample_0/sheets/GDPpercapita', new_workbook.views[0].content_url) + self.assertEqual("2016-08-18T18:33:24Z", format_datetime(new_workbook.created_at)) + self.assertEqual("2016-08-18T20:31:34Z", format_datetime(new_workbook.updated_at)) + self.assertEqual("ee8c6e70-43b6-11e6-af4f-f7b0d8e20760", new_workbook.project_id) + self.assertEqual("default", new_workbook.project_name) + self.assertEqual("5de011f8-5aa9-4d5b-b991-f462c8dd6bb7", new_workbook.owner_id) + self.assertEqual("fe0b4e89-73f4-435e-952d-3a263fbfa56c", new_workbook.views[0].id) + self.assertEqual("GDP per capita", new_workbook.views[0].name) + self.assertEqual("RESTAPISample_0/sheets/GDPpercapita", new_workbook.views[0].content_url) def test_publish_with_hidden_view(self) -> None: - with open(PUBLISH_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(PUBLISH_XML, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: m.post(self.baseurl, text=response_xml) - new_workbook = TSC.WorkbookItem(name='Sample', - show_tabs=False, - project_id='ee8c6e70-43b6-11e6-af4f-f7b0d8e20760') + new_workbook = TSC.WorkbookItem( + name="Sample", show_tabs=False, project_id="ee8c6e70-43b6-11e6-af4f-f7b0d8e20760" + ) - sample_workbook = os.path.join(TEST_ASSET_DIR, 'SampleWB.twbx') + sample_workbook = os.path.join(TEST_ASSET_DIR, "SampleWB.twbx") publish_mode = self.server.PublishMode.CreateNew - new_workbook.hidden_views = ['GDP per capita'] - new_workbook = self.server.workbooks.publish( - new_workbook, sample_workbook, publish_mode - ) + new_workbook.hidden_views = ["GDP per capita"] + new_workbook = self.server.workbooks.publish(new_workbook, sample_workbook, publish_mode) request_body = m._adapter.request_history[0]._request.body # order of attributes in xml is unspecified - self.assertTrue(re.search(rb'<\/views>', request_body)) - self.assertTrue(re.search(rb'<\/views>', request_body)) + self.assertTrue(re.search(rb"<\/views>", request_body)) + self.assertTrue(re.search(rb"<\/views>", request_body)) def test_publish_with_query_params(self) -> None: - with open(PUBLISH_ASYNC_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(PUBLISH_ASYNC_XML, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: m.post(self.baseurl, text=response_xml) - new_workbook = TSC.WorkbookItem(name='Sample', - show_tabs=False, - project_id='ee8c6e70-43b6-11e6-af4f-f7b0d8e20760') + new_workbook = TSC.WorkbookItem( + name="Sample", show_tabs=False, project_id="ee8c6e70-43b6-11e6-af4f-f7b0d8e20760" + ) - sample_workbook = os.path.join(TEST_ASSET_DIR, 'SampleWB.twbx') + sample_workbook = os.path.join(TEST_ASSET_DIR, "SampleWB.twbx") publish_mode = self.server.PublishMode.CreateNew - self.server.workbooks.publish(new_workbook, sample_workbook, publish_mode, - as_job=True, skip_connection_check=True) + self.server.workbooks.publish( + new_workbook, sample_workbook, publish_mode, as_job=True, skip_connection_check=True + ) request_query_params = m._adapter.request_history[0].qs - self.assertTrue('asjob' in request_query_params) - self.assertTrue(request_query_params['asjob']) - self.assertTrue('skipconnectioncheck' in request_query_params) - self.assertTrue(request_query_params['skipconnectioncheck']) + self.assertTrue("asjob" in request_query_params) + self.assertTrue(request_query_params["asjob"]) + self.assertTrue("skipconnectioncheck" in request_query_params) + self.assertTrue(request_query_params["skipconnectioncheck"]) def test_publish_async(self) -> None: - self.server.version = '3.0' + self.server.version = "3.0" baseurl = self.server.workbooks.baseurl - with open(PUBLISH_ASYNC_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(PUBLISH_ASYNC_XML, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: m.post(baseurl, text=response_xml) - new_workbook = TSC.WorkbookItem(name='Sample', - show_tabs=False, - project_id='ee8c6e70-43b6-11e6-af4f-f7b0d8e20760') + new_workbook = TSC.WorkbookItem( + name="Sample", show_tabs=False, project_id="ee8c6e70-43b6-11e6-af4f-f7b0d8e20760" + ) - sample_workbook = os.path.join(TEST_ASSET_DIR, 'SampleWB.twbx') + sample_workbook = os.path.join(TEST_ASSET_DIR, "SampleWB.twbx") publish_mode = self.server.PublishMode.CreateNew - new_job = self.server.workbooks.publish(new_workbook, - sample_workbook, - publish_mode, - as_job=True) + new_job = self.server.workbooks.publish(new_workbook, sample_workbook, publish_mode, as_job=True) - self.assertEqual('7c3d599e-949f-44c3-94a1-f30ba85757e4', new_job.id) - self.assertEqual('PublishWorkbook', new_job.type) - self.assertEqual('0', new_job.progress) - self.assertEqual('2018-06-29T23:22:32Z', format_datetime(new_job.created_at)) + self.assertEqual("7c3d599e-949f-44c3-94a1-f30ba85757e4", new_job.id) + self.assertEqual("PublishWorkbook", new_job.type) + self.assertEqual("0", new_job.progress) + self.assertEqual("2018-06-29T23:22:32Z", format_datetime(new_job.created_at)) self.assertEqual(1, new_job.finish_code) def test_publish_invalid_file(self) -> None: - new_workbook = TSC.WorkbookItem('test', 'ee8c6e70-43b6-11e6-af4f-f7b0d8e20760') - self.assertRaises(IOError, self.server.workbooks.publish, new_workbook, '.', - self.server.PublishMode.CreateNew) + new_workbook = TSC.WorkbookItem("test", "ee8c6e70-43b6-11e6-af4f-f7b0d8e20760") + self.assertRaises(IOError, self.server.workbooks.publish, new_workbook, ".", self.server.PublishMode.CreateNew) def test_publish_invalid_file_type(self) -> None: - new_workbook = TSC.WorkbookItem('test', 'ee8c6e70-43b6-11e6-af4f-f7b0d8e20760') - self.assertRaises(ValueError, self.server.workbooks.publish, - new_workbook, os.path.join(TEST_ASSET_DIR, 'SampleDS.tds'), - self.server.PublishMode.CreateNew) + new_workbook = TSC.WorkbookItem("test", "ee8c6e70-43b6-11e6-af4f-f7b0d8e20760") + self.assertRaises( + ValueError, + self.server.workbooks.publish, + new_workbook, + os.path.join(TEST_ASSET_DIR, "SampleDS.tds"), + self.server.PublishMode.CreateNew, + ) def test_publish_unnamed_file_object(self) -> None: - new_workbook = TSC.WorkbookItem('test') + new_workbook = TSC.WorkbookItem("test") - with open(os.path.join(TEST_ASSET_DIR, 'SampleWB.twbx'), 'rb') as f: + with open(os.path.join(TEST_ASSET_DIR, "SampleWB.twbx"), "rb") as f: - self.assertRaises(ValueError, self.server.workbooks.publish, - new_workbook, f, self.server.PublishMode.CreateNew - ) + self.assertRaises( + ValueError, self.server.workbooks.publish, new_workbook, f, self.server.PublishMode.CreateNew + ) def test_publish_non_bytes_file_object(self) -> None: - new_workbook = TSC.WorkbookItem('test') + new_workbook = TSC.WorkbookItem("test") - with open(os.path.join(TEST_ASSET_DIR, 'SampleWB.twbx')) as f: + with open(os.path.join(TEST_ASSET_DIR, "SampleWB.twbx")) as f: - self.assertRaises(TypeError, self.server.workbooks.publish, - new_workbook, f, self.server.PublishMode.CreateNew - ) + self.assertRaises( + TypeError, self.server.workbooks.publish, new_workbook, f, self.server.PublishMode.CreateNew + ) def test_publish_file_object_of_unknown_type_raises_exception(self) -> None: - new_workbook = TSC.WorkbookItem('test') + new_workbook = TSC.WorkbookItem("test") with BytesIO() as file_object: - file_object.write(bytes.fromhex('89504E470D0A1A0A')) + file_object.write(bytes.fromhex("89504E470D0A1A0A")) file_object.seek(0) - self.assertRaises(ValueError, self.server.workbooks.publish, new_workbook, - file_object, self.server.PublishMode.CreateNew) + self.assertRaises( + ValueError, self.server.workbooks.publish, new_workbook, file_object, self.server.PublishMode.CreateNew + ) def test_publish_multi_connection(self) -> None: - new_workbook = TSC.WorkbookItem(name='Sample', show_tabs=False, - project_id='ee8c6e70-43b6-11e6-af4f-f7b0d8e20760') + new_workbook = TSC.WorkbookItem( + name="Sample", show_tabs=False, project_id="ee8c6e70-43b6-11e6-af4f-f7b0d8e20760" + ) connection1 = TSC.ConnectionItem() - connection1.server_address = 'mysql.test.com' - connection1.connection_credentials = TSC.ConnectionCredentials('test', 'secret', True) + connection1.server_address = "mysql.test.com" + connection1.connection_credentials = TSC.ConnectionCredentials("test", "secret", True) connection2 = TSC.ConnectionItem() - connection2.server_address = 'pgsql.test.com' - connection2.connection_credentials = TSC.ConnectionCredentials('test', 'secret', True) + connection2.server_address = "pgsql.test.com" + connection2.connection_credentials = TSC.ConnectionCredentials("test", "secret", True) response = RequestFactory.Workbook._generate_xml(new_workbook, connections=[connection1, connection2]) # Can't use ConnectionItem parser due to xml namespace problems - connection_results = ET.fromstring(response).findall('.//connection') + connection_results = ET.fromstring(response).findall(".//connection") - self.assertEqual(connection_results[0].get('serverAddress', None), 'mysql.test.com') - self.assertEqual(connection_results[0].find('connectionCredentials').get('name', None), 'test') # type: ignore[union-attr] - self.assertEqual(connection_results[1].get('serverAddress', None), 'pgsql.test.com') - self.assertEqual(connection_results[1].find('connectionCredentials').get('password', None), 'secret') # type: ignore[union-attr] + self.assertEqual(connection_results[0].get("serverAddress", None), "mysql.test.com") + self.assertEqual(connection_results[0].find("connectionCredentials").get("name", None), "test") # type: ignore[union-attr] + self.assertEqual(connection_results[1].get("serverAddress", None), "pgsql.test.com") + self.assertEqual(connection_results[1].find("connectionCredentials").get("password", None), "secret") # type: ignore[union-attr] def test_publish_single_connection(self) -> None: - new_workbook = TSC.WorkbookItem(name='Sample', show_tabs=False, - project_id='ee8c6e70-43b6-11e6-af4f-f7b0d8e20760') - connection_creds = TSC.ConnectionCredentials('test', 'secret', True) + new_workbook = TSC.WorkbookItem( + name="Sample", show_tabs=False, project_id="ee8c6e70-43b6-11e6-af4f-f7b0d8e20760" + ) + connection_creds = TSC.ConnectionCredentials("test", "secret", True) response = RequestFactory.Workbook._generate_xml(new_workbook, connection_credentials=connection_creds) # Can't use ConnectionItem parser due to xml namespace problems - credentials = ET.fromstring(response).findall('.//connectionCredentials') + credentials = ET.fromstring(response).findall(".//connectionCredentials") self.assertEqual(len(credentials), 1) - self.assertEqual(credentials[0].get('name', None), 'test') - self.assertEqual(credentials[0].get('password', None), 'secret') - self.assertEqual(credentials[0].get('embed', None), 'true') + self.assertEqual(credentials[0].get("name", None), "test") + self.assertEqual(credentials[0].get("password", None), "secret") + self.assertEqual(credentials[0].get("embed", None), "true") def test_credentials_and_multi_connect_raises_exception(self) -> None: - new_workbook = TSC.WorkbookItem(name='Sample', show_tabs=False, - project_id='ee8c6e70-43b6-11e6-af4f-f7b0d8e20760') + new_workbook = TSC.WorkbookItem( + name="Sample", show_tabs=False, project_id="ee8c6e70-43b6-11e6-af4f-f7b0d8e20760" + ) - connection_creds = TSC.ConnectionCredentials('test', 'secret', True) + connection_creds = TSC.ConnectionCredentials("test", "secret", True) connection1 = TSC.ConnectionItem() - connection1.server_address = 'mysql.test.com' - connection1.connection_credentials = TSC.ConnectionCredentials('test', 'secret', True) + connection1.server_address = "mysql.test.com" + connection1.connection_credentials = TSC.ConnectionCredentials("test", "secret", True) with self.assertRaises(RuntimeError): - response = RequestFactory.Workbook._generate_xml(new_workbook, - connection_credentials=connection_creds, - connections=[connection1]) + response = RequestFactory.Workbook._generate_xml( + new_workbook, connection_credentials=connection_creds, connections=[connection1] + ) def test_synchronous_publish_timeout_error(self) -> None: with requests_mock.mock() as m: - m.register_uri('POST', self.baseurl, status_code=504) + m.register_uri("POST", self.baseurl, status_code=504) - new_workbook = TSC.WorkbookItem(project_id='') + new_workbook = TSC.WorkbookItem(project_id="") publish_mode = self.server.PublishMode.CreateNew - self.assertRaisesRegex(InternalServerError, 'Please use asynchronous publishing to avoid timeouts', - self.server.workbooks.publish, new_workbook, asset('SampleWB.twbx'), publish_mode) + self.assertRaisesRegex( + InternalServerError, + "Please use asynchronous publishing to avoid timeouts", + self.server.workbooks.publish, + new_workbook, + asset("SampleWB.twbx"), + publish_mode, + ) def test_delete_extracts_all(self) -> None: self.server.version = "3.10" self.baseurl = self.server.workbooks.baseurl with requests_mock.mock() as m: - m.post(self.baseurl + '/3cc6cd06-89ce-4fdc-b935-5294135d6d42/deleteExtract', status_code=200) - self.server.workbooks.delete_extract('3cc6cd06-89ce-4fdc-b935-5294135d6d42') + m.post(self.baseurl + "/3cc6cd06-89ce-4fdc-b935-5294135d6d42/deleteExtract", status_code=200) + self.server.workbooks.delete_extract("3cc6cd06-89ce-4fdc-b935-5294135d6d42") def test_create_extracts_all(self) -> None: self.server.version = "3.10" self.baseurl = self.server.workbooks.baseurl - with open(PUBLISH_ASYNC_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(PUBLISH_ASYNC_XML, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: - m.post(self.baseurl + '/3cc6cd06-89ce-4fdc-b935-5294135d6d42/createExtract', - status_code=200, text=response_xml) - self.server.workbooks.create_extract('3cc6cd06-89ce-4fdc-b935-5294135d6d42') + m.post( + self.baseurl + "/3cc6cd06-89ce-4fdc-b935-5294135d6d42/createExtract", status_code=200, text=response_xml + ) + self.server.workbooks.create_extract("3cc6cd06-89ce-4fdc-b935-5294135d6d42") def test_create_extracts_one(self) -> None: self.server.version = "3.10" self.baseurl = self.server.workbooks.baseurl - datasource = TSC.DatasourceItem('test') - datasource._id = '1f951daf-4061-451a-9df1-69a8062664f2' + datasource = TSC.DatasourceItem("test") + datasource._id = "1f951daf-4061-451a-9df1-69a8062664f2" - with open(PUBLISH_ASYNC_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(PUBLISH_ASYNC_XML, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: - m.post(self.baseurl + '/3cc6cd06-89ce-4fdc-b935-5294135d6d42/createExtract', - status_code=200, text=response_xml) - self.server.workbooks.create_extract('3cc6cd06-89ce-4fdc-b935-5294135d6d42', False, datasource) + m.post( + self.baseurl + "/3cc6cd06-89ce-4fdc-b935-5294135d6d42/createExtract", status_code=200, text=response_xml + ) + self.server.workbooks.create_extract("3cc6cd06-89ce-4fdc-b935-5294135d6d42", False, datasource) def test_revisions(self) -> None: self.baseurl = self.server.workbooks.baseurl - workbook = TSC.WorkbookItem('project', 'test') - workbook._id = '06b944d2-959d-4604-9305-12323c95e70e' + workbook = TSC.WorkbookItem("project", "test") + workbook._id = "06b944d2-959d-4604-9305-12323c95e70e" - with open(REVISION_XML, 'rb') as f: - response_xml = f.read().decode('utf-8') + with open(REVISION_XML, "rb") as f: + response_xml = f.read().decode("utf-8") with requests_mock.mock() as m: m.get("{0}/{1}/revisions".format(self.baseurl, workbook.id), text=response_xml) self.server.workbooks.populate_revisions(workbook) @@ -809,8 +818,8 @@ def test_revisions(self) -> None: def test_delete_revision(self) -> None: self.baseurl = self.server.workbooks.baseurl - workbook = TSC.WorkbookItem('project', 'test') - workbook._id = '06b944d2-959d-4604-9305-12323c95e70e' + workbook = TSC.WorkbookItem("project", "test") + workbook._id = "06b944d2-959d-4604-9305-12323c95e70e" with requests_mock.mock() as m: m.delete("{0}/{1}/revisions/3".format(self.baseurl, workbook.id)) @@ -818,8 +827,9 @@ def test_delete_revision(self) -> None: def test_download_revision(self) -> None: with requests_mock.mock() as m, tempfile.TemporaryDirectory() as td: - m.get(self.baseurl + '/9dbd2263-16b5-46e1-9c43-a76bb8ab65fb/revisions/3/content', - headers={'Content-Disposition': 'name="tableau_datasource"; filename="Sample datasource.tds"'}) - file_path = self.server.workbooks.download_revision('9dbd2263-16b5-46e1-9c43-a76bb8ab65fb', "3", td) + m.get( + self.baseurl + "/9dbd2263-16b5-46e1-9c43-a76bb8ab65fb/revisions/3/content", + headers={"Content-Disposition": 'name="tableau_datasource"; filename="Sample datasource.tds"'}, + ) + file_path = self.server.workbooks.download_revision("9dbd2263-16b5-46e1-9c43-a76bb8ab65fb", "3", td) self.assertTrue(os.path.exists(file_path)) - From 2c84fedc4082858cbefcae265b67aab4d33f5e24 Mon Sep 17 00:00:00 2001 From: Jac Date: Thu, 27 Jan 2022 21:11:33 -0800 Subject: [PATCH 03/13] Update run-tests.yml just make black do the formatting instead of watching it complain --- .github/workflows/run-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 93ba83b5a..297c62dd2 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -27,7 +27,7 @@ jobs: - name: Format with black run: | - black --check --line-length 120 tableauserverclient samples test + black --line-length 120 tableauserverclient samples test - name: Test with pytest if: always() From 2f98ac7c0137398c1d6c1d1c401efe65c27250a9 Mon Sep 17 00:00:00 2001 From: Jac Date: Thu, 27 Jan 2022 21:25:12 -0800 Subject: [PATCH 04/13] Update interval_item.py fixing DailyInterval has no attribute 'interval' --- tableauserverclient/models/interval_item.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tableauserverclient/models/interval_item.py b/tableauserverclient/models/interval_item.py index 320e01ef2..835463d09 100644 --- a/tableauserverclient/models/interval_item.py +++ b/tableauserverclient/models/interval_item.py @@ -84,8 +84,9 @@ def _interval_type_pairs(self): class DailyInterval(object): - def __init__(self, start_time): + def __init__(self, start_time, *interval_values): self.start_time = start_time + self.interval = interval_values @property def _frequency(self): @@ -100,6 +101,13 @@ def start_time(self): @property_not_nullable def start_time(self, value): self._start_time = value + + @property + def interval(self): + return self._interval + + @interval.setter + def interval(self, interval): class WeeklyInterval(object): From 86d3ed7ea0697f264367fd63a0e41be9554588e8 Mon Sep 17 00:00:00 2001 From: Jac Date: Thu, 27 Jan 2022 21:27:59 -0800 Subject: [PATCH 05/13] Update interval_item.py --- tableauserverclient/models/interval_item.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tableauserverclient/models/interval_item.py b/tableauserverclient/models/interval_item.py index 835463d09..bf252a73b 100644 --- a/tableauserverclient/models/interval_item.py +++ b/tableauserverclient/models/interval_item.py @@ -108,6 +108,7 @@ def interval(self): @interval.setter def interval(self, interval): + self._interval = interval_values class WeeklyInterval(object): From e4382a1b8d033bf4acf710154bd34dd91babbc79 Mon Sep 17 00:00:00 2001 From: Jac Date: Thu, 27 Jan 2022 21:31:02 -0800 Subject: [PATCH 06/13] Update interval_item.py --- tableauserverclient/models/interval_item.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tableauserverclient/models/interval_item.py b/tableauserverclient/models/interval_item.py index bf252a73b..ffb43c3af 100644 --- a/tableauserverclient/models/interval_item.py +++ b/tableauserverclient/models/interval_item.py @@ -108,7 +108,7 @@ def interval(self): @interval.setter def interval(self, interval): - self._interval = interval_values + self._interval = interval class WeeklyInterval(object): From de397eec9055f646e72d0f6295b5b1f01f496cfc Mon Sep 17 00:00:00 2001 From: Jac Date: Thu, 27 Jan 2022 21:40:35 -0800 Subject: [PATCH 07/13] Update schedules_endpoint.py mypy error: tableauserverclient/server/endpoint/schedules_endpoint.py:118: error: Argument 1 to "append" of "list" has incompatible type "Tuple[DatasourceItem, str, Callable[[Optional[str], str], bytes]]"; expected "Tuple[WorkbookItem, str, Callable[[Optional[str], str], bytes]]" [arg-type] --- tableauserverclient/server/endpoint/schedules_endpoint.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tableauserverclient/server/endpoint/schedules_endpoint.py b/tableauserverclient/server/endpoint/schedules_endpoint.py index 28f8d7650..3c7de5b82 100644 --- a/tableauserverclient/server/endpoint/schedules_endpoint.py +++ b/tableauserverclient/server/endpoint/schedules_endpoint.py @@ -112,4 +112,4 @@ def add_to( results = (add_to(*x) for x in items) # list() is needed for python 3.x compatibility - return list(filter(lambda x: not x.result, results)) + return list(filter(lambda x: not x.result, results)) # type:ignore[arg-type] From 6e1445c072c09c162e49c13674274fbfc873bb95 Mon Sep 17 00:00:00 2001 From: Jac Date: Thu, 27 Jan 2022 21:51:55 -0800 Subject: [PATCH 08/13] actually format with black --- .../server/endpoint/schedules_endpoint.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tableauserverclient/server/endpoint/schedules_endpoint.py b/tableauserverclient/server/endpoint/schedules_endpoint.py index 3c7de5b82..eafcd1264 100644 --- a/tableauserverclient/server/endpoint/schedules_endpoint.py +++ b/tableauserverclient/server/endpoint/schedules_endpoint.py @@ -80,7 +80,13 @@ def add_to_schedule( def add_to( resource: Union["DatasourceItem", "WorkbookItem"], type_: str, - req_factory: Callable[[str, str,], bytes] + req_factory: Callable[ + [ + str, + str, + ], + bytes, + ], ) -> AddResponse: id_ = resource.id url = "{0}/{1}/{2}s".format(self.siteurl, schedule_id, type_) @@ -112,4 +118,4 @@ def add_to( results = (add_to(*x) for x in items) # list() is needed for python 3.x compatibility - return list(filter(lambda x: not x.result, results)) # type:ignore[arg-type] + return list(filter(lambda x: not x.result, results)) # type:ignore[arg-type] From a1281e9a3c6cd2d9f380c83da83bc3e19d59101a Mon Sep 17 00:00:00 2001 From: Jac Date: Thu, 27 Jan 2022 21:55:35 -0800 Subject: [PATCH 09/13] Update run-tests.yml add back 'check' --- .github/workflows/run-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 297c62dd2..93ba83b5a 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -27,7 +27,7 @@ jobs: - name: Format with black run: | - black --line-length 120 tableauserverclient samples test + black --check --line-length 120 tableauserverclient samples test - name: Test with pytest if: always() From f56e7743a00227da2ab5da162b7606da3a426606 Mon Sep 17 00:00:00 2001 From: Jac Date: Thu, 27 Jan 2022 21:55:56 -0800 Subject: [PATCH 10/13] Update schedules_endpoint.py --- tableauserverclient/server/endpoint/schedules_endpoint.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tableauserverclient/server/endpoint/schedules_endpoint.py b/tableauserverclient/server/endpoint/schedules_endpoint.py index eafcd1264..9e9a033b8 100644 --- a/tableauserverclient/server/endpoint/schedules_endpoint.py +++ b/tableauserverclient/server/endpoint/schedules_endpoint.py @@ -114,7 +114,9 @@ def add_to( if workbook is not None: items.append((workbook, "workbook", RequestFactory.Schedule.add_workbook_req)) if datasource is not None: - items.append((datasource, "datasource", RequestFactory.Schedule.add_datasource_req)) # type:ignore[arg-type] + items.append( + (datasource, "datasource", RequestFactory.Schedule.add_datasource_req) # type:ignore[arg-type] + ) results = (add_to(*x) for x in items) # list() is needed for python 3.x compatibility From 969e04a46b79b1c305cf1919a39b33bad8581033 Mon Sep 17 00:00:00 2001 From: Jac Date: Thu, 27 Jan 2022 21:57:28 -0800 Subject: [PATCH 11/13] Update schedule_item.py --- tableauserverclient/models/schedule_item.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tableauserverclient/models/schedule_item.py b/tableauserverclient/models/schedule_item.py index 2130976a5..3eac9a3fb 100644 --- a/tableauserverclient/models/schedule_item.py +++ b/tableauserverclient/models/schedule_item.py @@ -18,6 +18,7 @@ Interval = Union[HourlyInterval, DailyInterval, WeeklyInterval, MonthlyInterval] + class ScheduleItem(object): class Type: Extract = "Extract" From 43622d267d1affbe4eb8a92d72f39bbb95b903a3 Mon Sep 17 00:00:00 2001 From: Jac Date: Thu, 27 Jan 2022 22:00:55 -0800 Subject: [PATCH 12/13] Update test_schedule.py --- test/test_schedule.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/test_schedule.py b/test/test_schedule.py index 078097941..73f61008e 100644 --- a/test/test_schedule.py +++ b/test/test_schedule.py @@ -167,8 +167,9 @@ def test_create_weekly(self) -> None: self.assertEqual("2016-09-16T16:15:00Z", format_datetime(new_schedule.next_run_at)) self.assertEqual(TSC.ScheduleItem.ExecutionOrder.Parallel, new_schedule.execution_order) self.assertEqual(time(9, 15), new_schedule.interval_item.start_time) - self.assertEqual(("Monday", "Wednesday", "Friday"), - new_schedule.interval_item.interval) # type: ignore[union-attr] + self.assertEqual( + ("Monday", "Wednesday", "Friday"), new_schedule.interval_item.interval + ) # type: ignore[union-attr] self.assertEqual(2, len(new_schedule.warnings)) self.assertEqual("warning 1", new_schedule.warnings[0]) self.assertEqual("warning 2", new_schedule.warnings[1]) @@ -225,8 +226,7 @@ def test_update(self) -> None: self.assertEqual("2016-09-16T14:00:00Z", format_datetime(single_schedule.next_run_at)) self.assertEqual(TSC.ScheduleItem.ExecutionOrder.Parallel, single_schedule.execution_order) self.assertEqual(time(7), single_schedule.interval_item.start_time) - self.assertEqual(("Monday", "Friday"), - single_schedule.interval_item.interval) # type: ignore[union-attr] + self.assertEqual(("Monday", "Friday"), single_schedule.interval_item.interval) # type: ignore[union-attr] self.assertEqual(TSC.ScheduleItem.State.Suspended, single_schedule.state) # Tests calling update with a schedule item returned from the server From 149ee8246c212216c448a9d300f75412fa62c312 Mon Sep 17 00:00:00 2001 From: Jac Date: Thu, 27 Jan 2022 22:02:06 -0800 Subject: [PATCH 13/13] Update interval_item.py --- tableauserverclient/models/interval_item.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tableauserverclient/models/interval_item.py b/tableauserverclient/models/interval_item.py index ffb43c3af..cf5e70353 100644 --- a/tableauserverclient/models/interval_item.py +++ b/tableauserverclient/models/interval_item.py @@ -101,11 +101,11 @@ def start_time(self): @property_not_nullable def start_time(self, value): self._start_time = value - + @property def interval(self): return self._interval - + @interval.setter def interval(self, interval): self._interval = interval