Skip to content

Commit ce37a20

Browse files
author
Chris Shin
authored
Merge pull request #801 from tableau/release-0.15
[Release] Sync master with v0.15 changes ## 0.15.0 (16 Feb 2021) * Added support for python version 3.9 (#744) * Added support for 'Get View by ID' (#750) * Added docs and test data to MANIFEST.in file (#780) * Added owner_id property to ProjectItem (#784) * Added support for skipping connection check while publishing workbook (#791) * Added support for 'Update Subscription' (#794) * Added support for 'Get Groups for a User' (#799) * Improved debug logging by including put/post request contents (#743) * Improved local and active-directory group creation (#770) * Improved 'Update Group' to match server requests/responses (#772) * Improved SiteItem with new properties and functions (#777) * Improved SubscriptionItem with new properties (#794) * Improved the 'type' property of TaskItem to convert server response to enum (#796) * Improved repository to use Github Actions for running tests/linter (#798) * Fixed data_acceleration field causing error in workbook update payload (#741)
2 parents a5b9252 + 3a8ec6c commit ce37a20

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+1272
-124
lines changed

.github/workflows/run-tests.yml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
name: Python package
2+
3+
on: [push]
4+
5+
jobs:
6+
build:
7+
8+
runs-on: ubuntu-latest
9+
strategy:
10+
fail-fast: false
11+
matrix:
12+
python-version: [3.5, 3.6, 3.7, 3.8, 3.9]
13+
14+
steps:
15+
- uses: actions/checkout@v2
16+
17+
- name: Set up Python ${{ matrix.python-version }}
18+
uses: actions/setup-python@v2
19+
with:
20+
python-version: ${{ matrix.python-version }}
21+
22+
- name: Install dependencies
23+
run: |
24+
python -m pip install --upgrade pip
25+
pip install -e .[test]
26+
27+
- name: Lint with pycodestyle
28+
run: |
29+
pycodestyle tableauserverclient test samples
30+
31+
- name: Test with pytest
32+
run: |
33+
pytest test

.travis.yml

Lines changed: 0 additions & 16 deletions
This file was deleted.

CHANGELOG.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,20 @@
1+
## 0.15.0 (16 Feb 2021)
2+
* Added support for python version 3.9 (#744)
3+
* Added support for 'Get View by ID' (#750)
4+
* Added docs and test data to MANIFEST.in file (#780)
5+
* Added owner_id property to ProjectItem (#784)
6+
* Added support for skipping connection check while publishing workbook (#791)
7+
* Added support for 'Update Subscription' (#794)
8+
* Added support for 'Get Groups for a User' (#799)
9+
* Improved debug logging by including put/post request contents (#743)
10+
* Improved local and active-directory group creation (#770)
11+
* Improved 'Update Group' to match server requests/responses (#772)
12+
* Improved SiteItem with new properties and functions (#777)
13+
* Improved SubscriptionItem with new properties (#794)
14+
* Improved the 'type' property of TaskItem to convert server response to enum (#796)
15+
* Improved repository to use Github Actions for running tests/linter (#798)
16+
* Fixed data_acceleration field causing error in workbook update payload (#741)
17+
118
## 0.14.1 (9 Dec 2020)
219
* Fixed filter query issue for server version below 2020.1 (#745)
320
* Fixed large workbook/datasource publish issue (#757)

CONTRIBUTORS.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ The following people have contributed to this project to make it possible, and w
4141
* [Paul Vickers](https://github.com/paulvic)
4242
* [Madhura Selvarajan](https://github.com/maddy-at-leisure)
4343
* [Niklas Nevalainen](https://github.com/nnevalainen)
44+
* [Terrence Jones](https://github.com/tjones-commits)
45+
* [John Vandenberg](https://github.com/jayvdb)
46+
* [Lee Boynton](https://github.com/lboynton)
4447

4548
## Core Team
4649

MANIFEST.in

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,22 @@ include versioneer.py
22
include tableauserverclient/_version.py
33
include LICENSE
44
include LICENSE.versioneer
5+
include README.md
6+
include CHANGELOG.md
7+
recursive-include docs *.md
8+
recursive-include samples *.py
9+
recursive-include samples *.txt
10+
recursive-include smoke *.py
11+
recursive-include test *.csv
12+
recursive-include test *.dict
13+
recursive-include test *.hyper
14+
recursive-include test *.json
15+
recursive-include test *.pdf
16+
recursive-include test *.png
17+
recursive-include test *.py
18+
recursive-include test *.tde
19+
recursive-include test *.tds
20+
recursive-include test *.tdsx
21+
recursive-include test *.twb
22+
recursive-include test *.twbx
23+
recursive-include test *.xml

samples/publish_workbook.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ def main():
3131
parser.add_argument('--logging-level', '-l', choices=['debug', 'info', 'error'], default='error',
3232
help='desired logging level (set to error by default)')
3333
parser.add_argument('--as-job', '-a', help='Publishing asynchronously', action='store_true')
34+
parser.add_argument('--skip-connection-check', '-c', help='Skip live connection check', action='store_true')
3435
parser.add_argument('--site', '-S', default='', help='id (contentUrl) of site to sign into')
3536

3637
args = parser.parse_args()
@@ -71,11 +72,13 @@ def main():
7172
new_workbook = TSC.WorkbookItem(default_project.id)
7273
if args.as_job:
7374
new_job = server.workbooks.publish(new_workbook, args.filepath, overwrite_true,
74-
connections=all_connections, as_job=args.as_job)
75+
connections=all_connections, as_job=args.as_job,
76+
skip_connection_check=args.skip_connection_check)
7577
print("Workbook published. JOB ID: {0}".format(new_job.id))
7678
else:
7779
new_workbook = server.workbooks.publish(new_workbook, args.filepath, overwrite_true,
78-
connections=all_connections, as_job=args.as_job)
80+
connections=all_connections, as_job=args.as_job,
81+
skip_connection_check=args.skip_connection_check)
7982
print("Workbook published. ID: {0}".format(new_workbook.id))
8083
else:
8184
error = "The default project could not be found."

setup.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
# This makes work easier for offline installs or low bandwidth machines
1616
needs_pytest = {'pytest', 'test', 'ptr'}.intersection(sys.argv)
1717
pytest_runner = ['pytest-runner'] if needs_pytest else []
18+
test_requirements = ['mock', 'pycodestyle', 'pytest', 'requests-mock>=1.0,<2.0']
1819

1920
setup(
2021
name='tableauserverclient',
@@ -34,9 +35,8 @@
3435
install_requires=[
3536
'requests>=2.11,<3.0',
3637
],
37-
tests_require=[
38-
'requests-mock>=1.0,<2.0',
39-
'pytest',
40-
'mock'
41-
]
38+
tests_require=test_requirements,
39+
extras_require={
40+
'test': test_requirements
41+
}
4242
)

tableauserverclient/models/group_item.py

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,17 @@ class GroupItem(object):
99

1010
tag_name = 'group'
1111

12-
def __init__(self, name=None):
13-
self._domain_name = None
12+
class LicenseMode:
13+
onLogin = 'onLogin'
14+
onSync = 'onSync'
15+
16+
def __init__(self, name=None, domain_name=None):
1417
self._id = None
15-
self._users = None
16-
self.name = name
1718
self._license_mode = None
1819
self._minimum_site_role = None
20+
self._users = None
21+
self.name = name
22+
self.domain_name = domain_name
1923

2024
@property
2125
def domain_name(self):
@@ -43,8 +47,8 @@ def license_mode(self):
4347
return self._license_mode
4448

4549
@license_mode.setter
50+
@property_is_enum(LicenseMode)
4651
def license_mode(self, value):
47-
# valid values = onSync, onLogin
4852
self._license_mode = value
4953

5054
@property
@@ -79,17 +83,18 @@ def from_response(cls, resp, ns):
7983
name = group_xml.get('name', None)
8084
group_item = cls(name)
8185
group_item._id = group_xml.get('id', None)
82-
# AD groups have an extra element under this
86+
87+
# Domain name is returned in a domain element for some calls
88+
domain_elem = group_xml.find('.//t:domain', namespaces=ns)
89+
if domain_elem is not None:
90+
group_item.domain_name = domain_elem.get('name', None)
91+
92+
# Import element is returned for both local and AD groups (2020.3+)
8393
import_elem = group_xml.find('.//t:import', namespaces=ns)
84-
if (import_elem is not None):
85-
group_item.domain_name = import_elem.get('domainName')
86-
group_item.license_mode = import_elem.get('grantLicenseMode')
87-
group_item.minimum_site_role = import_elem.get('siteRole')
88-
else:
89-
# local group, we will just have two extra attributes here
90-
group_item.domain_name = 'local'
91-
group_item.license_mode = group_xml.get('grantLicenseMode')
92-
group_item.minimum_site_role = group_xml.get('siteRole')
94+
if import_elem is not None:
95+
group_item.domain_name = import_elem.get('domainName', None)
96+
group_item.license_mode = import_elem.get('grantLicenseMode', None)
97+
group_item.minimum_site_role = import_elem.get('siteRole', None)
9398

9499
all_group_items.append(group_item)
95100
return all_group_items

tableauserverclient/models/project_item.py

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,14 @@ def name(self):
7474
def name(self, value):
7575
self._name = value
7676

77+
@property
78+
def owner_id(self):
79+
return self._owner_id
80+
81+
@owner_id.setter
82+
def owner_id(self, value):
83+
raise NotImplementedError('REST API does not currently support updating project owner.')
84+
7785
def is_default(self):
7886
return self.name.lower() == 'default'
7987

@@ -86,7 +94,7 @@ def _parse_common_tags(self, project_xml, ns):
8694
self._set_values(None, name, description, content_permissions, parent_id)
8795
return self
8896

89-
def _set_values(self, project_id, name, description, content_permissions, parent_id):
97+
def _set_values(self, project_id, name, description, content_permissions, parent_id, owner_id):
9098
if project_id is not None:
9199
self._id = project_id
92100
if name:
@@ -97,6 +105,8 @@ def _set_values(self, project_id, name, description, content_permissions, parent
97105
self._content_permissions = content_permissions
98106
if parent_id:
99107
self.parent_id = parent_id
108+
if owner_id:
109+
self._owner_id = owner_id
100110

101111
def _set_permissions(self, permissions):
102112
self._permissions = permissions
@@ -111,9 +121,9 @@ def from_response(cls, resp, ns):
111121
all_project_xml = parsed_response.findall('.//t:project', namespaces=ns)
112122

113123
for project_xml in all_project_xml:
114-
(id, name, description, content_permissions, parent_id) = cls._parse_element(project_xml)
124+
(id, name, description, content_permissions, parent_id, owner_id) = cls._parse_element(project_xml)
115125
project_item = cls(name)
116-
project_item._set_values(id, name, description, content_permissions, parent_id)
126+
project_item._set_values(id, name, description, content_permissions, parent_id, owner_id)
117127
all_project_items.append(project_item)
118128
return all_project_items
119129

@@ -124,5 +134,8 @@ def _parse_element(project_xml):
124134
description = project_xml.get('description', None)
125135
content_permissions = project_xml.get('contentPermissions', None)
126136
parent_id = project_xml.get('parentProjectId', None)
137+
owner_id = None
138+
for owner in project_xml:
139+
owner_id = owner.get('id', None)
127140

128-
return id, name, description, content_permissions, parent_id
141+
return id, name, description, content_permissions, parent_id, owner_id

0 commit comments

Comments
 (0)