Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions tableauserverapi/models/datasource_item.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import xml.etree.ElementTree as ET
from exceptions import UnpopulatedPropertyError
from tag_item import TagItem
from .exceptions import UnpopulatedPropertyError
from .tag_item import TagItem
from .. import NAMESPACE


Expand Down
2 changes: 1 addition & 1 deletion tableauserverapi/models/group_item.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import xml.etree.ElementTree as ET
from exceptions import UnpopulatedPropertyError
from .exceptions import UnpopulatedPropertyError
from .. import NAMESPACE


Expand Down
2 changes: 1 addition & 1 deletion tableauserverapi/models/user_item.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import xml.etree.ElementTree as ET
from exceptions import UnpopulatedPropertyError
from .exceptions import UnpopulatedPropertyError
from .. import NAMESPACE


Expand Down
6 changes: 3 additions & 3 deletions tableauserverapi/models/workbook_item.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import xml.etree.ElementTree as ET
from exceptions import UnpopulatedPropertyError
from tag_item import TagItem
from view_item import ViewItem
from .exceptions import UnpopulatedPropertyError
from .tag_item import TagItem
from .view_item import ViewItem
from .. import NAMESPACE
import copy

Expand Down
2 changes: 1 addition & 1 deletion tableauserverapi/server/endpoint/auth_endpoint.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from endpoint import Endpoint
from .endpoint import Endpoint
from .. import RequestFactory, NAMESPACE
import xml.etree.ElementTree as ET
import logging
Expand Down
4 changes: 2 additions & 2 deletions tableauserverapi/server/endpoint/datasources_endpoint.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from endpoint import Endpoint
from exceptions import MissingRequiredFieldError
from .endpoint import Endpoint
from .exceptions import MissingRequiredFieldError
from .fileuploads_endpoint import Fileuploads
from .. import RequestFactory, DatasourceItem, PaginationItem, ConnectionItem
import os
Expand Down
2 changes: 1 addition & 1 deletion tableauserverapi/server/endpoint/endpoint.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from exceptions import ServerResponseError
from .exceptions import ServerResponseError
import logging

logger = logging.getLogger('tableau.endpoint')
Expand Down
4 changes: 2 additions & 2 deletions tableauserverapi/server/endpoint/fileuploads_endpoint.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from endpoint import Endpoint
from exceptions import MissingRequiredFieldError
from .exceptions import MissingRequiredFieldError
from .endpoint import Endpoint
from .. import RequestFactory
from ...models.fileupload_item import FileuploadItem
import os.path
Expand Down
4 changes: 2 additions & 2 deletions tableauserverapi/server/endpoint/groups_endpoint.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from endpoint import Endpoint
from exceptions import MissingRequiredFieldError
from .endpoint import Endpoint
from .exceptions import MissingRequiredFieldError
from .. import RequestFactory, GroupItem, UserItem, PaginationItem
import logging

Expand Down
4 changes: 2 additions & 2 deletions tableauserverapi/server/endpoint/projects_endpoint.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from endpoint import Endpoint
from exceptions import MissingRequiredFieldError
from .endpoint import Endpoint
from .exceptions import MissingRequiredFieldError
from .. import RequestFactory, ProjectItem, PaginationItem
import logging
import copy
Expand Down
4 changes: 2 additions & 2 deletions tableauserverapi/server/endpoint/sites_endpoint.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from endpoint import Endpoint
from exceptions import MissingRequiredFieldError
from .endpoint import Endpoint
from .exceptions import MissingRequiredFieldError
from .. import RequestFactory, SiteItem, PaginationItem
import logging
import copy
Expand Down
8 changes: 4 additions & 4 deletions tableauserverapi/server/endpoint/users_endpoint.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from endpoint import Endpoint
from exceptions import MissingRequiredFieldError
from .endpoint import Endpoint
from .exceptions import MissingRequiredFieldError
from .. import RequestFactory, UserItem, WorkbookItem, PaginationItem
import logging
import copy
Expand Down Expand Up @@ -33,7 +33,7 @@ def get_by_id(self, user_id):
logger.info('Querying single user (ID: {0})'.format(user_id))
url = "{0}/{1}".format(self._construct_url(), user_id)
server_response = self.get_request(url)
return UserItem.from_response(server_response.text)[0]
return UserItem.from_response(server_response.text).pop()

# Update user
def update(self, user_item):
Expand Down Expand Up @@ -62,7 +62,7 @@ def add(self, user_item):
url = self._construct_url()
add_req = RequestFactory.User.add_req(user_item)
server_response = self.post_request(url, add_req)
new_user = UserItem.from_response(server_response.text)[0]
new_user = UserItem.from_response(server_response.text).pop()
logger.info('Added new user (ID: {0})'.format(user_item.id))
return new_user

Expand Down
4 changes: 2 additions & 2 deletions tableauserverapi/server/endpoint/views_endpoint.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from endpoint import Endpoint
from exceptions import MissingRequiredFieldError
from .endpoint import Endpoint
from .exceptions import MissingRequiredFieldError
from .. import ViewItem, PaginationItem
import logging

Expand Down
4 changes: 2 additions & 2 deletions tableauserverapi/server/endpoint/workbooks_endpoint.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from endpoint import Endpoint
from exceptions import MissingRequiredFieldError
from .endpoint import Endpoint
from .exceptions import MissingRequiredFieldError
from .fileuploads_endpoint import Fileuploads
from .. import RequestFactory, WorkbookItem, ConnectionItem, ViewItem, PaginationItem
from ...models.tag_item import TagItem
Expand Down
2 changes: 1 addition & 1 deletion tableauserverapi/server/filter.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from request_options import RequestOptions
from .request_options import RequestOptions


class Filter(object):
Expand Down
4 changes: 2 additions & 2 deletions tableauserverapi/server/server.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from exceptions import NotSignedInError
from endpoint import Sites, Views, Users, Groups, Workbooks, Datasources, Projects, Auth
from .exceptions import NotSignedInError
from .endpoint import Sites, Views, Users, Groups, Workbooks, Datasources, Projects, Auth
import requests


Expand Down
Empty file added test/__init__.py
Empty file.
93 changes: 93 additions & 0 deletions test/assets/SampleDS.tds
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<?xml version='1.0' encoding='utf-8' ?>
<datasource formatted-name='postgres.1of3kl00aoax5d1a1ejma1397430' inline='true' source-platform='mac' version='9.3' xmlns:user='http://www.tableausoftware.com/xml/user'>
<connection authentication='username-password' class='postgres' dbname='TestV1' odbc-native-protocol='yes' port='5432' server='postgres91.test.tsi.lan' username='test'>
<relation name='xy' table='[public].[xy]' type='table' />
<metadata-records>
<metadata-record class='column'>
<remote-name>a</remote-name>
<remote-type>130</remote-type>
<local-name>[a]</local-name>
<parent-name>[xy]</parent-name>
<remote-alias>a</remote-alias>
<ordinal>1</ordinal>
<local-type>string</local-type>
<aggregation>Count</aggregation>
<width>255</width>
<contains-null>true</contains-null>
<attributes>
<attribute datatype='string' name='DebugRemoteType'>&quot;SQL_WVARCHAR&quot;</attribute>
<attribute datatype='string' name='DebugWireType'>&quot;SQL_C_WCHAR&quot;</attribute>
<attribute datatype='string' name='TypeIsVarchar'>&quot;true&quot;</attribute>
</attributes>
</metadata-record>
<metadata-record class='column'>
<remote-name>Today's Date</remote-name>
<remote-type>130</remote-type>
<local-name>[Today&apos;s Date]</local-name>
<parent-name>[xy]</parent-name>
<remote-alias>a</remote-alias>
<ordinal>1</ordinal>
<local-type>string</local-type>
<aggregation>Count</aggregation>
<width>255</width>
<contains-null>true</contains-null>
<attributes>
<attribute datatype='string' name='DebugRemoteType'>&quot;SQL_WVARCHAR&quot;</attribute>
<attribute datatype='string' name='DebugWireType'>&quot;SQL_C_WCHAR&quot;</attribute>
<attribute datatype='string' name='TypeIsVarchar'>&quot;true&quot;</attribute>
</attributes>
</metadata-record>
<metadata-record class='column'>
<remote-name>x</remote-name>
<remote-type>3</remote-type>
<local-name>[x]</local-name>
<parent-name>[xy]</parent-name>
<remote-alias>x</remote-alias>
<ordinal>2</ordinal>
<local-type>integer</local-type>
<aggregation>Sum</aggregation>
<precision>10</precision>
<contains-null>true</contains-null>
<attributes>
<attribute datatype='string' name='DebugRemoteType'>&quot;SQL_INTEGER&quot;</attribute>
<attribute datatype='string' name='DebugWireType'>&quot;SQL_C_SLONG&quot;</attribute>
</attributes>
</metadata-record>
<metadata-record class='column'>
<remote-name>y</remote-name>
<remote-type>3</remote-type>
<local-name>[y]</local-name>
<parent-name>[xy]</parent-name>
<remote-alias>y</remote-alias>
<ordinal>3</ordinal>
<local-type>integer</local-type>
<aggregation>Sum</aggregation>
<precision>10</precision>
<contains-null>true</contains-null>
<attributes>
<attribute datatype='string' name='DebugRemoteType'>&quot;SQL_INTEGER&quot;</attribute>
<attribute datatype='string' name='DebugWireType'>&quot;SQL_C_SLONG&quot;</attribute>
</attributes>
</metadata-record>
</metadata-records>
</connection>
<aliases enabled='yes' />
<column datatype='integer' name='[Number of Records]' role='measure' type='quantitative' user:auto-column='numrec'>
<calculation class='tableau' formula='1' />
</column>
<column caption='A' datatype='string' name='[a]' role='dimension' type='nominal'>
<desc>
<formatted-text>
<run bold='true' fontsize='96'>A thing</run>
<run fontcolor='#686868'>&#10;Something will go here too, in a muted gray</run>
</formatted-text>
</desc>
</column>
<column caption='Today&apos;s Date' datatype='string' name='[Today&apos;s Date]' role='dimension' type='nominal' />
<column caption='X' datatype='integer' name='[x]' role='measure' type='ordinal' />
<column caption='Y' datatype='integer' name='[y]' role='measure' type='quantitative' />
<layout dim-ordering='alphabetic' dim-percentage='0.5' measure-ordering='alphabetic' measure-percentage='0.5' show-structure='true' />
<semantic-values>
<semantic-value key='[Country].[Name]' value='&quot;United States&quot;' />
</semantic-values>
</datasource>
Binary file added test/assets/SampleWB.twbx
Binary file not shown.
10 changes: 5 additions & 5 deletions test/test_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def setUp(self):

def test_sign_in(self):
with open(SIGN_IN_XML, 'rb') as f:
response_xml = f.read()
response_xml = f.read().decode('utf-8')
with requests_mock.mock() as m:
m.post(self.baseurl + '/signin', text=response_xml)
tableau_auth = TSA.TableauAuth('testuser', 'password', site='Samples')
Expand All @@ -29,7 +29,7 @@ def test_sign_in(self):

def test_sign_in_impersonate(self):
with open(SIGN_IN_IMPERSONATE_XML, 'rb') as f:
response_xml = f.read()
response_xml = f.read().decode('utf-8')
with requests_mock.mock() as m:
m.post(self.baseurl + '/signin', text=response_xml)
tableau_auth = TSA.TableauAuth('testuser', 'password',
Expand All @@ -42,23 +42,23 @@ def test_sign_in_impersonate(self):

def test_sign_in_error(self):
with open(SIGN_IN_ERROR_XML, 'rb') as f:
response_xml = f.read()
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 = TSA.TableauAuth('testuser', 'wrongpassword')
self.assertRaises(TSA.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()
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 = TSA.TableauAuth('', '')
self.assertRaises(TSA.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()
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='')
Expand Down
19 changes: 10 additions & 9 deletions test/test_datasource.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def setUp(self):

def test_get(self):
with open(GET_XML, 'rb') as f:
response_xml = f.read()
response_xml = f.read().decode('utf-8')
with requests_mock.mock() as m:
m.get(self.baseurl, text=response_xml)
pagination_item, all_datasources = self.server.datasources.get()
Expand Down Expand Up @@ -57,7 +57,7 @@ def test_get_before_signin(self):

def test_get_empty(self):
with open(GET_EMPTY_XML, 'rb') as f:
response_xml = f.read()
response_xml = f.read().decode('utf-8')
with requests_mock.mock() as m:
m.get(self.baseurl, text=response_xml)
pagination_item, all_datasources = self.server.datasources.get()
Expand All @@ -67,7 +67,7 @@ def test_get_empty(self):

def test_get_by_id(self):
with open(GET_BY_ID_XML, 'rb') as f:
response_xml = f.read()
response_xml = f.read().decode('utf-8')
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')
Expand All @@ -85,7 +85,7 @@ def test_get_by_id(self):

def test_update(self):
with open(UPDATE_XML, 'rb') as f:
response_xml = f.read()
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 = TSA.DatasourceItem('test', '1d0304cd-3796-429f-b815-7258370b9b74')
Expand All @@ -99,7 +99,7 @@ def test_update(self):

def test_update_copy_fields(self):
with open(UPDATE_XML, 'rb') as f:
response_xml = f.read()
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 = TSA.DatasourceItem('test', '1d0304cd-3796-429f-b815-7258370b9b74')
Expand All @@ -113,11 +113,12 @@ def test_update_copy_fields(self):

def test_publish(self):
with open(PUBLISH_XML, 'rb') as f:
response_xml = f.read()
response_xml = f.read().decode('utf-8')
with requests_mock.mock() as m:
m.post(self.baseurl, text=response_xml)
new_datasource = TSA.DatasourceItem('SampleDS', 'ee8c6e70-43b6-11e6-af4f-f7b0d8e20760')
new_datasource = self.server.datasources.publish(new_datasource, '../samples/SampleDS.tds',
new_datasource = self.server.datasources.publish(new_datasource,
os.path.join(TEST_ASSET_DIR, 'SampleDS.tds'),
mode=self.server.PublishMode.CreateNew)

self.assertEqual('e76a1461-3b1d-4588-bf1b-17551a879ad9', new_datasource.id)
Expand Down Expand Up @@ -155,9 +156,9 @@ def test_publish_missing_path(self):
def test_publish_missing_mode(self):
new_datasource = TSA.DatasourceItem('test', 'ee8c6e70-43b6-11e6-af4f-f7b0d8e20760')
self.assertRaises(ValueError, self.server.datasources.publish, new_datasource,
'../samples/SampleDS.tds', None)
os.path.join(TEST_ASSET_DIR, 'SampleDS.tds'), None)

def test_publish_invalid_file_type(self):
new_datasource = TSA.DatasourceItem('test', 'ee8c6e70-43b6-11e6-af4f-f7b0d8e20760')
self.assertRaises(ValueError, self.server.datasources.publish, new_datasource,
'../samples/SampleWB.twbx', self.server.PublishMode.Append)
os.path.join(TEST_ASSET_DIR, 'SampleWB.twbx'), self.server.PublishMode.Append)
Loading