8000 Support for Certified Data Sources in the REST API (#189) · gaoang2148/server-client-python@b2b8593 · GitHub
[go: up one dir, main page]

Skip to content

Commit b2b8593

Browse files
authored
Support for Certified Data Sources in the REST API (tableau#189)
* Support for Certified Data Sources in the REST API
1 parent aecfe7d commit b2b8593

File tree

5 files changed

+52
-13
lines changed

5 files changed

+52
-13
lines changed

tableauserverclient/models/datasource_item.py

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import xml.etree.ElementTree as ET
22
from .exceptions import UnpopulatedPropertyError
3-
from .property_decorators import property_not_nullable
3+
from .property_decorators import property_not_nullable, property_is_boolean
44
from .tag_item import TagItem
55
from .. import NAMESPACE
66
from ..datetime_helpers import parse_datetime
@@ -17,6 +17,8 @@ def __init__(self, project_id, name=None):
1717
self._initial_tags = set()
1818
self._project_name = None
1919
self._updated_at = None
20+
self._certified = None
21+
self._certification_note = None
2022
self.name = name
2123
self.owner_id = None
2224
self.project_id = project_id
@@ -37,6 +39,24 @@ def content_url(self):
3739
def created_at(self):
3840
return self._created_at
3941

42+
@property
43+
def certified(self):
44+
return self._certified
45+
46+
@certified.setter
47+
@property_not_nullable
48+
@property_is_boolean
49+
def certified(self, value):
50+
self._certified = value
51+
52+
@property
53+
def certification_note(self):
54+
return self._certification_note
55+
56+
@certification_note.setter
57+
def certification_note(self, value):
58+
self._certification_note = value
59+
4060
@property
4161
def id(self):
4262
return self._id
@@ -65,16 +85,18 @@ def updated_at(self):
6585
def _set_connections(self, connections):
6686
self._connections = connections
6787

68-
def _parse_common_tags(self, datasource_xml):
88+
def _parse_common_elements(self, datasource_xml):
6989
if not isinstance(datasource_xml, ET.Element):
7090
datasource_xml = ET.fromstring(datasource_xml).find('.//t:datasource', namespaces=NAMESPACE)
7191
if datasource_xml is not None:
72-
(_, _, _, _, _, updated_at, _, project_id, project_name, owner_id) = self._parse_element(datasource_xml)
73-
self._set_values(None, None, None, None, None, updated_at, None, project_id, project_name, owner_id)
92+
(_, _, _, _, _, updated_at, _, project_id, project_name, owner_id,
93+
certified, certification_note) = self._parse_element(datasource_xml)
94+
self._set_values(None, None, None, None, None, updated_at, None, project_id,
95+
project_name, owner_id, certified, certification_note)
7496
return self
7597

7698
def _set_values(self, id, name, datasource_type, content_url, created_at,
77-
updated_at, tags, project_id, project_name, owner_id):
99+
updated_at, tags, project_id, project_name, owner_id, certified, certification_note):
78100
if id is not None:
79101
self._id = id
80102
if name:
@@ -96,6 +118,9 @@ def _set_values(self, id, name, datasource_type, content_url, created_at,
96118
self._project_name = project_name
97119
if owner_id:
98120
self.owner_id = owner_id
121+
if certification_note:
122+
self.certification_note = certification_note
123+
self.certified = certified # Always True/False, not conditional
99124

100125
@classmethod
101126
def from_response(cls, resp):
@@ -104,22 +129,25 @@ def from_response(cls, resp):
104129
all_datasource_xml = parsed_response.findall('.//t:datasource', namespaces=NAMESPACE)
105130

106131
for datasource_xml in all_datasource_xml:
107-
(id, name, datasource_type, content_url, created_at, updated_at,
108-
tags, project_id, project_name, owner_id) = cls._parse_element(datasource_xml)
132+
(id_, name, datasource_type, content_url, created_at, updated_at,
133+
tags, project_id, project_name, owner_id,
134+
certified, certification_note) = cls._parse_element(datasource_xml)
109135
datasource_item = cls(project_id)
110-
datasource_item._set_values(id, name, datasource_type, content_url, created_at, updated_at,
111-
tags, None, project_name, owner_id)
136+
datasource_item._set_values(id_, name, datasource_type, content_url, created_at, updated_at,
137+
tags, None, project_name, owner_id, certified, certification_note)
112138
all_datasource_items.append(datasource_item)
113139
return all_datasource_items
114140

115141
@staticmethod
116142
def _parse_element(datasource_xml):
117-
id = datasource_xml.get('id', None)
143+
id_ = datasource_xml.get('id', None)
118144
name = datasource_xml.get('name', None)
119145
datasource_type = datasource_xml.get('type', None)
120146
content_url = datasource_xml.get('contentUrl', None)
121147
created_at = parse_datetime(datasource_xml.get('createdAt', None))
122148
updated_at = parse_datetime(datasource_xml.get('updatedAt', None))
149+
certification_note = datasource_xml.get('certificationNote', None)
150+
certified = str(datasource_xml.get('isCertified', None)).lower() == 'true'
123151

124152
tags = None
125153
tags_elem = datasource_xml.find('.//t:tags', namespaces=NAMESPACE)
@@ -138,4 +166,5 @@ def _parse_element(datasource_xml):
138166
if owner_elem is not None:
139167
owner_id = owner_elem.get('id', None)
140168

141-
return id, name, datasource_type, content_url, created_at, updated_at, tags, project_id, project_name, owner_id
169+
return (id_, name, datasource_type, content_url, created_at, updated_at, tags, project_id,
170+
project_name, owner_id, certified, certification_note)

tableauserverclient/server/endpoint/datasources_endpoint.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ def update(self, datasource_item):
112112
server_response = self.put_request(url, update_req)
113113
logger.info('Updated datasource item (ID: {0})'.format(datasource_item.id))
114114
updated_datasource = copy.copy(datasource_item)
115-
return updated_datasource._parse_common_tags(server_response.content)
115+
return updated_datasource._parse_common_elements(server_response.content)
116116

117117
# Publish datasource
118118
@api(version="2.0")

tableauserverclient/server/request_factory.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,12 @@ def update_req(self, datasource_item):
6565
if datasource_item.owner_id:
6666
owner_element = ET.SubElement(datasource_element, 'owner')
6767
owner_element.attrib['id'] = datasource_item.owner_id
68+
69+
datasource_element.attrib['isCertified'] = str(datasource_item.certified).lower()
70+
71+
if datasource_item.certification_note:
72+
datasource_element.attrib['certificationNote'] = str(datasource_item.certification_note)
73+
6874
return ET.tostring(xml_request)
6975

7076
def publish_req(self, datasource_item, filename, file_contents, connection_credentials=None):

test/assets/datasource_update.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version='1.0' encoding='UTF-8'?>
22
<tsResponse xmlns="http://tableau.com/api" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://tableau.com/api http://tableau.com/api/ts-api-2.3.xsd">
3-
<datasource id="9dbd2263-16b5-46e1-9c43-a76bb8ab65fb" name="Sample datasource" contentUrl="Sampledatasource" type="dataengine" createdAt="2016-08-04T21:31:55Z" updatedAt="2016-08-17T20:13:13Z">
3+
<datasource id="9dbd2263-16b5-46e1-9c43-a76bb8ab65fb" name="Sample data BE96 source" contentUrl="Sampledatasource" type="dataengine" createdAt="2016-08-04T21:31:55Z" updatedAt="2016-08-17T20:13:13Z" isCertified="True" certificationNote="Warning, here be dragons.">
44
<project id="1d0304cd-3796-429f-b815-7258370b9b74" />
55
<owner id="dd2239f6-ddf1-4107-981a-4cf94e415794" />
66
</datasource>

test/test_datasource.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,11 +93,15 @@ def test_update(self):
9393
single_datasource = TSC.DatasourceItem('test', '1d0304cd-3796-429f-b815-7258370b9b74')
9494
single_datasource.owner_id = 'dd2239f6-ddf1-4107-981a-4cf94e415794'
9595
single_datasource._id = '9dbd2263-16b5-46e1-9c43-a76bb8ab65fb'
96+
single_datasource.certified = True
97+
single_datasource.certification_note = "Warning, here be dragons."
9698
single_datasource = self.server.datasources.update(single_datasource)
9799

98100
self.assertEqual('9dbd2263-16b5-46e1-9c43-a76bb8ab65fb', single_datasource.id)
99101
self.assertEqual('1d0304cd-3796-429f-b815-7258370b9b74', single_datasource.project_id)
100102
self.assertEqual('dd2239f6-ddf1-4107-981a-4cf94e415794', single_datasource.owner_id)
103+
self.assertEqual(True, single_datasource.certified)
104+
self.assertEqual("Warning, here be dragons.", single_datasource.certification_note)
101105

102106
def test_update_copy_fields(self):
103107
with open(UPDATE_XML, 'rb') as f:

0 commit comments

Comments
 (0)
0