From 47f6666b9c33f4d69629fc09fa8c38cf583a1719 Mon Sep 17 00:00:00 2001 From: William Lang Date: Thu, 13 Jul 2017 09:42:11 -0700 Subject: [PATCH 1/8] add workbook id to tasks and add tests --- tableauserverclient/models/task_item.py | 9 ++++-- test/assets/tasks_no_workbook.xml | 22 +++++++++++++ test/assets/tasks_with_workbook.xml | 25 ++++++++++++++ test/test_task.py | 43 +++++++++++++++++++++++++ 4 files changed, 97 insertions(+), 2 deletions(-) create mode 100644 test/assets/tasks_no_workbook.xml create mode 100644 test/assets/tasks_with_workbook.xml create mode 100644 test/test_task.py diff --git a/tableauserverclient/models/task_item.py b/tableauserverclient/models/task_item.py index b87c0eaa6..4869038de 100644 --- a/tableauserverclient/models/task_item.py +++ b/tableauserverclient/models/task_item.py @@ -4,12 +4,13 @@ class TaskItem(object): - def __init__(self, id_, task_type, priority, consecutive_failed_count=0, schedule_id=None): + def __init__(self, id_, task_type, priority, consecutive_failed_count=0, schedule_id=None, workbook_id=None): self.id = id_ self.task_type = task_type self.priority = priority self.consecutive_failed_count = consecutive_failed_count self.schedule_id = schedule_id + self.workbook_id = workbook_id def __repr__(self): return " + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/assets/tasks_with_workbook.xml b/test/assets/tasks_with_workbook.xml new file mode 100644 index 000000000..412c496f5 --- /dev/null +++ b/test/assets/tasks_with_workbook.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/test_task.py b/test/test_task.py new file mode 100644 index 000000000..bdf67847f --- /dev/null +++ b/test/test_task.py @@ -0,0 +1,43 @@ +from datetime import time +import unittest +import os +import requests_mock +import tableauserverclient as TSC +from tableauserverclient.datetime_helpers import format_datetime + +TEST_ASSET_DIR = os.path.join(os.path.dirname(__file__), "assets") + +GET_XML_NO_WORKBOOK = os.path.join(TEST_ASSET_DIR, "tasks_no_workbook.xml") +GET_XML_WITH_WORKBOOK = os.path.join(TEST_ASSET_DIR, "tasks_with_workbook.xml") + + +class TaskTests(unittest.TestCase): + def setUp(self): + self.server = TSC.Server("http://test") + self.server.version = '2.6' + + # Fake Signin + self.server._site_id = "dad65087-b08b-4603-af4e-2887b8aafc67" + self.server._auth_token = "j80k54ll2lfMZ0tv97mlPvvSCRyD0DOM" + + self.baseurl = self.server.tasks.baseurl + + def test_get_tasks_with_no_workbook(self): + with open(GET_XML_NO_WORKBOOK, "rb") as f: + response_xml = f.read().decode("utf-8") + with requests_mock.mock() as m: + m.get(self.baseurl, text=response_xml) + all_tasks, pagination_item = self.server.tasks.get() + + task = all_tasks[0] + self.assertEqual(None, task.workbook_id) + + def test_get_tasks_with_workbook(self): + with open(GET_XML_WITH_WORKBOOK, "rb") as f: + response_xml = f.read().decode("utf-8") + with requests_mock.mock() as m: + m.get(self.baseurl, text=response_xml) + all_tasks, pagination_item = self.server.tasks.get() + + task = all_tasks[0] + self.assertEqual('c7a9327e-1cda-4504-b026-ddb43b976d1d', task.workbook_id) From 8f94e29bd4b8eb1f75e7d6e2f8a9411d9b579f99 Mon Sep 17 00:00:00 2001 From: William Lang Date: Thu, 13 Jul 2017 09:45:41 -0700 Subject: [PATCH 2/8] add workbook id to __repr__ --- tableauserverclient/models/task_item.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tableauserverclient/models/task_item.py b/tableauserverclient/models/task_item.py index 4869038de..494429bed 100644 --- a/tableauserverclient/models/task_item.py +++ b/tableauserverclient/models/task_item.py @@ -14,7 +14,7 @@ def __init__(self, id_, task_type, priority, consecutive_failed_count=0, schedul def __repr__(self): return "".format(**self.__dict__) + "schedule_id}) workbook_id({workbook_id})>".format(**self.__dict__) @classmethod def from_response(cls, xml): From 8aec69b9370fa3afb925a67f2672d2e293773204 Mon Sep 17 00:00:00 2001 From: William Lang Date: Thu, 13 Jul 2017 09:48:00 -0700 Subject: [PATCH 3/8] remove unused imports --- test/test_task.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/test_task.py b/test/test_task.py index bdf67847f..2baa27953 100644 --- a/test/test_task.py +++ b/test/test_task.py @@ -1,9 +1,7 @@ -from datetime import time import unittest import os import requests_mock import tableauserverclient as TSC -from tableauserverclient.datetime_helpers import format_datetime TEST_ASSET_DIR = os.path.join(os.path.dirname(__file__), "assets") From 9ad2544fe0e84c21525567fe2eb2879f1429e15b Mon Sep 17 00:00:00 2001 From: William Lang Date: Mon, 17 Jul 2017 16:49:34 -0700 Subject: [PATCH 4/8] add target class to abstract references to other objects --- tableauserverclient/models/target.py | 14 ++++++++ tableauserverclient/models/task_item.py | 24 ++++++++++---- ...ml => tasks_no_workbook_or_datasource.xml} | 0 test/assets/tasks_with_datasource.xml | 13 ++++++++ test/assets/tasks_with_workbook.xml | 12 ------- .../tasks_with_workbook_and_datasource.xml | 25 +++++++++++++++ test/test_task.py | 32 ++++++++++++++++--- 7 files changed, 97 insertions(+), 23 deletions(-) create mode 100644 tableauserverclient/models/target.py rename test/assets/{tasks_no_workbook.xml => tasks_no_workbook_or_datasource.xml} (100%) create mode 100644 test/assets/tasks_with_datasource.xml create mode 100644 test/assets/tasks_with_workbook_and_datasource.xml diff --git a/tableauserverclient/models/target.py b/tableauserverclient/models/target.py new file mode 100644 index 000000000..533ffba6b --- /dev/null +++ b/tableauserverclient/models/target.py @@ -0,0 +1,14 @@ +"""Target class meant to abstract mappings to other objects""" +class Target(): + def __init__(self, id, target_type): + self.id = id + self.target_type = target_type + + def __repr__(self): + return "" + + def get_type(self): + return self.target_type + + def get_id(self): + return self.id diff --git a/tableauserverclient/models/task_item.py b/tableauserverclient/models/task_item.py index 494429bed..a143afc25 100644 --- a/tableauserverclient/models/task_item.py +++ b/tableauserverclient/models/task_item.py @@ -1,20 +1,20 @@ import xml.etree.ElementTree as ET from .. import NAMESPACE from .schedule_item import ScheduleItem +from .target import Target class TaskItem(object): - def __init__(self, id_, task_type, priority, consecutive_failed_count=0, schedule_id=None, workbook_id=None): + def __init__(self, id_, task_type, priority, consecutive_failed_count=0, schedule_id=None, target=None): self.id = id_ self.task_type = task_type self.priority = priority self.consecutive_failed_count = consecutive_failed_count - self.schedule_id = schedule_id - self.workbook_id = workbook_id + self.target = target def __repr__(self): return "".format(**self.__dict__) + "schedule_id}) target({target})>".format(**self.__dict__) @classmethod def from_response(cls, xml): @@ -29,15 +29,25 @@ def from_response(cls, xml): @classmethod def _parse_element(cls, element): schedule = None - workbook = None + target = None schedule_element = element.find('.//t:schedule', namespaces=NAMESPACE) workbook_element = element.find('.//t:workbook', namespaces=NAMESPACE) + datasource_element = element.find('.//t:datasource', namespaces=NAMESPACE) if schedule_element is not None: schedule = schedule_element.get('id', None) + + # according to the Tableau Server REST API documentation, + # there should be only one of workbook or datasource if workbook_element is not None: - workbook = workbook_element.get('id', None) + workbook_id = workbook_element.get('id', None) + target = Target(workbook_id, "workbook") + if datasource_element is not None: + datasource_id = datasource_element.get('id', None) + target = Target(datasource_id, "datasource") + # + task_type = element.get('type', None) priority = int(element.get('priority', -1)) consecutive_failed_count = int(element.get('consecutiveFailedCount', 0)) id_ = element.get('id', None) - return cls(id_, task_type, priority, consecutive_failed_count, schedule, workbook) + return cls(id_, task_type, priority, consecutive_failed_count, schedule, target) diff --git a/test/assets/tasks_no_workbook.xml b/test/assets/tasks_no_workbook_or_datasource.xml similarity index 100% rename from test/assets/tasks_no_workbook.xml rename to test/assets/tasks_no_workbook_or_datasource.xml diff --git a/test/assets/tasks_with_datasource.xml b/test/assets/tasks_with_datasource.xml new file mode 100644 index 000000000..68e23a417 --- /dev/null +++ b/test/assets/tasks_with_datasource.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/test/assets/tasks_with_workbook.xml b/test/assets/tasks_with_workbook.xml index 412c496f5..1565abf74 100644 --- a/test/assets/tasks_with_workbook.xml +++ b/test/assets/tasks_with_workbook.xml @@ -9,17 +9,5 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/test/assets/tasks_with_workbook_and_datasource.xml b/test/assets/tasks_with_workbook_and_datasource.xml new file mode 100644 index 000000000..4389fa06c --- /dev/null +++ b/test/assets/tasks_with_workbook_and_datasource.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/test_task.py b/test/test_task.py index 2baa27953..8c3a5a6b0 100644 --- a/test/test_task.py +++ b/test/test_task.py @@ -5,9 +5,10 @@ TEST_ASSET_DIR = os.path.join(os.path.dirname(__file__), "assets") -GET_XML_NO_WORKBOOK = os.path.join(TEST_ASSET_DIR, "tasks_no_workbook.xml") +GET_XML_NO_WORKBOOK = os.path.join(TEST_ASSET_DIR, "tasks_no_workbook_or_datasource.xml") GET_XML_WITH_WORKBOOK = os.path.join(TEST_ASSET_DIR, "tasks_with_workbook.xml") - +GET_XML_WITH_DATASOURCE = os.path.join(TEST_ASSET_DIR, "tasks_with_datasource.xml") +GET_XML_WITH_WORKBOOK_AND_DATASOURCE = os.path.join(TEST_ASSET_DIR, "tasks_with_workbook_and_datasource.xml") class TaskTests(unittest.TestCase): def setUp(self): @@ -28,7 +29,7 @@ def test_get_tasks_with_no_workbook(self): all_tasks, pagination_item = self.server.tasks.get() task = all_tasks[0] - self.assertEqual(None, task.workbook_id) + self.assertEqual(None, task.target) def test_get_tasks_with_workbook(self): with open(GET_XML_WITH_WORKBOOK, "rb") as f: @@ -38,4 +39,27 @@ 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.workbook_id) + self.assertEqual('c7a9327e-1cda-4504-b026-ddb43b976d1d', task.target.id) + self.assertEqual('workbook', task.target.target_type) + + def test_get_tasks_with_datasource(self): + with open(GET_XML_WITH_DATASOURCE, "rb") as f: + response_xml = f.read().decode("utf-8") + with requests_mock.mock() as m: + m.get(self.baseurl, text=response_xml) + 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.target_type) + + def test_get_tasks_with_workbook_and_datasource(self): + with open(GET_XML_WITH_WORKBOOK_AND_DATASOURCE, "rb") as f: + response_xml = f.read().decode("utf-8") + with requests_mock.mock() as m: + m.get(self.baseurl, text=response_xml) + all_tasks, pagination_item = self.server.tasks.get() + + self.assertEqual('workbook', all_tasks[0].target.target_type) + self.assertEqual('datasource', all_tasks[1].target.target_type) + self.assertEqual('workbook', all_tasks[2].target.target_type) \ No newline at end of file From 30c228c7ab514e04f649b555b1c30a157cdd5081 Mon Sep 17 00:00:00 2001 From: William Lang Date: Mon, 17 Jul 2017 16:52:54 -0700 Subject: [PATCH 5/8] forgot a new line --- test/test_task.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_task.py b/test/test_task.py index 8c3a5a6b0..637f458f4 100644 --- a/test/test_task.py +++ b/test/test_task.py @@ -62,4 +62,4 @@ def test_get_tasks_with_workbook_and_datasource(self): self.assertEqual('workbook', all_tasks[0].target.target_type) self.assertEqual('datasource', all_tasks[1].target.target_type) - self.assertEqual('workbook', all_tasks[2].target.target_type) \ No newline at end of file + self.assertEqual('workbook', all_tasks[2].target.target_type) From aa80e6d75eb5a6ddb4aeea97fadee81c03c37675 Mon Sep 17 00:00:00 2001 From: William Lang Date: Mon, 17 Jul 2017 16:55:37 -0700 Subject: [PATCH 6/8] aaaand another new line --- test/test_task.py | 1 + 1 file changed, 1 insertion(+) diff --git a/test/test_task.py b/test/test_task.py index 637f458f4..56d9c6130 100644 --- a/test/test_task.py +++ b/test/test_task.py @@ -10,6 +10,7 @@ GET_XML_WITH_DATASOURCE = os.path.join(TEST_ASSET_DIR, "tasks_with_datasource.xml") GET_XML_WITH_WORKBOOK_AND_DATASOURCE = os.path.join(TEST_ASSET_DIR, "tasks_with_workbook_and_datasource.xml") + class TaskTests(unittest.TestCase): def setUp(self): self.server = TSC.Server("http://test") From 4e107ad59a093cbe20977eb81e3577d32eada7f9 Mon Sep 17 00:00:00 2001 From: William Lang Date: Wed, 19 Jul 2017 10:42:40 -0700 Subject: [PATCH 7/8] add test for schedule id, refactor target --- tableauserverclient/models/target.py | 16 ++++++---------- tableauserverclient/models/task_item.py | 1 + test/test_task.py | 22 +++++++++++++++++----- 3 files changed, 24 insertions(+), 15 deletions(-) diff --git a/tableauserverclient/models/target.py b/tableauserverclient/models/target.py index 533ffba6b..2f784fb6a 100644 --- a/tableauserverclient/models/target.py +++ b/tableauserverclient/models/target.py @@ -1,14 +1,10 @@ """Target class meant to abstract mappings to other objects""" -class Target(): - def __init__(self, id, target_type): - self.id = id - self.target_type = target_type - def __repr__(self): - return "" - def get_type(self): - return self.target_type +class Target(): + def __init__(self, id_, target_type): + self.id = id_ + self.type = target_type - def get_id(self): - return self.id + def __repr__(self): + return "".format(**self.__dict__) diff --git a/tableauserverclient/models/task_item.py b/tableauserverclient/models/task_item.py index a143afc25..c82dcf07f 100644 --- a/tableauserverclient/models/task_item.py +++ b/tableauserverclient/models/task_item.py @@ -10,6 +10,7 @@ def __init__(self, id_, task_type, priority, consecutive_failed_count=0, schedul self.task_type = task_type self.priority = priority self.consecutive_failed_count = consecutive_failed_count + self.schedule_id = schedule_id self.target = target def __repr__(self): diff --git a/test/test_task.py b/test/test_task.py index 56d9c6130..2529f811a 100644 --- a/test/test_task.py +++ b/test/test_task.py @@ -41,7 +41,7 @@ def test_get_tasks_with_workbook(self): task = all_tasks[0] self.assertEqual('c7a9327e-1cda-4504-b026-ddb43b976d1d', task.target.id) - self.assertEqual('workbook', task.target.target_type) + self.assertEqual('workbook', task.target.type) def test_get_tasks_with_datasource(self): with open(GET_XML_WITH_DATASOURCE, "rb") as f: @@ -52,7 +52,7 @@ def test_get_tasks_with_datasource(self): task = all_tasks[0] self.assertEqual('c7a9327e-1cda-4504-b026-ddb43b976d1d', task.target.id) - self.assertEqual('datasource', task.target.target_type) + 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: @@ -61,6 +61,18 @@ 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.target_type) - self.assertEqual('datasource', all_tasks[1].target.target_type) - self.assertEqual('workbook', all_tasks[2].target.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: + response_xml = f.read().decode("utf-8") + with requests_mock.mock() as m: + m.get(self.baseurl, text=response_xml) + 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) From b8757f119c85e7276a04338312f948a96d81ae8d Mon Sep 17 00:00:00 2001 From: William Lang Date: Thu, 20 Jul 2017 10:43:39 -0700 Subject: [PATCH 8/8] remove # --- tableauserverclient/models/task_item.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tableauserverclient/models/task_item.py b/tableauserverclient/models/task_item.py index c82dcf07f..2693bda30 100644 --- a/tableauserverclient/models/task_item.py +++ b/tableauserverclient/models/task_item.py @@ -45,7 +45,6 @@ def _parse_element(cls, element): if datasource_element is not None: datasource_id = datasource_element.get('id', None) target = Target(datasource_id, "datasource") - # task_type = element.get('type', None) priority = int(element.get('priority', -1))