8000 prepare release 0.20 (#1107) · trungluu1/server-client-python@3c021c0 · GitHub
[go: up one dir, main page]

Skip to content

Commit 3c021c0

Browse files
jacalataAmar Yadavscumljorwoodsbcantoni
authored
prepare release 0.20 (tableau#1107)
* Datasources: Use explicit None identity check for datasource updates (tableau#1099) (Resolves tableau#1062 - cannot set empty password) * Projects: add publish-samples option to create/update project * Workbooks: fix workbook.delete_extract, add workbook pdf download, make project_id nullable to support "Personal Space", Remove vf support from populate_excel, make hidden views an attribute of Workbooks and deprecate hidden_views flag in publish request * Schedules: add get_by_id method * Users: Reassign content on user removal, add user import logic * Jobs: Add Status, ParentProjectId and StartedAt filters, Extract refreshable item IDs from job XML response * Sites: Add version awareness to site create/update methods: Update sites requests for Breaking change in 3.10: flowsEnabled removed, flowsEditingEnabled and flowsSchedulingEnabled added ,Allow setting site user_quota to None if tiered licenses exist * Do not eagerly fetch content when a stream was requested * create single Credentials class (tableau#1032), Included redacted print methods for each credential type * on init set use_server_version = False so that we don't try and contact the server before people finish setting certs * add client version/debug header * Logging: log RequestOptions params (tableau#1070), add redaction method to remove passwords when logging requests and responses, which can contain embedded credentials, log the url of the request that got an error in the response. * fix filter for python 3, remove support for python 3.6 (add python version enforcement in setup.py) * Fix slicing logic, add tests for queryset slicing crossing a page, add support for len magic method to queryset * Add type hints for workbook and data source revisions, data alerts, Favorites, Flows, groups, permissions, projects, sites, subscriptions, Users, webhooks * Samples: fix export sample, delete redundant samples (export_wb, download_view_image), add user import sample, default permissions sample * add publish to pypi actio, enable Black for CI, consolidate config files into pyproject.toml co-authored-by: Amar Yadav <AmarKumar.Yadav@genmills.com> Co-authored-by: Jac <jacalata@users.noreply.github.com> Co-authored-by: Stephen Mitchell <scum@mac.com> Co-authored-by: jorwoods <jorwoods@users.noreply.github.com> Co-authored-by: Brian Cantoni <bcantoni@salesforce.com> Co-authored-by: Tyler Doyle <doyle.tyler@gmail.com> Co-authored-by: bcmyguest1 <49045013+bcmyguest1@users.noreply.github.com>
1 parent 265a4bf commit 3c021c0

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

+1005
-386
lines changed

.github/workflows/publish-pypi.yml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ name: Publish to PyPi
66
on:
77
workflow_dispatch:
88
push:
9-
branches:
10-
- master
9+
tags:
10+
- 'v*.*.*'
1111

1212
jobs:
1313
build-n-publish:
@@ -19,12 +19,13 @@ jobs:
1919
fetch-depth: 0
2020
- uses: actions/setup-python@v1
2121
with:
22-
python-version: 3.8
22+
python-version: 3.7
2323
- name: Build dist files
2424
run: |
2525
python -m pip install --upgrade pip
2626
pip install -e .[test]
27-
python setup.py sdist --formats=gztar
27+
python setup.py sdist --formats=gztar bdist_wheel
28+
git describe --tag --dirty --always
2829
- name: Publish distribution 📦 to Test PyPI
2930
uses: pypa/gh-action-pypi-publish@release/v1 # license BSD-2
3031
with:

.github/workflows/run-tests.yml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,3 @@ jobs:
2929
if: always()
3030
run: |
3131
pytest test
32-
33-
- name: Run Mypy tests
34-
run: |
35-
mypy --show-error-codes --disable-error-code misc --disable-error-code import tableauserverclient test

MANIFEST.in

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
1-
include versioneer.py
2-
include tableauserverclient/_version.py
1+
include CHANGELOG.md
2+
include contributing.md
3+
include CONTRIBUTORS.md
34
include LICENSE
45
include LICENSE.versioneer
56
include README.md
6-
include CHANGELOG.md
7+
include tableauserverclient/_version.py
8+
include versioneer.py
79
recursive-include docs *.md
810
recursive-include samples *.py
911
recursive-include samples *.txt
10-
recursive-include smoke *.py
1112
recursive-include test *.csv
1213
recursive-include test *.dict
1314
recursive-include test *.hyper
@@ -16,5 +17,6 @@ recursive-include test *.pdf
1617
recursive-include test *.png
1718
recursive-include test *.py
1819
recursive-include test *.xml
20+
recursive-include test *.tde
1921
global-include *.pyi
20-
global-include *.typed
22+
global-include *.typed

contributing.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,8 @@ somewhere.
5757
## Getting Started
5858

5959
```shell
60-
pip install versioneer
61-
python setup.py build
62-
python setup.py test
60+
python -m build
61+
pytest
6362
```
6463

6564
### To use your locally built version

pyproject.toml

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,37 @@
11
[build-system]
2-
requires = ["setuptools>=45.0", "versioneer-518", "wheel"]
2+
requires = ["setuptools>=45.0", "versioneer>=0.24", "wheel"]
33
build-backend = "setuptools.build_meta"
44

5+
[project]
6+
name="tableauserverclient"
7+
8+
dynamic = ["version"]
9+
description='A Python module for working with the Tableau Server REST API.'
10+
authors = [{name="Tableau", email="github@tableau.com"}]
11+
license = {file = "LICENSE"}
12+
readme = "README.md"
13+
14+
dependencies = [
15+
'defusedxml>=0.7.1',
16+
'packaging~=21.3',
17+
'requests>=2.28',
18+
'urllib3~=1.26.8',
19+
]
20+
requires-python = ">=3.7"
21+
classifiers = [
22+
"Programming Language :: Python",
23+
"Programming Language :: Python :: 3",
24+
"Programming Language :: Python :: 3.7",
25+
"Programming Language :: Python :: 3.8",
26+
"Programming Language :: Python :: 3.9",
27+
"Programming Language :: Python :: 3.10"
28+
]
29+
[project.urls]
30+
repository = "https://github.com/tableau/server-client-python"
31+
32+
[project.optional-dependencies]
33+
test = ["argparse", "black", "mock", "mypy", "pytest>=7.0", "requests-mock>=1.0,<2.0"]
34+
535
[tool.black]
636
line-length = 120
737
target-version = ['py37', 'py38', 'py39', 'py310']
@@ -11,8 +41,10 @@ disable_error_code = [
1141
'misc',
1242
'import'
1343
]
14-
files = [
15-
"tableauserverclient",
16-
"test"
17-
]
44+
files = ["tableauserverclient", "test"]
1845
show_error_codes = true
46+
ignore_missing_imports = true
47+
48+
[tool.pytest.ini_options]
49+
testpaths = ["test"]
50+
addopts = "--junitxml=./test.junit.xml"

samples/create_group.py

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,13 @@
88

99
import argparse
1010
import logging
11+
import os
1112

1213
from datetime import time
14+
from typing import List
1315

1416
import tableauserverclient as TSC
17+
from tableauserverclient import ServerResponseError
1518

1619

1720
def main():
@@ -35,7 +38,7 @@ def main():
3538
)
3639
# Options specific to this sample
3740
# This sample has no additional options, yet. If you add some, please add them here
38-
41+
parser.add_argument("--file", help="csv file containing user info", required=False)
3942
args = parser.parse_args()
4043

4144
# Set logging level based on user input, or error by default
@@ -45,9 +48,48 @@ def main():
4548
tableau_auth = TSC.PersonalAccessTokenAuth(args.token_name, args.token_value, site_id=args.site)
4649
server = TSC.Server(args.server, use_server_version=True)
4750
with server.auth.sign_in(tableau_auth):
51+
# this code shows 3 different error codes that mean "resource is already in collection"
52+
# 409009: group already exists on server
53+
# 409107: user is already on site
54+
# 409011: user is already in group
55+
4856
group = TSC.GroupItem("test")
49-
group = server.groups.create(group)
50-
print(group)
57+
try:
58+
group = server.groups.create(group)
59+
except TSC.server.endpoint.exceptions.ServerResponseError as rError:
60+
if rError.code == "409009":
61+
print("Group already exists")
62+
group = server.groups.filter(name=group.name)[0]
63+
else:
64+
raise rError
65+
server.groups.populate_users(group)
66+
for user in group.users:
67+
print(user.name)
68+
69+
if args.file:
70+
filepath = os.path.abspath(args.file)
71+
print("Add users to site from file {}:".format(filepath))
72+
added: List[TSC.UserItem]
73+
failed: List[TSC.UserItem, TSC.ServerResponseError]
74+
added, failed = server.users.create_from_file(filepath)
75+
for user, error in failed:
76+
print(user, error.code)
77+
if error.code == "409017":
78+
user = server.users.filter(name=user.name)[0]
79+
added.append(user)
80+
print("Adding users to group:{}".format(added))
81+
for user in added:
82+
print("Adding user {}".format(user))
83+
try:
84+
server.groups.add_user(group, user.id)
85+
except ServerResponseError as serverError:
86+
if serverError.code == "409011":
87+
print("user {} is already a member of group {}".format(user.name, group.name))
88+
else:
89+
raise rError
90+
91+
for user in group.users:
92+
print(user.name)
5193

5294

5395
if __name__ == "__main__":

samples/explore_site.py

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
####
2+
# This script demonstrates how to use the Tableau Server Client
3+
# to interact with sites.
4+
####
5+
6+
import argparse
7+
import logging
8+
import os.path
9+
import sys
10+
11+
import tableauserverclient as TSC
12+
13+
14+
def main():
15+
16+
parser = argparse.ArgumentParser(description="Explore site updates by the Server API.")
17+
# Common options; please keep those in sync across all samples
18+
parser.add_argument("--server", "-s", required=True, help="server address")
19+
parser.add_argument("--site", "-S", help="site name")
20+
parser.add_argument(
21+
"--token-name", "-p", required=True, help="name of the personal access token used to sign into the server"
22+
)
23+
parser.add_argument(
24+
"--token-value", "-v", required=True, help="value of the personal access token used to sign into the server"
25+
)
26+
parser.add_argument(
27+
"--logging-level",
28+
"-l",
29+
choices=["debug", "info", "error"],
30+
default="error",
31+
help="desired logging level (set to error by default)",
32+
)
33+
34+
parser.add_argument("--delete")
35+
parser.add_argument("--create")
36+
parser.add_argument("--url")
37+
parser.add_argument("--new_site_name")
38+
parser.add_argument("--user_quota")
39+
parser.add_argument("--storage_quota")
40+
parser.add_argument("--status")
41+
42+
args = parser.parse_args()
43+
44+
# Set logging level based on user input, or error by default
45+
logging_level = getattr(logging, args.logging_level.upper())
46+
logging.basicConfig(level=logging_level)
47+
48+
# SIGN IN
49+
tableau_auth = TSC.PersonalAccessTokenAuth(args.token_name, args.token_value, site_id=args.site)
50+
server = TSC.Server(args.server, use_server_version=True)
51+
new_site = None
52+
with server.auth.sign_in(tableau_auth):
53+
current_site = server.sites.get_by_id(server.site_id)
54+
55+
if args.delete:
56+
print("You can only delete the site you are currently in")
57+
print("Delete site `{}`?".format(current_site.name))
58+
# server.sites.delete(server.site_id)
59+
60+
elif args.create:
61+
new_site = TSC.SiteItem(args.create, args.url or args.create)
62+
site_item = server.sites.create(new_site)
63+
print(site_item)
64+
# to do anything further with the site, you need to log into it
65+
# if a PAT is required, that means going to the UI to create one
66+
67+
else:
68+
new_site = current_site
69+
print(current_site, "current user quota:", current_site.user_quota)
70+
print("Remember, you can only update the site you are currently in")
71+
if args.url:
72+
new_site.content_url = args.url
73+
if args.user_quota:
74+
new_site.user_quota = args.user_quota
75+
try:
76+
updated_site = server.sites.update(new_site)
77+
print(updated_site, "new user quota:", updated_site.user_quota)
78+
except TSC.ServerResponseError as e:
79+
print(e)
80+
81+
82+
if __name__ == "__main__":
83+
main()

samples/list.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,10 @@ def main():
5959
count = 0
6060
for resource in TSC.Pager(endpoint.get, options):
6161
count = count + 1
62-
print(resource.id, resource.name)
62+
# endpoint.populate_connections(resource)
63+
print(resource.name[:18], " ") # , resource._connections())
64+
if count > 100:
65+
break
6366
print("Total: {}".format(count))
6467

6568

samples/online_users.csv

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
ayoung@tableau.com, , , "Creator", None, Yes
2+
ahsiao@tableau.com, , , "Explorer", None, No

setup.cfg

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,10 @@
1-
[wheel]
2-
universal = 1
3-
4-
[pep8]
5-
max_line_length = 120
6-
71
# See the docstring in versioneer.py for instructions. Note that you must
82
# re-run 'versioneer.py setup' after changing this section, and commit the
93
# resulting files.
10-
4+
# versioneer does not support pyproject.toml
115
[versioneer]
126
VCS = git
137
style = pep440-pre
148
versionfile_source = tableauserverclient/_version.py
159
versionfile_build = tableauserverclient/_version.py
1610
tag_prefix = v
17-
#parentdir_prefix =
18-
19-
[aliases]
20-
smoke=pytest
21-
22-
[tool:pytest]
23-
testpaths = test smoke
24-
addopts = --junitxml=./test.junit.xml
25-
26-
[mypy]
27-
ignore_missing_imports = True

0 commit comments

Comments
 (0)
0