8000 194 fix namespace issue (#219) · sbttc/server-client-python@ff60613 · GitHub
[go: up one dir, main page]

Skip to content

Commit ff60613

Browse files
author
Russell Hay
authored
194 fix namespace issue (tableau#219)
* Moving user endpoint to use dynamic namespace * move groups to using dynamic namespace * move PagintationItem to use dynamic namespace * move exceptions to use dynamic namespace * move workbooks to use dynamic namespace * move views to use dynamic namespace * move views to use dynamic namespace * move tasks to use dynamic namespace * move tags to use dynamic namespace * move datasource to use dynamic namespace * move connections item to use dynamic namespace * move site to use dynamic namespace * fix up tests and remove NAMESPACE * move namespace to be a property * Move detection into a Namespace class * Move to using the Namespace class * remove deprecated namespace code * better detection method from Tyler's suggestion * fixing pycodestyle failures * removing unneeded import * throwing an exception if there is a unknown namespace
1 parent de2fa26 commit ff60613

33 files changed

+194
-164
lines changed

tableauserverclient/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from .namespace import NAMESPACE
1+
from .namespace import NEW_NAMESPACE as DEFAULT_NAMESPACE
22
from .models import ConnectionCredentials, ConnectionItem, DatasourceItem,\
33
GroupItem, PaginationItem, ProjectItem, ScheduleItem, \
44
SiteItem, TableauAuth, UserItem, ViewItem, WorkbookItem, UnpopulatedPropertyError, \

tableauserverclient/models/connection_item.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import xml.etree.ElementTree as ET
2-
from .. import NAMESPACE
32

43

54
class ConnectionItem(object):
@@ -31,18 +30,18 @@ def connection_type(self):
3130
return self._connection_type
3231

3332
@classmethod
34-
def from_response(cls, resp):
33+
def from_response(cls, resp, ns):
3534
all_connection_items = list()
3635
parsed_response = ET.fromstring(resp)
37-
all_connection_xml = parsed_response.findall('.//t:connection', namespaces=NAMESPACE)
36+
all_connection_xml = parsed_response.findall('.//t:connection', namespaces=ns)
3837
for connection_xml in all_connection_xml:
3938
connection_item = cls()
4039
connection_item._id = connection_xml.get('id', None)
4140
connection_item._connection_type = connection_xml.get('type', None)
4241
connection_item.server_address = connection_xml.get('serverAddress', None)
4342
connection_item.server_port = connection_xml.get('serverPort', None)
4443
connection_item.username = connection_xml.get('userName', None)
45-
datasource_elem = connection_xml.find('.//t:datasource', namespaces=NAMESPACE)
44+
datasource_elem = connection_xml.find('.//t:datasource', namespaces=ns)
4645
if datasource_elem is not None:
4746
connection_item._datasource_id = datasource_elem.get('id', None)
4847
connection_item._datasource_name = datasource_elem.get('name', None)

tableauserverclient/models/datasource_item.py

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
from .exceptions import UnpopulatedPropertyError
33
from .property_decorators import property_not_nullable, property_is_boolean
44
from .tag_item import TagItem
5-
from .. import NAMESPACE
65
from ..datetime_helpers import parse_datetime
76
import copy
87

@@ -85,12 +84,12 @@ def updated_at(self):
8584
def _set_connections(self, connections):
8685
self._connections = connections
8786

88-
def _parse_common_elements(self, datasource_xml):
87+
def _parse_common_elements(self, datasource_xml, ns):
8988
if not isinstance(datasource_xml, ET.Element):
90-
datasource_xml = ET.fromstring(datasource_xml).find('.//t:datasource', namespaces=NAMESPACE)
89+
datasource_xml = ET.fromstring(datasource_xml).find('.//t:datasource', namespaces=ns)
9190
if datasource_xml is not None:
9291
(_, _, _, _, _, updated_at, _, project_id, project_name, owner_id,
93-
certified, certification_note) = self._parse_element(datasource_xml)
92+
certified, certification_note) = self._parse_element(datasource_xml, ns)
9493
self._set_values(None, None, None, None, None, updated_at, None, project_id,
9594
project_name, owner_id, certified, certification_note)
9695
return self
@@ -123,23 +122,23 @@ def _set_values(self, id, name, datasource_type, content_url, created_at,
123122
self.certified = certified # Always True/False, not conditional
124123

125124
@classmethod
126-
def from_response(cls, resp):
125+
def from_response(cls, resp, ns):
127126
all_datasource_items = list()
128127
parsed_response = ET.fromstring(resp)
129-
all_datasource_xml = parsed_response.findall('.//t:datasource', namespaces=NAMESPACE)
128+
all_datasource_xml = parsed_response.findall('.//t:datasource', namespaces=ns)
130129

131130
for datasource_xml in all_datasource_xml:
132131
(id_, name, datasource_type, content_url, created_at, updated_at,
133132
tags, project_id, project_name, owner_id,
134-
certified, certification_note) = cls._parse_element(datasource_xml)
133+
certified, certification_note) = cls._parse_element(datasource_xml, ns)
135134
datasource_item = cls(project_id)
136135
datasource_item._set_values(id_, name, datasource_type, content_url, created_at, updated_at,
137136
tags, None, project_name, owner_id, certified, certification_note)
138137
all_datasource_items.append(datasource_item)
139138
return all_datasource_items
140139

141140
@staticmethod
142-
def _parse_element(datasource_xml):
141+
def _parse_element(datasource_xml, ns):
143142
id_ = datasource_xml.get('id', None)
144143
name = datasource_xml.get('name', None)
145144
datasource_type = datasource_xml.get('type', None)
@@ -150,19 +149,19 @@ def _parse_element(datasource_xml):
150149
certified = str(datasource_xml.get('isCertified', None)).lower() == 'true'
151150

152151
tags = None
153-
tags_elem = datasource_xml.find('.//t:tags', namespaces=NAMESPACE)
152+
tags_elem = datasource_xml.find('.//t:tags', namespaces=ns)
154153
if tags_elem is not None:
155-
tags = TagItem.from_xml_element(tags_elem)
154+
tags = TagItem.from_xml_element(tags_elem, ns)
156155

157156
project_id = None
158157
project_name = None
159-
project_elem = datasource_xml.find('.//t:project', namespaces=NAMESPACE)
158+
project_elem = datasource_xml.find('.//t:project', namespaces=ns)
160159
if project_elem is not None:
161160
project_id = project_elem.get('id', None)
162161
project_name = project_elem.get('name', None)
163162

164163
owner_id = None
165-
owner_elem = datasource_xml.find('.//t:owner', namespaces=NAMESPACE)
164+
owner_elem = datasource_xml.find('.//t:owner', namespaces=ns)
166165
if owner_elem is not None:
167166
owner_id = owner_elem.get('id', None)
168167

tableauserverclient/models/fileupload_item.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import xml.etree.ElementTree as ET
2-
from .. import NAMESPACE
32

43

54
class FileuploadItem(object):
@@ -16,9 +15,9 @@ def file_size(self):
1615
return self._file_size
1716

1817
@classmethod
19-
def from_response(cls, resp):
18+
def from_response(cls, resp, ns):
2019
parsed_response = ET.fromstring(resp)
21-
fileupload_elem = parsed_response.find('.//t:fileUpload', namespaces=NAMESPACE)
20+
fileupload_elem = parsed_response.find('.//t:fileUpload', namespaces=ns)
2221
fileupload_item = cls()
2322
fileupload_item._upload_session_id = fileupload_elem.get('uploadSessionId', None)
2423
fileupload_item._file_size = fileupload_elem.get('fileSize', None)

tableauserverclient/models/group_item.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import xml.etree.ElementTree as ET
22
from .exceptions import UnpopulatedPropertyError
33
from .property_decorators import property_not_empty
4-
from .. import NAMESPACE
54

65

76
class GroupItem(object):
@@ -40,16 +39,16 @@ def _set_users(self, users):
4039
self._users = users
4140

4241
@classmethod
43-
def from_response(cls, resp):
42+
def from_response(cls, resp, ns):
4443
all_group_items = list()
4544
parsed_response = ET.fromstring(resp)
46-
all_group_xml = parsed_response.findall('.//t:group', namespaces=NAMESPACE)
45+
all_group_xml = parsed_response.findall('.//t:group', namespaces=ns)
4746
for group_xml in all_group_xml:
4847
name = group_xml.get('name', None)
4948
group_item = cls(name)
5049
group_item._id = group_xml.get('id', None)
5150

52-
domain_elem = group_xml.find('.//t:domain', namespaces=NAMESPACE)
51+
domain_elem = group_xml.find('.//t:domain', namespaces=ns)
5352
if domain_elem is not None:
5453
group_item._domain_name = domain_elem.get('name', None)
5554
all_group_items.append(group_item)

tableauserverclient/models/pagination_item.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import xml.etree.ElementTree as ET
2-
from .. import NAMESPACE
32

43

54
class PaginationItem(object):
@@ -21,9 +20,9 @@ def total_available(self):
2120
return self._total_available
2221

2322
@classmethod
24-
def from_response(cls, resp):
23+
def from_response(cls, resp, ns):
2524
parsed_response = ET.fromstring(resp)
26-
pagination_xml = parsed_response.find('t:pagination', namespaces=NAMESPACE)
25+
pagination_xml = parsed_response.find('t:pagination', namespaces=ns)
2726
pagination_item = cls()
2827
if pagination_xml is not None:
2928
pagination_item._page_number = int(pagination_xml.get('pageNumber', '-1'))

tableauserverclient/models/project_item.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import xml.etree.ElementTree as ET
22
from .property_decorators import property_is_enum, property_not_empty
3-
from .. import NAMESPACE
43

54

65
class ProjectItem(object):
@@ -63,10 +62,10 @@ def _set_values(self, project_id, name, description, content_permissions, parent
6362
self.parent_id = parent_id
6463

6564
@classmethod
66-
def from_response(cls, resp):
65+
def from_response(cls, resp, ns):
6766
all_project_items = list()
6867
parsed_response = ET.fromstring(resp)
69-
all_project_xml = parsed_response.findall('.//t:project', namespaces=NAMESPACE)
68+
all_project_xml = parsed_response.findall('.//t:project', namespaces=ns)
7069

7170
for project_xml in all_project_xml:
7271
(id, name, description, content_permissions, parent_id) = cls._parse_element(project_xml)

tableauserverclient/models/schedule_item.py

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
from .interval_item import IntervalItem, HourlyInterval, DailyInterval, WeeklyInterval, MonthlyInterval
55
from .property_decorators import property_is_enum, property_not_nullable, property_is_int
6-
from .. import NAMESPACE
76
from ..datetime_helpers import parse_datetime
87

98

@@ -102,12 +101,13 @@ def state(self, value):
102101
def updated_at(self):
103102
return self._updated_at
104103

105-
def _parse_common_tags(self, schedule_xml):
104+
def _parse_common_tags(self, schedule_xml, ns):
106105
if not isinstance(schedule_xml, ET.Element):
107-
schedule_xml = ET.fromstring(schedule_xml).find('.//t:schedule', namespaces=NAMESPACE)
106+
print(ns)
107+
schedule_xml = ET.fromstring(schedule_xml).find('.//t:schedule', namespaces=ns)
108108
if schedule_xml is not None:
109109
(_, name, _, _, updated_at, _, next_run_at, end_schedule_at, execution_order,
110-
priority, interval_item) = self._parse_element(schedule_xml)
110+
priority, interval_item) = self._parse_element(schedule_xml, ns)
111111

112112
self._set_values(id_=None,
113113
name=name,
@@ -149,17 +149,17 @@ def _set_values(self, id_, name, state, created_at, updated_at, schedule_type,
149149
self._interval_item = interval_item
150150

151151
@classmethod
152-
def from_response(cls, resp):
152+
def from_response(cls, resp, ns):
153153
parsed_response = ET.fromstring(resp)
154-
return cls.from_element(parsed_response)
154+
return cls.from_element(parsed_response, ns)
155155

156156
@classmethod
157-
def from_element(cls, parsed_response):
157+
def from_element(cls, parsed_response, ns):
158158
all_schedule_items = []
159-
all_schedule_xml = parsed_response.findall('.//t:schedule', namespaces=NAMESPACE)
159+
all_schedule_xml = parsed_response.findall('.//t:schedule', namespaces=ns)
160160
for schedule_xml in all_schedule_xml:
161161
(id_, name, state, created_at, updated_at, schedule_type, next_run_at,
162-
end_schedule_at, execution_order, priority, interval_item) = cls._parse_element(schedule_xml)
162+
end_schedule_at, execution_order, priority, interval_item) = cls._parse_element(schedule_xml, ns)
163163

164164
schedule_item = cls(name, priority, schedule_type, execution_order, interval_item)
165165

@@ -179,13 +179,13 @@ def from_element(cls, parsed_response):
179179
return all_schedule_items
180180

181181
@staticmethod
182-
def _parse_interval_item(parsed_response, frequency):
182+
def _parse_interval_item(parsed_response, frequency, ns):
183183
start_time = parsed_response.get("start", None)
184184
start_time = datetime.strptime(start_time, "%H:%M:%S").time()
185185
end_time = parsed_response.get("end", None)
186186
if end_time is not None:
187187
end_time = datetime.strptime(end_time, "%H:%M:%S").time()
188-
interval_elems = parsed_response.findall(".//t:intervals/t:interval", namespaces=NAMESPACE)
188+
interval_elems = parsed_response.findall(".//t:intervals/t:interval", namespaces=ns)
189189
interval = []
190190
for interval_elem in interval_elems:
191191
interval.extend(interval_elem.attrib.items())
@@ -212,7 +212,7 @@ def _parse_interval_item(parsed_response, frequency):
212212
return MonthlyInterval(start_time, interval_value)
213213

214214
@staticmethod
215-
def _parse_element(schedule_xml):
215+
def _parse_element(schedule_xml, ns):
216216
id = schedule_xml.get('id', None)
217217
name = schedule_xml.get('name', None)
218218
state = schedule_xml.get('state', None)
@@ -229,9 +229,9 @@ def _parse_element(schedule_xml):
229229
priority = int(priority)
230230

231231
interval_item = None
232-
frequency_detail_elem = schedule_xml.find('.//t:frequencyDetails', namespaces=NAMESPACE)
232+
frequency_detail_elem = schedule_xml.find('.//t:frequencyDetails', namespaces=ns)
233233
if frequency_detail_elem is not None:
234-
interval_item = ScheduleItem._parse_interval_item(frequency_detail_elem, frequency)
234+
interval_item = ScheduleItem._parse_interval_item(frequency_detail_elem, frequency, ns)
235235

236236
return id, name, state, created_at, updated_at, schedule_type, \
237237
next_run_at, end_schedule_at, execution_order, priority, interval_item

tableauserverclient/models/server_info_item.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import xml.etree.ElementTree as ET
2-
from .. import NAMESPACE
32

43

54
class ServerInfoItem(object):
@@ -21,10 +20,10 @@ def rest_api_version(self):
2120
return self._rest_api_version
2221

2322
@classmethod
24-
def from_response(cls, resp):
23+
def from_response(cls, resp, ns):
2524
parsed_response = ET.fromstring(resp)
26-
product_version_tag = parsed_response.find('.//t:productVersion', namespaces=NAMESPACE)
27-
rest_api_version_tag = parsed_response.find('.//t:restApiVersion', namespaces=NAMESPACE)
25+
product_version_tag = parsed_response.find('.//t:productVersion', namespaces=ns)
26+
rest_api_version_tag = parsed_response.find('.//t:restApiVersion', namespaces=ns)
2827

2928
build_number = product_version_tag.get('build', None)
3029
product_version = product_version_tag.text

tableauserverclient/models/site_item.py

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import xml.etree.ElementTree as ET
22
from .property_decorators import (property_is_enum, property_is_boolean, property_matches,
33
property_not_empty, property_not_nullable, property_is_int)
4-
from .. import NAMESPACE
54

65

76
VALID_CONTENT_URL_RE = r"^[a-zA-Z0-9_\-]*$"
@@ -127,13 +126,13 @@ def subscribe_others_enabled(self, value):
127126
def is_default(self):
128127
return self.name.lower() == 'default'
129128

130-
def _parse_common_tags(self, site_xml):
129+
def _parse_common_tags(self, site_xml, ns):
131130
if not isinstance(site_xml, ET.Element):
132-
site_xml = ET.fromstring(site_xml).find('.//t:site', namespaces=NAMESPACE)
131+
site_xml = ET.fromstring(site_xml).find('.//t:site', namespaces=ns)
133132
if site_xml is not None:
134133
(_, name, content_url, _, admin_mode, state,
135134
subscribe_others_enabled, disable_subscriptions, revision_history_enabled,
136-
user_quota, storage_quota, revision_limit, num_users, storage) = self._parse_element(site_xml)
135+
user_quota, storage_quota, revision_limit, num_users, storage) = self._parse_element(site_xml, ns)
137136

138137
self._set_values(None, name, content_url, None, admin_mode, state, subscribe_others_enabled,
139138
disable_subscriptions, revision_history_enabled, user_quota, storage_quota,
@@ -173,14 +172,14 @@ def _set_values(self, id, name, content_url, status_reason, admin_mode, state,
173172
self._storage = storage
174173

175174
@classmethod
176-
def from_response(cls, resp):
175+
def from_response(cls, resp, ns):
177176
all_site_items = list()
178177
parsed_response = ET.fromstring(resp)
179-
all_site_xml = parsed_response.findall('.//t:site', namespaces=NAMESPACE)
178+
all_site_xml = parsed_response.findall('.//t:site', namespaces=ns)
180179
for site_xml in all_site_xml:
181180
(id, name, content_url, status_reason, admin_mode, state, subscribe_others_enabled,
182181
disable_subscriptions, revision_history_enabled, user_quota, storage_quota,
183-
revision_limit, num_users, storage) = cls._parse_element(site_xml)
182+
revision_limit, num_users, storage) = cls._parse_element(site_xml, ns)
184183

185184
site_item = cls(name, content_url)
186185
site_item._set_values(id, name, content_url, status_reason, admin_mode, state,
@@ -190,7 +189,7 @@ def from_response(cls, resp):
190189
return all_site_items
191190

192191
@staticmethod
193-
def _parse_element(site_xml):
192+
def _parse_element(site_xml, ns):
194193
id = site_xml.get('id', None)
195194
name = site_xml.get('name', None)
196195
content_url = site_xml.get('contentUrl', None)
@@ -215,7 +214,7 @@ def _parse_element(site_xml):
215214

216215
num_users = None
217216
storage = None
218-
usage_elem = site_xml.find('.//t:usage', namespaces=NAMESPACE)
217+
usage_elem = site_xml.find('.//t:usage', namespaces=ns)
219218
if usage_elem is not None:
220219
num_users = usage_elem.get('numUsers', None)
221220
storage = usage_elem.get('storage', None)

0 commit comments

Comments
 (0)
0