8000 Add connection credentials (#80) · jgchavez-cl/server-client-python@7c41a0a · GitHub
[go: up one dir, main page]

Skip to content

Commit 7c41a0a

Browse files
geordieladRussell Hay
authored andcommitted
Add connection credentials (tableau#80)
1 parent 2f041d1 commit 7c41a0a

File tree

6 files changed

+56
-17
lines changed

6 files changed

+56
-17
lines changed

tableauserverclient/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from .namespace import NAMESPACE
2-
from .models import ConnectionItem, DatasourceItem,\
2+
from .models import ConnectionCredentials, ConnectionItem, DatasourceItem,\
33
GroupItem, PaginationItem, ProjectItem, ScheduleItem, \
44
SiteItem, TableauAuth, UserItem, ViewItem, WorkbookItem, UnpopulatedPropertyError, \
55
HourlyInterval, DailyInterval, WeeklyInterval, MonthlyInterval, IntervalItem

tableauserverclient/models/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from .connection_credentials import ConnectionCredentials
12
from .connection_item import ConnectionItem
23
from .datasource_item import DatasourceItem
34
from .exceptions import UnpopulatedPropertyError
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
from .property_decorators import property_is_boolean
2+
3+
4+
class ConnectionCredentials(object):
5+
"""Connection Credentials for Workbooks and Datasources publish request.
6+
7+
Consider removing this object and other variables holding secrets
8+
as soon as possible after use to avoid them hanging around in memory.
9+
10+
"""
11+
12+
def __init__(self, name, password, embed=True):
13+
self.name = name
14+
self.password = password
15+
self.embed = embed
16+
17+
@property
18+
def embed(self):
19+
return self._embed
20+
21+
@embed.setter
22+
@property_is_boolean
23+
def embed(self, value):
24+
self._embed = value

tableauserverclient/server/endpoint/datasources_endpoint.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ def update(self, datasource_item):
9494
return updated_datasource._parse_common_tags(server_response.content)
9595

9696
# Publish datasource
97-
def publish(self, datasource_item, file_path, mode):
97+
def publish(self, datasource_item, file_path, mode, connection_credentials=None):
9898
if not os.path.isfile(file_path):
9999
error = "File path does not lead to an existing file."
100100
raise IOError(error)
@@ -122,14 +122,16 @@ def publish(self, datasource_item, file_path, mode):
122122
logger.info('Publishing {0} to server with chunking method (datasource over 64MB)'.format(filename))
123123
upload_session_id = Fileuploads.upload_chunks(self.parent_srv, file_path)
124124
url = "{0}&uploadSessionId={1}".format(url, upload_session_id)
125-
xml_request, content_type = RequestFactory.Datasource.publish_req_chunked(datasource_item)
125+
xml_request, content_type = RequestFactory.Datasource.publish_req_chunked(datasource_item,
126+
connection_credentials)
126127
else:
127128
logger.info('Publishing {0} to server'.format(filename))
128129
with open(file_path, 'rb') as f:
129130
file_contents = f.read()
130131
xml_request, content_type = RequestFactory.Datasource.publish_req(datasource_item,
131132
filename,
132-
file_contents)
133+
file_contents,
134+
connection_credentials)
133135
server_response = self.post_request(url, xml_request, content_type)
134136
new_datasource = DatasourceItem.from_response(server_response.content)[0]
135137
logger.info('Published {0} (ID: {1})'.format(filename, new_datasource.id))

tableauserverclient/server/endpoint/workbooks_endpoint.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ def populate_preview_image(self, workbook_item):
140140
logger.info('Populated preview image for workbook (ID: {0})'.format(workbook_item.id))
141141

142142
# Publishes workbook. Chunking method if file over 64MB
143-
def publish(self, workbook_item, file_path, mode):
143+
def publish(self, workbook_item, file_path, mode, connection_credentials=None):
144144
if not os.path.isfile(file_path):
145145
error = "File path does not lead to an existing file."
146146
raise IOError(error)
@@ -171,14 +171,16 @@ def publish(self, workbook_item, file_path, mode):
171171
logger.info('Publishing {0} to server with chunking method (workbook over 64MB)'.format(filename))
172172
upload_session_id = Fileuploads.upload_chunks(self.parent_srv, file_path)
173173
url = "{0}&uploadSessionId={1}".format(url, upload_session_id)
174-
xml_request, content_type = RequestFactory.Workbook.publish_req_chunked(workbook_item)
174+
xml_request, content_type = RequestFactory.Workbook.publish_req_chunked(workbook_item,
175+
connection_credentials)
175176
else:
176177
logger.info('Publishing {0} to server'.format(filename))
177178
with open(file_path, 'rb') as f:
178179
file_contents = f.read()
179180
xml_request, content_type = RequestFactory.Workbook.publish_req(workbook_item,
180181
filename,
181-
file_contents)
182+
file_contents,
183+
connection_credentials)
182184
server_response = self.post_request(url, xml_request, content_type)
183185
new_workbook = WorkbookItem.from_response(server_response.content)[0]
184186
logger.info('Published {0} (ID: {1})'.format(filename, new_workbook.id))

tableauserverclient/server/request_factory.py

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,17 @@ def signin_req(self, auth_item):
3030

3131

3232
class DatasourceRequest(object):
33-
def _generate_xml(self, datasource_item):
33+
def _generate_xml(self, datasource_item, connection_credentials=None):
3434
xml_request = ET.Element('tsRequest')
3535
datasource_element = ET.SubElement(xml_request, 'datasource')
3636
datasource_element.attrib['name'] = datasource_item.name
3737
project_element = ET.SubElement(datasource_element, 'project')
3838
project_element.attrib['id'] = datasource_item.project_id
39+
if connection_credentials:
40+
credentials_element = ET.SubElement(datasource_element, 'connectionCredentials')
41+
credentials_element.attrib['name'] = connection_credentials.name
42+
credentials_element.attrib['password'] = connection_credentials.password
43+
credentials_element.attrib['embed'] = 'true' if connection_credentials.embed else 'false'
3944
return ET.tostring(xml_request)
4045

4146
def update_req(self, datasource_item):
@@ -49,15 +54,15 @@ def update_req(self, datasource_item):
4954
owner_element.attrib['id'] = datasource_item.owner_id
5055
return ET.tostring(xml_request)
5156

52-
def publish_req(self, datasource_item, filename, file_contents):
53-
xml_request = self._generate_xml(datasource_item)
57+
def publish_req(self, datasource_item, filename, file_contents, connection_credentials=None):
58+
xml_request = self._generate_xml(datasource_item, connection_credentials)
5459

5560
parts = {'request_payload': ('', xml_request, 'text/xml'),
5661
'tableau_datasource': (filename, file_contents, 'application/octet-stream')}
5762
return _add_multipart(parts)
5863

59-
def publish_req_chunked(self, datasource_item):
60-
xml_request = self._generate_xml(datasource_item)
64+
def publish_req_chunked(self, datasource_item, connection_credentials=None):
65+
xml_request = self._generate_xml(datasource_item, connection_credentials)
6166

6267
parts = {'request_payload': ('', xml_request, 'text/xml')}
6368
return _add_multipart(parts)
@@ -260,14 +265,19 @@ def add_req(self, user_item):
260265

261266

262267
class WorkbookRequest(object):
263-
def _generate_xml(self, workbook_item):
268+
def _generate_xml(self, workbook_item, connection_credentials=None):
264269
xml_request = ET.Element('tsRequest')
265270
workbook_element = ET.SubElement(xml_request, 'workbook')
266271
workbook_element.attrib['name'] = workbook_item.name
267272
if workbook_item.show_tabs:
268273
workbook_element.attrib['showTabs'] = str(workbook_item.show_tabs).lower()
269274
project_element = ET.SubElement(workbook_element, 'project')
270275
project_element.attrib['id'] = workbook_item.project_id
276+
if connection_credentials:
277+
credentials_element = ET.SubElement(workbook_element, 'connectionCredentials')
278+
credentials_element.attrib['name'] = connection_credentials.name
279+
credentials_element.attrib['password'] = connection_credentials.password
280+
credentials_element.attrib['embed'] = 'true' if connection_credentials.embed else 'false'
271281
return ET.tostring(xml_request)
272282

273283
def update_req(self, workbook_item):
@@ -283,15 +293,15 @@ def update_req(self, workbook_item):
283293
owner_element.attrib['id'] = workbook_item.owner_id
284294
return ET.tostring(xml_request)
285295

286-
def publish_req(self, workbook_item, filename, file_contents):
287-
xml_request = self._generate_xml(workbook_item)
296+
def publish_req(self, workbook_item, filename, file_contents, connection_credentials=None):
297+
xml_request = self._generate_xml(workbook_item, connection_credentials)
288298

289299
parts = {'request_payload': ('', xml_request, 'text/xml'),
290300
'tableau_workbook': (filename, file_contents, 'application/octet-stream')}
291301
return _add_multipart(parts)
292302

293-
def publish_req_chunked(self, workbook_item):
294-
xml_request = self._generate_xml(workbook_item)
303+
def publish_req_chunked(self, workbook_item, connection_credentials=None):
304+
xml_request = self._generate_xml(workbook_item, connection_credentials)
295305

296306
parts = {'request_payload': ('', xml_request, 'text/xml')}
297307
return _add_multipart(parts)

0 commit comments

Comments
 (0)
0