Skip to content

Commit 4259316

Browse files
authored
Merge pull request #1444 from tableau/development
v0.33 Features: - add name, datasource-name to Job item - enable bulk add and remove users - Linked Tasks: get, get by ID, run Now - implement Tags: create new, add/delete for workbooks, flows, datasources - get page and chunk size from env vars - add some repr implementations - implement virtual connections Bugfix: - #1447 - #1449
2 parents 257cf61 + 4584717 commit 4259316

File tree

71 files changed

+3127
-277
lines changed

Some content is hidden

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

71 files changed

+3127
-277
lines changed

CONTRIBUTORS.md

+73-53
Original file line numberDiff line numberDiff line change
@@ -4,59 +4,79 @@ The following people have contributed to this project to make it possible, and w
44

55
## Contributors
66

7+
* [jacalata](https://github.com/jacalata)
8+
* [jorwoods](https://github.com/jorwoods)
9+
* [t8y8](https://github.com/t8y8)
10+
* [bcantoni](https://github.com/bcantoni)
11+
* [shinchris](https://github.com/shinchris)
12+
* [vogelsgesang](https://github.com/vogelsgesang)
13+
* [lbrendanl](https://github.com/lbrendanl)
14+
* [LGraber](https://github.com/LGraber)
15+
* [gaoang2148](https://github.com/gaoang2148)
16+
* [benlower](https://github.com/benlower)
17+
* [liu-rebecca](https://github.com/liu-rebecca)
18+
* [guodah](https://github.com/guodah)
19+
* [jdomingu](https://github.com/jdomingu)
20+
* [kykrueger](https://github.com/kykrueger)
21+
* [jz-huang](https://github.com/jz-huang)
22+
* [opus-42](https://github.com/opus-42)
23+
* [markm-io](https://github.com/markm-io)
24+
* [graysonarts](https://github.com/graysonarts)
25+
* [d45](https://github.com/d45)
26+
* [preguraman](https://github.com/preguraman)
27+
* [sotnich](https://github.com/sotnich)
28+
* [mmuttreja-tableau](https://github.com/mmuttreja-tableau)
29+
* [dependabot[bot]](https://github.com/apps/dependabot)
30+
* [scuml](https://github.com/scuml)
31+
* [ovinis](https://github.com/ovinis)
32+
* [FFMMM](https://github.com/FFMMM)
33+
* [martinbpeters](https://github.com/martinbpeters)
34+
* [talvalin](https://github.com/talvalin)
35+
* [dzucker-tab](https://github.com/dzucker-tab)
36+
* [a-torres-2](https://github.com/a-torres-2)
37+
* [nnevalainen](https://github.com/nnevalainen)
38+
* [mbren](https://github.com/mbren)
39+
* [wolkiewiczk](https://github.com/wolkiewiczk)
40+
* [jacobj10](https://github.com/jacobj10)
41+
* [hugoboos](https://github.com/hugoboos)
42+
* [grbritz](https://github.com/grbritz)
43+
* [fpagliar](https://github.com/fpagliar)
44+
* [bskim45](https://github.com/bskim45)
45+
* [baixin137](https://github.com/baixin137)
46+
* [jessicachen79](https://github.com/jessicachen79)
47+
* [gconklin](https://github.com/gconklin)
748
* [geordielad](https://github.com/geordielad)
8-
* [Hugo Stijns](https://github.com/hugoboos)
9-
* [kovner](https://github.com/kovner)
10-
* [Talvalin](https://github.com/Talvalin)
11-
* [Chris Toomey](https://github.com/cmtoomey)
12-
* [Vathsala Achar](https://github.com/VathsalaAchar)
13-
* [Graeme Britz](https://github.com/grbritz)
14-
* [Russ Goldin](https://github.com/tagyoureit)
15-
* [William Lang](https://github.com/williamlang)
16-
* [Jim Morris](https://github.com/jimbodriven)
17-
* [BingoDinkus](https://github.com/BingoDinkus)
18-
* [Sergey Sotnichenko](https://github.com/sotnich)
19-
* [Bruce Zhang](https://github.com/baixin137)
20-
* [Bumsoo Kim](https://github.com/bskim45)
49+
* [fossabot](https://github.com/fossabot)
2150
* [daniel1608](https://github.com/daniel1608)
22-
* [Joshua Jacob](https://github.com/jacobj10)
23-
* [Francisco Pagliaricci](https://github.com/fpagliar)
24-
* [Tomasz Machalski](https://github.com/toomyem)
25-
* [Jared Dominguez](https://github.com/jdomingu)
26-
* [Brendan Lee](https://github.com/lbrendanl)
27-
* [Martin Dertz](https://github.com/martydertz)
28-
* [Christian Oliff](https://github.com/coliff)
29-
* [Albin Antony](https://github.com/user9747)
30-
* [prae04](https://github.com/prae04)
31-
* [Martin Peters](https://github.com/martinbpeters)
32-
* [Sherman K](https://github.com/shrmnk)
33-
* [Jorge Fonseca](https://github.com/JorgeFonseca)
34-
* [Kacper Wolkiewicz](https://github.com/wolkiewiczk)
35-
* [Dahai Guo](https://github.com/guodah)
36-
* [Geraldine Zanolli](https://github.com/illonage)
37-
* [Jordan Woods](https://github.com/jorwoods)
38-
* [Reba Magier](https://github.com/rmagier1)
39-
* [Stephen Mitchell](https://github.com/scuml)
40-
* [absentmoose](https://github.com/absentmoose)
41-
* [Paul Vickers](https://github.com/paulvic)
42-
* [Madhura Selvarajan](https://github.com/maddy-at-leisure)
43-
* [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)
4751
* [annematronic](https://github.com/annematronic)
48-
49-
## Core Team
50-
51-
* [Chris Shin](https://github.com/shinchris)
52-
* [Lee Graber](https://github.com/lgraber)
53-
* [Tyler Doyle](https://github.com/t8y8)
54-
* [Russell Hay](https://github.com/RussTheAerialist)
55-
* [Ben Lower](https://github.com/benlower)
56-
* [Ang Gao](https://github.com/gaoang2148)
57-
* [Priya Reguraman](https://github.com/preguraman)
58-
* [Jac Fitzgerald](https://github.com/jacalata)
59-
* [Dan Zucker](https://github.com/dzucker-tab)
60-
* [Brian Cantoni](https://github.com/bcantoni)
61-
* [Ovini Nanayakkara](https://github.com/ovinis)
62-
* [Manish Muttreja](https://github.com/mmuttreja-tableau)
52+
* [rshide](https://github.com/rshide)
53+
* [VathsalaAchar](https://github.com/VathsalaAchar)
54+
* [TrimPeachu](https://github.com/TrimPeachu)
55+
* [ajbosco](https://github.com/ajbosco)
56+
* [jimbodriven](https://github.com/jimbodriven)
57+
* [ltiffanydev](https://github.com/ltiffanydev)
58+
* [martydertz](https://github.com/martydertz)
59+
* [r-richmond](https://github.com/r-richmond)
60+
* [sfarr15](https://github.com/sfarr15)
61+
* [tagyoureit](https://github.com/tagyoureit)
62+
* [tjones-commits](https://github.com/tjones-commits)
63+
* [yoshichan5](https://github.com/yoshichan5)
64+
* [wlodi83](https://github.com/wlodi83)
65+
* [anipmehta](https://github.com/anipmehta)
66+
* [cmtoomey](https://github.com/cmtoomey)
67+
* [pes-magic](https://github.com/pes-magic)
68+
* [illonage](https://github.com/illonage)
69+
* [jayvdb](https://github.com/jayvdb)
70+
* [jorgeFons](https://github.com/jorgeFons)
71+
* [Kovner](https://github.com/Kovner)
72+
* [LarsBreddemann](https://github.com/LarsBreddemann)
73+
* [lboynton](https://github.com/lboynton)
74+
* [maddy-at-leisure](https://github.com/maddy-at-leisure)
75+
* [narcolino-tableau](https://github.com/narcolino-tableau)
76+
* [PatrickfBraz](https://github.com/PatrickfBraz)
77+
* [paulvic](https://github.com/paulvic)
78+
* [shrmnk](https://github.com/shrmnk)
79+
* [TableauKyle](https://github.com/TableauKyle)
80+
* [bossenti](https://github.com/bossenti)
81+
* [ma7tcsp](https://github.com/ma7tcsp)
82+
* [toomyem](https://github.com/toomyem)

README.md

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

12-
This repository contains Python source code for the library and sample files showing how to use it. As of May 2022, Python versions 3.7 and up are supported.
12+
This repository contains Python source code for the library and sample files showing how to use it. As of September 2024, support for Python 3.7 and 3.8 will be dropped - support for older versions of Python aims to match https://devguide.python.org/versions/
1313

1414
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.
1515

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

19-
19+
To contribute, see our [Developer Guide](https://tableau.github.io/server-client-python/docs/dev-guide). A list of all our contributors to date is in [CONTRIBUTORS.md].
2020

2121
## License
2222
[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Ftableau%2Fserver-client-python.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2Ftableau%2Fserver-client-python?ref=badge_large)

contributing.md

+2-63
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@ Contribution can include, but are not limited to, any of the following:
1010
* Fix an Issue/Bug
1111
* Add/Fix documentation
1212

13-
Contributions must follow the guidelines outlined on the [Tableau Organization](http://tableau.github.io/) page, though filing an issue or requesting a feature do not require the CLA.
14-
1513
## Issues and Feature Requests
1614

1715
To submit an issue/bug report, or to request a feature, please submit a [GitHub issue](https://github.com/tableau/server-client-python/issues) to the repo.
@@ -22,65 +20,6 @@ files to assist in the repro. **Be sure to scrub the files of any potentially s
2220
For a feature request, please try to describe the scenario you are trying to accomplish that requires the feature. This will help us understand
2321
the limitations that you are running into, and provide us with a use case to know if we've satisfied your request.
2422

25-
### Label usage on Issues
26-
27-
The core team is responsible for assigning most labels to the issue. Labels
28-
are used for prioritizing the core team's work, and use the following
29-
definitions for labels.
30-
31-
The following labels are only to be set or changed by the core team:
32-
33-
* **bug** - A bug is an unintended behavior for existing functionality. It only relates to existing functionality and the behavior that is expected with that functionality. We do not use **bug** to indicate priority.
34-
* **enhancement** - An enhancement is a new piece of functionality and is related to the fact that new code will need to be written in order to close this issue. We do not use **enhancement** to indicate priority.
35-
* **CLARequired** - This label is used to indicate that the contribution will require that the CLA is signed before we can accept a PR. This label should not be used on Issues
36-
* **CLANotRequired** - This label is used to indicate that the contribution does not require a CLA to be signed. This is used for minor fixes and usually around doc fixes or correcting strings.
37-
* **help wanted** - This label on an issue indicates it's a good choice for external contributors to take on. It usually means it's an issue that can be tackled by first time contributors.
38-
39-
The following labels can be used by the issue creator or anyone in the
40-
community to help us prioritize enhancement and bug fixes that are
41-
causing pain from our users. The short of it is, purple tags are ones that
42-
anyone can add to an issue:
43-
44-
* **Critical** - This means that you won't be able to use the library until the issues have been resolved. If an issue is already labeled as critical, but you want to show your support for it, add a +1 comment to the issue. This helps us know what issues are really impacting our users.
45-
* **Nice To Have** - This means that the issue doesn't block your usage of the library, but would make your life easier. Like with critical, if the issue is already tagged with this, but you want to show your support, add a +1 comment to the issue.
46-
47-
## Fixes, Implementations, and Documentation
48-
49-
For all other things, please submit a PR that includes the fix, documentation, or new code that you are trying to contribute. More information on
50-
creating a PR can be found in the [Development Guide](https://tableau.github.io/server-client-python/docs/dev-guide).
51-
52-
If the feature is complex or has multiple solutions that could be equally appropriate approaches, it would be helpful to file an issue to discuss the
53-
design trade-offs of each solution before implementing, to allow us to collectively arrive at the best solution, which most likely exists in the middle
54-
somewhere.
55-
56-
## Getting Started
57-
58-
```shell
59-
python -m build
60-
pytest
61-
```
62-
63-
### To use your locally built version
64-
```shell
65-
pip install .
66-
```
67-
68-
### Debugging Tools
69-
See what your outgoing requests look like: https://requestbin.net/ (unaffiliated link not under our control)
70-
71-
72-
### Before Committing
73-
74-
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.
75-
76-
```shell
77-
# this will run the formatter without making changes
78-
black . --check
79-
80-
# this will format the directory and code for you
81-
black .
23+
### Making Contributions
8224

83-
# this will run type checking
84-
pip install mypy
85-
mypy tableauserverclient test samples
86-
```
25+
Refer to the [Developer Guide](https://tableau.github.io/server-client-python/docs/dev-guide) which explains how to make contributions to the TSC project.

getcontributors.py

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import json
2+
import requests
3+
4+
5+
logins = json.loads(
6+
requests.get("https://api.github.com/repos/tableau/server-client-python/contributors?per_page=200").text
7+
)
8+
for login in logins:
9+
print(f"* [{login["login"]}]({login["html_url"]})")

tableauserverclient/__init__.py

+10
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,14 @@
1717
FlowRunItem,
1818
FileuploadItem,
1919
GroupItem,
20+
GroupSetItem,
2021
HourlyInterval,
2122
IntervalItem,
2223
JobItem,
2324
JWTAuth,
25+
LinkedTaskItem,
26+
LinkedTaskStepItem,
27+
LinkedTaskFlowRunItem,
2428
MetricItem,
2529
MonthlyInterval,
2630
PaginationItem,
@@ -39,6 +43,7 @@
3943
TaskItem,
4044
UserItem,
4145
ViewItem,
46+
VirtualConnectionItem,
4247
WebhookItem,
4348
WeeklyInterval,
4449
WorkbookItem,
@@ -79,6 +84,7 @@
7984
"FlowRunItem",
8085
"FileuploadItem",
8186
"GroupItem",
87+
"GroupSetItem",
8288
"HourlyInterval",
8389
"IntervalItem",
8490
"JobItem",
@@ -116,4 +122,8 @@
116122
"Pager",
117123
"Server",
118124
"Sort",
125+
"LinkedTaskItem",
126+
"LinkedTaskStepItem",
127+
"LinkedTaskFlowRunItem",
128+
"VirtualConnectionItem",
119129
]

tableauserverclient/config.py

+16-4
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,25 @@
1-
# TODO: check for env variables, else set default values
1+
import os
22

33
ALLOWED_FILE_EXTENSIONS = ["tds", "tdsx", "tde", "hyper", "parquet"]
44

55
BYTES_PER_MB = 1024 * 1024
66

7-
# For when a datasource is over 64MB, break it into 5MB(standard chunk size) chunks
8-
CHUNK_SIZE_MB = 5 * 10 # 5MB felt too slow, upped it to 50
9-
107
DELAY_SLEEP_SECONDS = 0.1
118

129
# The maximum size of a file that can be published in a single request is 64MB
1310
FILESIZE_LIMIT_MB = 64
11+
12+
13+
class Config:
14+
# For when a datasource is over 64MB, break it into 5MB(standard chunk size) chunks
15+
@property
16+
def CHUNK_SIZE_MB(self):
17+
return int(os.getenv("TSC_CHUNK_SIZE_MB", 5 * 10)) # 5MB felt too slow, upped it to 50
18+
19+
# Default page size
20+
@property
21+
def PAGE_SIZE(self):
22+
return int(os.getenv("TSC_PAGE_SIZE", 100))
23+
24+
25+
config = Config()

tableauserverclient/models/__init__.py

+12
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from tableauserverclient.models.flow_item import FlowItem
1515
from tableauserverclient.models.flow_run_item import FlowRunItem
1616
from tableauserverclient.models.group_item import GroupItem
17+
from tableauserverclient.models.groupset_item import GroupSetItem
1718
from tableauserverclient.models.interval_item import (
1819
IntervalItem,
1920
DailyInterval,
@@ -22,6 +23,11 @@
2223
HourlyInterval,
2324
)
2425
from tableauserverclient.models.job_item import JobItem, BackgroundJobItem
26+
from tableauserverclient.models.linked_tasks_item import (
27+
LinkedTaskItem,
28+
LinkedTaskStepItem,
29+
LinkedTaskFlowRunItem,
30+
)
2531
from tableauserverclient.models.metric_item import MetricItem
2632
from tableauserverclient.models.pagination_item import PaginationItem
2733
from tableauserverclient.models.permissions_item import PermissionsRule, Permission
@@ -39,6 +45,7 @@
3945
from tableauserverclient.models.task_item import TaskItem
4046
from tableauserverclient.models.user_item import UserItem
4147
from tableauserverclient.models.view_item import ViewItem
48+
from tableauserverclient.models.virtual_connection_item import VirtualConnectionItem
4249
from tableauserverclient.models.webhook_item import WebhookItem
4350
from tableauserverclient.models.workbook_item import WorkbookItem
4451

@@ -60,6 +67,7 @@
6067
"FlowItem",
6168
"FlowRunItem",
6269
"GroupItem",
70+
"GroupSetItem",
6371
"IntervalItem",
6472
"JobItem",
6573
"DailyInterval",
@@ -89,6 +97,10 @@
8997
"TaskItem",
9098
"UserItem",
9199
"ViewItem",
100+
"VirtualConnectionItem",
92101
"WebhookItem",
93102
"WorkbookItem",
103+
"LinkedTaskItem",
104+
"LinkedTaskStepItem",
105+
"LinkedTaskFlowRunItem",
94106
]

tableauserverclient/models/connection_item.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,14 @@ def from_response(cls, resp, ns) -> List["ConnectionItem"]:
6666
for connection_xml in all_connection_xml:
6767
connection_item = cls()
6868
connection_item._id = connection_xml.get("id", None)
69-
connection_item._connection_type = connection_xml.get("type", None)
69+
connection_item._connection_type = connection_xml.get("type", connection_xml.get("dbClass", None))
7070
connection_item.embed_password = string_to_bool(connection_xml.get("embedPassword", ""))
7171
connection_item.server_address = connection_xml.get("serverAddress", None)
7272
connection_item.server_port = connection_xml.get("serverPort", None)
7373
connection_item.username = connection_xml.get("userName", None)
74-
connection_item._query_tagging = string_to_bool(connection_xml.get("queryTaggingEnabled", None))
74+
connection_item._query_tagging = (
75+
string_to_bool(s) if (s := connection_xml.get("queryTagging", None)) else None
76+
)
7577
datasource_elem = connection_xml.find(".//t:datasource", namespaces=ns)
7678
if datasource_elem is not None:
7779
connection_item._datasource_id = datasource_elem.get("id", None)

tableauserverclient/models/database_item.py

+6
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,12 @@ def __init__(self, name, description=None, content_permissions=None):
4444

4545
self._tables = None # Not implemented yet
4646

47+
def __str__(self):
48+
return "<Database {0} '{1}'>".format(self._id, self.name)
49+
50+
def __repr__(self):
51+
return self.__str__() + " { " + ", ".join(" % s: % s" % item for item in vars(self).items()) + "}"
52+
4753
@property
4854
def dqws(self):
4955
if self._data_quality_warnings is None:

0 commit comments

Comments
 (0)