Skip to content

Commit 9ec60ac

Browse files
authored
Release with security and functionality updates (#1021)
Switched to using defused_xml for xml attack protection added linting and type hints improve experience with self-signed certificates/invalid ssl updated samples new item types: metrics, revisions for datasources and workbooks features: support adding flows to schedules, exporting workbooks to powerpoint fixes: delete extracts
1 parent 4a1656e commit 9ec60ac

File tree

165 files changed

+6657
-4292
lines changed

Some content is hidden

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

165 files changed

+6657
-4292
lines changed

.github/workflows/meta-checks.yml

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
name: types and style checks
2+
3+
on: [push, pull_request]
4+
5+
jobs:
6+
build:
7+
strategy:
8+
fail-fast: false
9+
matrix:
10+
os: [ubuntu-latest, macos-latest, windows-latest]
11+
python-version: ['3.10']
12+
13+
runs-on: ${{ matrix.os }}
14+
15+
steps:
16+
- uses: actions/checkout@v2
17+
18+
- name: Set up Python ${{ matrix.python-version }} on ${{ matrix.os }}
19+
uses: actions/setup-python@v2
20+
with:
21+
python-version: ${{ matrix.python-version }}
22+
23+
- name: Install dependencies
24+
run: |
25+
python -m pip install --upgrade pip
26+
pip install -e .[test]
27+
28+
- name: Format with black
29+
run: |
30+
black --check --line-length 120 tableauserverclient samples test
31+
32+
- name: Run Mypy tests
33+
if: always()
34+
run: |
35+
mypy --show-error-codes --disable-error-code misc --disable-error-code import tableauserverclient test

.github/workflows/publish-pypi.yml

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: Publish to PyPi
2+
3+
# This will publish a package to TestPyPi (and real Pypi if run on master) with a version
4+
# number generated by versioneer from the most recent tag looking like v____
5+
# TODO: maybe move this into the package job so all release-based actions are together
6+
on:
7+
workflow_dispatch:
8+
push:
9+
branches:
10+
- master
11+
12+
jobs:
13+
build-n-publish:
14+
name: Build dist files for PyPi
15+
runs-on: ubuntu-latest
16+
steps:
17+
- uses: actions/checkout@v3
18+
with:
19+
fetch-depth: 0
20+
- uses: actions/setup-python@v1
21+
with:
22+
python-version: 3.8
23+
- name: Build dist files
24+
run: |
25+
python -m pip install --upgrade pip
26+
pip install -e .[test]
27+
python setup.py sdist --formats=gztar
28+
- name: Publish distribution 📦 to Test PyPI
29+
uses: pypa/gh-action-pypi-publish@release/v1 # license BSD-2
30+
with:
31+
password: ${{ secrets.TEST_PYPI_API_TOKEN }}
32+
repository_url: https://test.pypi.org/legacy/
33+
- name: Publish distribution 📦 to PyPI
34+
if: github.ref == 'refs/heads/master'
35+
uses: pypa/gh-action-pypi-publish@release/v1 # license BSD-2
36+
with:
37+
password: ${{ secrets.PYPI_API_TOKEN }}

.github/workflows/run-tests.yml

+4-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: Python tests
22

3-
on: [push]
3+
on: [push, pull_request]
44

55
jobs:
66
build:
@@ -24,13 +24,12 @@ jobs:
2424
run: |
2525
python -m pip install --upgrade pip
2626
pip install -e .[test]
27-
pip install mypy
2827
2928
- name: Test with pytest
29+
if: always()
3030
run: |
3131
pytest test
3232
33-
- name: Run Mypy but allow failures
33+
- name: Run Mypy tests
3434
run: |
35-
mypy --show-error-codes --disable-error-code misc tableauserverclient
36-
continue-on-error: true
35+
mypy --show-error-codes --disable-error-code misc --disable-error-code import tableauserverclient test

.github/workflows/slack.yml

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ jobs:
99
name: Sends a message to Slack when a push, a pull request or an issue is made
1010
steps:
1111
- name: Send message to Slack API
12+
continue-on-error: true
1213
uses: archive/[email protected]
1314
id: notify
1415
with:

CHANGELOG.md

+10
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
2+
## 0.18.0 (6 April 2022)
3+
* Switched to using defused_xml for xml attack protection
4+
* added linting and type hints
5+
* improve experience with self-signed certificates/invalid ssl
6+
* updated samples
7+
* new item types: metrics, revisions for datasources and workbooks
8+
* features: support adding flows to schedules, exporting workbooks to powerpoint
9+
* fixes: delete extracts
10+
111
## 0.17.0 (20 October 2021)
212
* Added support for accepting parameters for post request of the metadata api (#850)
313
* Fixed jobs.get_by_id(job_id) example & reference docs (#867, #868)

MANIFEST.in

+2-5
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,6 @@ recursive-include test *.json
1515
recursive-include test *.pdf
1616
recursive-include test *.png
1717
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
2318
recursive-include test *.xml
19+
global-include *.pyi
20+
global-include *.typed

README.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ Use the Tableau Server Client (TSC) library to increase your productivity as you
88
* Create users and groups.
99
* Query projects, sites, and more.
1010

11-
This repository contains Python source code and sample files. Python versions 3.6 and up are supported.
11+
This repository contains Python source code for the library and sample files showing how to use it. Python versions 3.6 and up are supported.
12+
13+
To see sample code that works directly with the REST API (in Java, Python, or Postman), visit the [REST API Samples](https://github.com/tableau/rest-api-samples) repo.
1214

1315
For more information on installing and using TSC, see the documentation:
1416
<https://tableau.github.io/server-client-python/docs/>

contributing.md

+11-2
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,23 @@ python setup.py build
6262
python setup.py test
6363
```
6464

65+
### To use your locally built version
66+
```shell
67+
pip install .
68+
```
69+
6570
### Before Committing
6671

6772
Our CI runs include a Python lint run, so you should run this locally and fix complaints before committing as this will fail your checkin.
6873

6974
```shell
7075
# this will run the formatter without making changes
71-
black --line-length 120 tableauserverclient --check
76+
black --line-length 120 tableauserverclient test samples --check
7277

7378
# this will format the directory and code for you
74-
black --line-length 120 tableauserverclient
79+
black --line-length 120 tableauserverclient test samples
80+
81+
# this will run type checking
82+
pip install mypy
83+
mypy --show-error-codes --disable-error-code misc --disable-error-code import tableauserverclient test
7584
```

samples/add_default_permission.py

+18-14
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,23 @@
1616

1717

1818
def main():
19-
parser = argparse.ArgumentParser(description='Add workbook default permissions for a given project.')
19+
parser = argparse.ArgumentParser(description="Add workbook default permissions for a given project.")
2020
# Common options; please keep those in sync across all samples
21-
parser.add_argument('--server', '-s', required=True, help='server address')
22-
parser.add_argument('--site', '-S', help='site name')
23-
parser.add_argument('--token-name', '-p', required=True,
24-
help='name of the personal access token used to sign into the server')
25-
parser.add_argument('--token-value', '-v', required=True,
26-
help='value of the personal access token used to sign into the server')
27-
parser.add_argument('--logging-level', '-l', choices=['debug', 'info', 'error'], default='error',
28-
help='desired logging level (set to error by default)')
21+
parser.add_argument("--server", "-s", required=True, help="server address")
22+
parser.add_argument("--site", "-S", help="site name")
23+
parser.add_argument(
24+
"--token-name", "-p", required=True, help="name of the personal access token used to sign into the server"
25+
)
26+
parser.add_argument(
27+
"--token-value", "-v", required=True, help="value of the personal access token used to sign into the server"
28+
)
29+
parser.add_argument(
30+
"--logging-level",
31+
"-l",
32+
choices=["debug", "info", "error"],
33+
default="error",
34+
help="desired logging level (set to error by default)",
35+
)
2936
# Options specific to this sample
3037
# This sample has no additional options, yet. If you add some, please add them here
3138

@@ -53,10 +60,7 @@ def main():
5360
new_capabilities = {TSC.Permission.Capability.ExportXml: TSC.Permission.Mode.Allow}
5461

5562
# Each PermissionRule in the list contains a grantee and a dict of capabilities
56-
new_rules = [TSC.PermissionsRule(
57-
grantee=default_permissions.grantee,
58-
capabilities=new_capabilities
59-
)]
63+
new_rules = [TSC.PermissionsRule(grantee=default_permissions.grantee, capabilities=new_capabilities)]
6064

6165
new_default_permissions = server.projects.update_workbook_default_permissions(project, new_rules)
6266

@@ -78,5 +82,5 @@ def main():
7882
# server.projects.delete(project.id)
7983

8084

81-
if __name__ == '__main__':
85+
if __name__ == "__main__":
8286
main()

samples/create_group.py

+18-11
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,23 @@
1616

1717
def main():
1818

19-
parser = argparse.ArgumentParser(description='Creates a sample user group.')
19+
parser = argparse.ArgumentParser(description="Creates a sample user group.")
2020
# Common options; please keep those in sync across all samples
21-
parser.add_argument('--server', '-s', required=True, help='server address')
22-
parser.add_argument('--site', '-S', help='site name')
23-
parser.add_argument('--token-name', '-p', required=True,
24-
help='name of the personal access token used to sign into the server')
25-
parser.add_argument('--token-value', '-v', required=True,
26-
help='value of the personal access token used to sign into the server')
27-
parser.add_argument('--logging-level', '-l', choices=['debug', 'info', 'error'], default='error',
28-
help='desired logging level (set to error by default)')
21+
parser.add_argument("--server", "-s", required=True, help="server address")
22+
parser.add_argument("--site", "-S", help="site name")
23+
parser.add_argument(
24+
"--token-name", "-p", required=True, help="name of the personal access token used to sign into the server"
25+
)
26+
parser.add_argument(
27+
"--token-value", "-v", required=True, help="value of the personal access token used to sign into the server"
28+
)
29+
parser.add_argument(
30+
"--logging-level",
31+
"-l",
32+
choices=["debug", "info", "error"],
33+
default="error",
34+
help="desired logging level (set to error by default)",
35+
)
2936
# Options specific to this sample
3037
# This sample has no additional options, yet. If you add some, please add them here
3138

@@ -38,10 +45,10 @@ def main():
3845
tableau_auth = TSC.PersonalAccessTokenAuth(args.token_name, args.token_value, site_id=args.site)
3946
server = TSC.Server(args.server, use_server_version=True)
4047
with server.auth.sign_in(tableau_auth):
41-
group = TSC.GroupItem('test')
48+
group = TSC.GroupItem("test")
4249
group = server.groups.create(group)
4350
print(group)
4451

4552

46-
if __name__ == '__main__':
53+
if __name__ == "__main__":
4754
main()

samples/create_project.py

+30-19
Original file line numberDiff line numberDiff line change
@@ -14,27 +14,34 @@
1414
import tableauserverclient as TSC
1515

1616

17-
def create_project(server, project_item):
17+
def create_project(server, project_item, samples=False):
1818
try:
19-
project_item = server.projects.create(project_item)
20-
print('Created a new project called: %s' % project_item.name)
19+
project_item = server.projects.create(project_item, samples)
20+
print("Created a new project called: %s" % project_item.name)
2121
return project_item
2222
except TSC.ServerResponseError:
23-
print('We have already created this project: %s' % project_item.name)
23+
print("We have already created this project: %s" % project_item.name)
2424
sys.exit(1)
2525

2626

2727
def main():
28-
parser = argparse.ArgumentParser(description='Create new projects.')
28+
parser = argparse.ArgumentParser(description="Create new projects.")
2929
# Common options; please keep those in sync across all samples
30-
parser.add_argument('--server', '-s', required=True, help='server address')
31-
parser.add_argument('--site', '-S', help='site name')
32-
parser.add_argument('--token-name', '-p', required=True,
33-
help='name of the personal access token used to sign into the server')
34-
parser.add_argument('--token-value', '-v', required=True,
35-
help='value of the personal access token used to sign into the server')
36-
parser.add_argument('--logging-level', '-l', choices=['debug', 'info', 'error'], default='error',
37-
help='desired logging level (set to error by default)')
30+
parser.add_argument("--server", "-s", required=True, help="server address")
31+
parser.add_argument("--site", "-S", help="site name")
32+
parser.add_argument(
33+
"--token-name", "-p", required=True, help="name of the personal access token used to sign into the server"
34+
)
35+
parser.add_argument(
36+
"--token-value", "-v", required=True, help="value of the personal access token used to sign into the server"
37+
)
38+
parser.add_argument(
39+
"--logging-level",
40+
"-l",
41+
choices=["debug", "info", "error"],
42+
default="error",
43+
help="desired logging level (set to error by default)",
44+
)
3845
# Options specific to this sample
3946
# This sample has no additional options, yet. If you add some, please add them here
4047

@@ -45,23 +52,27 @@ def main():
4552
logging.basicConfig(level=logging_level)
4653

4754
tableau_auth = TSC.PersonalAccessTokenAuth(args.token_name, args.token_value, site_id=args.site)
48-
server = TSC.Server(args.server, use_server_version=True)
55+
server = TSC.Server(args.server)
56+
server.use_server_version()
4957
with server.auth.sign_in(tableau_auth):
5058
# Use highest Server REST API version available
5159
server.use_server_version()
5260

5361
# Without parent_id specified, projects are created at the top level.
54-
top_level_project = TSC.ProjectItem(name='Top Level Project')
62+
top_level_project = TSC.ProjectItem(name="Top Level Project")
5563
top_level_project = create_project(server, top_level_project)
5664

5765
# Specifying parent_id creates a nested projects.
58-
child_project = TSC.ProjectItem(name='Child Project', parent_id=top_level_project.id)
59-
child_project = create_project(server, child_project)
66+
child_project = TSC.ProjectItem(name="Child Project", parent_id=top_level_project.id)
67+
child_project = create_project(server, child_project, samples=True)
6068

6169
# Projects can be nested at any level.
62-
grand_child_project = TSC.ProjectItem(name='Grand Child Project', parent_id=child_project.id)
70+
grand_child_project = TSC.ProjectItem(name="Grand Child Project", parent_id=child_project.id)
6371
grand_child_project = create_project(server, grand_child_project)
6472

73+
# Projects can be updated
74+
changed_project = server.projects.update(grand_child_project, samples=True)
6575

66-
if __name__ == '__main__':
76+
77+
if __name__ == "__main__":
6778
main()

0 commit comments

Comments
 (0)